编辑公式网址:http://private.codecogs.com/latex/eqneditor.php
K近邻算法,即为给定一个训练样本集,对新输入的实例,在训练样本集中找到与该实例最邻近的K个实例(最邻近),如果这K个实例的多数属于某一个类,将其作为新输入实例的分类;
输入为新实例:(实例的特征向量——>特征空间的点);输出为实例的类别:(输出的类别可以多种)。
优点:精度高、对于异常值不敏感、无数据输入假定;
缺点:计算复杂度高、空间复杂度高;
K-近邻算法过程:1.收集数据;
2.准备数据(距离度量);
3.分析数据;
4.训练算法;
5.测试算法(计算错误率);
6.使用算法(首先输入样本数据和结构化的输出结果,然后运行K-近邻算法判定输入数据分布所属类别;最后应用对计算出的分类执行后续的处理。
K-近邻算法的描述:
输入:训练数据集(先确定实例类别)
T={(x1,y1),(x2,y2),.....,(xN,yN)}, 其中,xi为实例的特征向量,yi为实例的类别=(c1,c2,....ck);
输出:实例x所属的类别y;
(1)根据给定的距离度量,在训练集T中找出于x最近邻的k个点,x的领域记作Nk(x);
(2)在Nk(x)中根据分类决策规则(多数表决)决定x的类别y;
I为指示函数,即为yi=cj时I为1,否则为0;
K-近邻模型:即为特征空间的划分
训练集;
距离度量(欧式距离,标准化欧式距离,夹角余弦等);
K值得选择;
分类决策规则;
1.距离的度量:特征空间中两个实例点的距离为两个实例点相似程度的反应;
xi,和xj的Lp距离定义为:
Lp(xi,xj)=(∑l=1n|x(l)i−x(l)j|p)1p
当P=2时,则为欧式距离;
当p=1时,则为曼哈顿距离;
当p=无穷时,则为各个坐标距离的最大值;
二维空间中档p为不同值时,Lp距离图
Lp距离间的关系
K值得选择:
k值较小,即为用较小的领域中的训练实例进行预测(近似误差减小,估计误差会增大,容易出现过拟合);
k值较大,即为用较大的领域中的训练实例进行预测(增大了近似误差,较少估计误差)
分类决策规则:
分类损失函数为0-1函数;分类函数为F—>R—>{c1,c2,...ck} ;则误分类的概率为P(Y!=F(x))=1-P(y=F(x))
误分类率为:
代码实现:
from numpy import *
import operator
def createDataSet():
group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) #创建一个矩阵,每一行作为一个样本
labels=['A','A','B','B'] #分为两类
return group,labels
def classify(inX, dataSet, labels, k): #inX用于分类的输入向量,dataSet为训练样本集,labels:标签向量,K为K-近邻算法中k的值
numSaples= dataSet.shape[0] #shape为array的属性,描述一个多维数组的维度
#计算欧式距离
diffMat = tile(inX, (numSaples,1))-dataSet #把inX二维数组化,dataSet表示生成数组后的行数,1表示列的倍数。
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1) #axis=1,表示矩阵中行之间的数的求和,等于0时表示列之间数的求和
distances = sqDistances**0.5
sortedDistances = distances.argsort() #对一个数组进行非降序排序
classCount={}
for i in range(k):
numOfLabel = labels[sortedDistances[i]]
classCount[numOfLabel]=classCount.get(numOfLabel,0)+1 #get()方法是访问字典项的方法,即访问下标键位numOflabel的项,如果没有这一项,则初始值为0
maxCount = 0
for key, value in classCount.items():
if value>maxCount:
maxCount = value
maxIndex = key
return maxIndex
测试代码:
from numpy import* import kNN dataSet,labels = kNN.createDataSet() testX = array([1.2,1.3]) k=3 output_Label = kNN.classify(testX, dataSet, labels,3) print(testX,output_Label) testX = array([0.3,0.2]) output_Label = kNN.classify(testX, dataSet, labels,3) print(testX,output_Label)
实验结果:代码中有调用tile(A,reps);函数通过reps重复A后得到一个多维数组;不了解可以查看一下[ 1.2 1.3] A [ 0.3 0.2] B