您的位置:首页 > 其它

K-近邻分类算法KNN

2015-11-07 21:38 323 查看

一、KNN算法的步骤

计算已知类别数据集中每个点与当前点的距离;
选取与当前点距离最小的K个点;
统计前K个点中每个类别的样本出现的频率;
返回前K个点出现频率最高的类别作为当前点的预测分类。

二、计算距离

传统上,KNN算法采用的是欧式距离,即:假设item的特征向量为(x1,x2,......,xn),则欧式距离=2个item在特征空间上的直线距离。如果item是文本,它的特征是文本中的多个word的话,采用余弦距离较好。

三、K值的选取

对于KNN算法来说,选择一个合适的K值至关重要,它决定了模型对未来数据的分类性能的好坏。

      当K值过大时例如极端情况下取K=N(N=训练样本数),由于KNN采用的是投票机制,所以最终训练出来的模型总会选择得票数最多的类作为分类结果。此时会出现这样的问题:模型总会选择训练样本最多的类,而不管这个类离目标样本T是否最近(解决该问题的一种方案是设置“投票权重(Voting-Weight)”,投票时,离目标样本T近的VW值大,反之VW值小)。所以,K值取的太大会导致KNN分类器不准确。

      当K值过小时,KNN分类器又会被训练样本中的“噪声”所干扰。

      所以,K值不能过大,也不能过小,K值的选取取决于学习难度与训练样本的规模,通常,K取3~10。一种常见的做法就是设置K等于训练样本数的“平方根”。更好的一种方法是“交叉验证”:设置多个测试样本集,用这些样本集来测试多个K值,根据分类性能选择最合适的K值。

四、样本特征的标准化

在计算样本item间的距离时,距离依赖于特征是如何被度量的,如果某个特征具有比其他特征大的多的值,显然,距离值将会强烈的被这个特征所支配,这是不合适的,我们需要标准化特征值,即对各特征的值进行“缩放”,使每个特征对距离值的贡献相对平均。

    对特征值进行标准化的传统方法是min-max标准化(min-max normalization),它将特征X的每个值减去X的最小值再除以X的值域,从而使X值落在[0,1]内:

    


    另外一种常用的标准化方法是Z-Score标准化(Z-Score normalization),它将特征X的每个值减去X的均值再除以X的标准差,得到一个称为z-score的值:



五、KNN案例-威斯康星乳腺癌诊断

1、收集数据。

这里,我们将使用“威斯康星乳腺癌诊断(Breast Cancer Wisconsin Diagnostic)”数据集,该数据集由威斯康星大学的研究者捐赠,包括569例细胞活性检测案例,每个案例有32个特征,一个特征是识别号码,一个特征是癌症诊断结果(M表示恶性;B表示良性),其他30个特征是每个案例中细胞核的测量结果,这里取细胞核的10个特征(半径;质地;......;对称性;分形维数),取这10个特征的均值、标准差、最大值作为测量结果。数据集中部分样本如下图:


 

2、准备数据。

- 数据预处理。

- 创建训练样本集、测试样本集。

3、KNN分类(类别预测)。

代码如下:
</pre><pre name="code" class="plain"># knn classification algorithm.
# author : oucqiangz2012  qiangz2012@yeah.net

# 导入源数据。
bcwd_dataframe <- read.csv(file = "G:\\DataMining\\dataSets\\Breast Cancer Wisconsin Diagnostic\\wdbc.csv",stringsAsFactors = FALSE)

# 数据预处理。
bcwd_dataframe <- bcwd_dataframe[-1] # 删除第一个ID特征。
bcwd_dataframe$Diagnosis <- factor(x = bcwd_dataframe$Diagnosis,levels = c("B","M"),labels = c("Benign","Malignant"))
# 因变量重编码为因子类型。

min_max_norm <- function(x) {
return ( (x-min(x)) / (max(x)-min(x)) )
}
bcwd_norm_features <- data.frame(lapply(bcwd_dataframe[2:31],min_max_norm)) # z-score后的特征矩阵。
bcwd_labes <- bcwd_dataframe$Diagnosis # 类别。

# 创建训练样本集、测试样本集。
bcwd_train <- bcwd_norm_features[1:470,] #取前470个样本组成训练集。
bcwd_test <- bcwd_norm_features[471:569,] #后面的样本组成测试集。

bcwd_train_labels <- bcwd_labes[1:470] # train的类别。
bcwd_test_obs_labels <- bcwd_labes[471:569] # test的类别。

# 类别预测。
library(FastKNN)
dist_matrix <- Distance_for_KNN_test(bcwd_test,bcwd_train) # test与train的距离矩阵。
test_labes_pred <- knn_test_function(bcwd_train,bcwd_test,dist_matrix,bcwd_train_labels,k = 3) #KNN算法预测的test类别。

# 模型性能评估。
# Package: gmodels
library(gmodels)
CrossTable(x = bcwd_test_obs_labels, y = test_labes_pred, prop.chisq = FALSE)

# 模型性能优化。
# 交叉验证:试验不同K值的KNN性能;扩大训练样本规模...


分类效果用crosstable表示如下:



显然,性能不是很好,需要进一步优化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: