菜鸟起飞——机器学习实战第二篇:k-近邻算法

来源:互联网 发布:c语言是面向过程 编辑:程序博客网 时间:2024/05/16 08:16

本文是第二篇kNN算法篇,我将从原理、数学模型、代码实现到案例分析这四个步骤来依次展开这一章所有的内容。

番外:

首先,我们说一下python代码如何运行。

我们保存以下代码为knn.py

from numpy import *     #导入模块import operatordef 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 operatordef createDataSet():group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels = ['A','A','B','B']return group, labelsdef 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


0 0
原创粉丝点击