本文是第二篇kNN算法篇,我将从原理、数学模型、代码实现到案例分析这四个步骤来依次展开这一章所有的内容。
番外:
首先,我们说一下python代码如何运行。
我们保存以下代码为knn.py
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
上文中spyder这个ide可以直接run(运行),但我们这里采用notepad++加cmd方式。(cmd相关知识传送门:http://www.crifan.com/files/doc/docbook/soft_dev_basic/release/html/soft_dev_basic.html#win_cmd)
这里仍然有两种方式:
①cmd中输入python,进入python开发环境,即进入>>>这样的环境
>>>import knn
>>>groups,labels = knn.createDataSet()
>>>groups(or labels)
>>>显示
②在knn.py中写入main方法(当然这里没得显示,因为createDataSet()只是导入数据)
if __name__ == "__main__":
createDataSet()
cmd输入knn.py
一、kNN原理
定义:采用不同特征值之间的距离方法进行分类。
原理:我们知道样本集中每一数据与所属分类的对应关系,输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
优点: 精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高
使用数据范围:数值型和标称型
根据四则运算法,我们①两个减法运算;②两个差值分别平方③上述结果相加④开根;我们根据这样的顺序来编写代码。
核心代码(写入knn.py):
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 classify0(inX, dataSet, labels, k): #用于分类的inX,输入的训练样本集dataSet,便签向量labels,k为近邻数目。
dataSetSize = dataSet.shape[0] #shape函数取第一维长度,即样本集中的行数,或者直观理解为[]的个数,通常和tile()一起使用
diffMat = tile(inX, (dataSetSize,1)) - dataSet #tile函数为copy函数,可以想象为卡卡西的写轮眼。。。将输入向量复制为样本集同行的矩阵,便于计算
sqDiffMat = diffMat**2 #diffMat里是差值的矩阵(虽然numpy中array和matrix不同,我们这里仍然理解为矩阵)
sqDistances = sqDiffMat.sum(axis=1) #指array中每行元素的和,这些和再组成一个array,但是如果array只有一行,只能用sum()
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort() #argsort()返回的是从小到大的索引值
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #这里classCount.get(voteIlabel, 0)是指不存在相对应key值的value则返回0
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)#3.5版本中numpy.iteritems()改为.items()
return sortedClassCount[0][0] #sorted() 按classCount字典的第2个元素(即类别出现的次数)从大到小排序
测试:
cmd输入python,进入Python开发环境
>>>knn.classify0([0,0],group,labels,3) #结果应该为B