您的位置:首页 > 编程语言 > Python开发

机器学习算法与Python实践(5) - 最邻近分类算法(KNN)

2017-11-23 18:04 447 查看

K-Nearest Neighbor(KNN)

简称KNN,最常用的机器学习算法之一,核心思想俗称“随大流”。是一种分类算法,基于实例的学习(instance-based learning)和懒惰学习(lazy learning)。

懒惰学习:指的是在训练是仅仅是保存样本集的信息,直到测试样本到达是才进行分类决策。

核心思想:

在距离空间里,如果一个样本的最接近的k个邻居里,绝大多数属于某个类别,则该样本也属于这个类别。

举个例子:

训练:

电影名称打架(次)接吻(次)电影类型
北京遇上西雅图3104爱情
喜欢你2100爱情
疯狂动物城181爱情
战狼210110动作
力王995动作
敢死队982动作
测试

电影名称打架(次)接吻(次)电影类型
你的名字1890未知
之后需要求出电影《你的名字》的电影类型,我们可以用我们学过的知识进行计算。将所有点与“未知”的电影《你的名字》进行距离计算,因为这个例子是二维的,因此这里我们使用E(x,y)=sqrt((x2−x1)2+(y2−y1)2),如果是多维的话,可以使用:

x=∑ni=0(xi−yi)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾√

计算出来的结果如下:

电影名称与《你的名字》的距离
北京遇上西雅图20.5
喜欢你18.7
疯狂动物城19.2
战狼2115.3
力王117.4
敢死队118.9
那么现在我们得到了样本集与《你的名字》的距离,按照距离的递增顺序,可以找到k个距离最近的电影,假定k=3,则三个最靠近的电影是和《北京遇上西雅图》,《喜欢你》,《疯狂动物城》, kNN算法按照距离最近的三部电影类型决定未知电影类型,这三部都是爱情片,所以未知电影的类型也为爱情片。(如果三部中有两部爱情片,一部动作片,以多的类型确定)

从上面的例子中我们总结出—>KNN算法的一般流程:

初始化距离为最大值

计算未知样本和每个训练样本的距离dist

得到目前K个最临近样本中的最大距离maxdist

如果dist小于maxdist,则将该训练样本作为K-最近邻样本

重复步骤2、3、4,直到未知样本和所有训练样本的距离都算完

统计K-最近邻样本中每个类标号出现的次数

选择出现频率最大的类标号作为未知样本的类标号

KNN算法的Python代码实现(直接调包)

'''机器学习算法与Python实践(5) - 最邻近分类算法(KNN)'''
import numpy as np
from sklearn import neighbors
import warnings

warnings.filterwarnings('ignore')  # warning信息不打印,可有可无

knn = neighbors.KNeighborsClassifier()  # 取得knn分类器

data = np.array([[3, 104], [2, 100], [1, 81],
[101, 10], [99, 5], [98, 2]])  # data对应着打斗次数和接吻次数

labels = np.array([1, 1, 1, 2, 2, 2])  # labels则是对应 1:爱情片 和 2:动作片
knn.fit(data, labels)  # 导入数据进行训练

print('预测电影类型为:', knn.predict([18, 90]))


运行结果如下:



KNN算法的Python代码实现(实现)

# encoding:utf-8
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):
# 返回“数组”的行数,如果shape[1]返回的则是数组的列数
dataSetSize = dataSet.shape[0]
# 两个“数组”相减,得到新的数组
diffMat = tile(inX, (dataSetSize, 1)) - dataSet
# 求平方
sqDiffMat = diffMat ** 2
# 求和,返回的是一维数组
sqDistances = sqDiffMat.sum(axis=1)
# 开方,即测试点到其余各个点的距离
distances = sqDistances ** 0.5
# 排序,返回值是原数组从小到大排序的下标值
sortedDistIndicies = distances.argsort()
# 定义一个空的字典
classCount = {}
for i in range(k):
# 返回距离最近的k个点所对应的标签值
voteIlabel = labels[sortedDistIndicies[i]]
# 存放到字典中
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
# 排序 classCount.iteritems() 输出键值对 key代表排序的关键字 True代表降序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
# 返回距离最小的点对应的标签

return sortedClassCount[0][0]

group, labels = createDataSet()
tmp = classify0([0, 0], group, labels, 3)
print(tmp)


运行结果如下:



参考文章:

《机器学习实战》k最近邻算法(K-Nearest Neighbor,Python实现)

K-Nearest Neighbor(KNN) 最邻近分类算法及Python实现方式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: