算法简介
物以类聚人以群分,kNN算法正是如此,它是机器学习中一个非常基础的算法,经常用于分类问题,也可以用于回归预测。
1.算法优缺点
优点:简单易用,不需要较高的数学知识也能理解;预测效果好,并且训练模型时间快;对于异常值也不是很敏感。
缺点:计算量大;需要占用较多的内存;懒惰学习,预测速度慢。
2.什么是k
在这个算法中,k指的是距离目标最近的k个实例,并根据哪种实例的数量更多来对目标进行分类,当k取1时,将离目标最近的实例标签赋给目标,也称最近邻分类。
3.计算距离的方法
采用欧式距离的方法计算
在二维平面上对于两点(x1,x2)和(y1,y2)
d12=(x1−x2)2+(y1−y2)2
kNN实现
以电影分类为例子,通过对电影中出现的打斗镜头次数和亲吻镜头次数统计,来对电影进行分类,分为爱情片和动作片。
影片名称 | 打斗镜头次数 | 亲吻镜头次数 | 电影类型 |
---|---|---|---|
天龙特工队 | 115 | 6 | 动作片 |
生死狙击 | 109 | 8 | 动作片 |
敢死队1 | 120 | 9 | 动作片 |
恋恋笔记本 | 5 | 78 | 爱情片 |
花样年华 | 6 | 60 | 爱情片 |
爱在黎明破晓时 | 8 | 69 | 爱情片 |
实现代码如下:
from matplotlib import pyplot as plt
from numpy import *
import operator
def createDataSet():
group = array([[115, 6], [109, 8], [120, 9], [5, 78], [6, 60], [8, 69]])
labels = ['动作片', '动作片', '动作片', '爱情片', '爱情片', '爱情片']
return group, labels
def classifyKNN(inX, dataSet, labels, k):
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) :
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
def data_show(in_data, train_data):
# 显示训练数据
x = []
y = []
for i in range(train_data.shape[0]):
x.append(train_data[i][0])
y.append(train_data[i][1])
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot(x, y, "*")
plt.xlabel("打斗镜头出现次数")
plt.ylabel("接吻镜头出现次数")
plt.plot(in_data[0], in_data[1], "r*")
plt.show()
if __name__ == '__main__':
group, labels = createDataSet()
#测试集
test = [10, 99]
#kNN分类
test_class = classifyKNN(test, group, labels, 3)
#打印分类结果
print(test_class)
data_show(test, group)
通过计算测试集和每个点之间的距离,可以通过计算欧式距离的方法来计算,找出k个距离最近的点,出现次数最多的实例类别就是测试数据的类别。
测试数据的电影类型为爱情片。
总结
kNN算法需要计算样本点和测试点之间的距离,当数据量非常庞大的时候,计算量就会边的庞大,相应的占用内存和时间就会变多。
在选择k值的时候也要根据具体的实验数据来进行选择,调试出最适合的k值。
当某类样本数据较少,分类不均衡时,其对应的准确性就会降低,在处理样本数据的时候也要注意。