K-最近邻算法

邻近算法,或者说K-近邻(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。

核心思想

如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。KNN方法在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

算法步骤
步骤描述
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别(决策依据方法之一)作为测试数据的预测分类。

关于距离的计算

这里的距离指的是平面上两个点的直线距离。常用的距离计算公式有:
1.闵可夫斯基距离
2.欧几里得距离
3.曼哈顿距离
4.切比雪夫距离
5.马氏距离
6.余弦相似度
7.皮尔逊相关系数
8.汉明距离
9.杰卡德相似系数
10.编辑距离

11.DTW距离
12.KL散度

关于K值的选择

K称为临近数,即在预测目标点时取几个临近的点来预测。

1.如果当K的取值过小时,一旦有噪声得成分存在们将会对预测产生比较大影响,例如取K值为1时,一旦最近的一个点是噪声,那么就会出现偏差,K值的减小就意味着整体模型变得复杂,容易发生过拟合;

2,如果K的值取的过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。这时与输入目标点较远实例也会对预测起作用,使预测发生错误。K值的增大就意味着整体的模型变得简单,也就是容易发生欠拟合;
3.如果K=N的时候,那么就是取全部的实例,即为取实例中某分类下最多的点,就对预测没有什么实际的意义了;
为此我们可以这样取K的值:
1.从k=1开始,使用检验集估计分类器的误差率。重复该过程,每次K增值1,允许增加一个近邻。选取产生最小误差率的K;

2,一般K的取值不超过20,上限是n的开方,随着数据集的增大,K的值也要增大;
3.K的取值尽量要取奇数以保证在计算结果最后会产生一个较多的类别,如果取偶数可能会产生相等的情况,不利于预测。

import inline as inline
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
#原始数据
data=[[1,0.9],[1,1],[0.1,0.2],[0,0.1]]
labels=['A','A','B','B']
test_data=[[0.1,0.3]]
#绘制原始数据散点图
print("------------------------数据准备----------------------")
print("原始数据图像绘制...")
for i in range(len(data)):
    plt.scatter(data[i][0],data[i][1],color='b')
plt.scatter(test_data[0][0],test_data[0][1],color='r')
plt.show()
#测试数据x=(0.1,0.3)
#采用欧氏距离进行计算
print("------------------------距离计算----------------------")
x=[[0.1,0.3]]
distance=[]
labels_vz=[]
for i in range(len(data)):
    d=0
    d=sqrt((x[0][0]-data[i][0])**2+(x[0][1]-data[i][1])**2)
    distance.append(d)
    labels_vz.append(i)
print("计算的距离为:\n",distance)
print("现在对应的标签位置为:\n",labels_vz)
#按照升序排序,并取距离最小的前3个
print("-----------------------距离排序-----------------------")
for i in range(len(data)-1):
    for j in range(i+1,len(data)):
        if distance[i]>distance[j]:
            distance[i],distance[j]= distance[j],distance[i]
            labels_vz[i],labels_vz[j]= labels_vz[j],labels_vz[i]
print("排序后的距离为:\n",labels_vz)
print("取距离最近的3个值:",distance[0:3])
#进行投票表决
print("-----------------------表决投票-----------------------")
A=0
B=0
for i in range(len(labels_vz[0:3])):
    if labels[labels_vz[i]]=='A':
        A+=1
    else:
        B+=1
print("投票为A的数量为:",A)
print("投票为B的数量为:",B)
print("\n对照初始图中红色点(测试点)与前两个标签为A的离的最近,所以我们的计算与图中所呈现的绘图一致")

K-最近邻算法_第1张图片

 

你可能感兴趣的:(人工智能)