最近邻规则分类KNN
KNN例子
- 为了判断未知实例的类别,以所有已知类别的实例作为参照选择参数K
- 计算未知实例与所有已知实例的距离
- 选择最近K个已知实例
- 根据少数服从多数的投票法则,让未知实例归类为K个最邻近样本中最多数的类别
欧式距离
E(x,y)=∑i=0n(xi−yi)2 E(x, y) = \sqrt{\sum_{i=0}^{n}(x_i-y_i)^{2}} E(x,y)=i=0∑n(xi−yi)2
算法的缺点
- 算法复杂度高(需要比较所有已知实例与要分类的实例)
- 当其样本分布不平衡时,比如其中一类样本过大(实例数量过多)占主导的时候,新的未知实例容易被归类为这个主导样本,因为这类样本实例的数量过大,但这个新的未知实例实际并没有接近目标样本。
import matplotlib.pyplot as plt
import numpy as np
import operator
# 已知分类的数据
x1 = np.array([3, 2, 1])
y1 = np.array([104, 100, 81])
x2 = np.array([101, 99, 98])
y2 = np.array([10, 5, 2])
scatter1 = plt.scatter(x1, y1, c='r')
scatter2 = plt.scatter(x2, y2, c='b')
# 位置数据
x = np.array([18])
y = np.array([90])
scatter3 = plt.scatter(x, y, c='k')
#画图
plt.legend(handles = [scatter1, scatter2, scatter3], labels=['labelA','labelB','labelC'], loc='best')
plt.show()
# 已知分类的数据
x_data = np.array([[3, 104],
[2, 100],
[1, 8],
[101, 10],
[95, 5],
[81, 2]])
y_data = np.array(['A', 'A', 'A', 'B', 'B', 'B'])
x_test = np.array([18, 90])
# 计算样本量
x_data_size = x_data.shape[0]
# 计算x_test与每一个样本的差值
diffMat = np.tile(x_test, (x_data_size, 1)) - x_data
# 计算差值平方
sqDiffMat = diffMat ** 2
# 求和
sqDistances = sqDiffMat.sum(axis = 1)
# 开方
distances = np.sqrt(sqDistances)
# 从小到大进行排序
sortedDistances = distances.argsort()
classCount = {}
#设置k
k = 5
for i in range(k):
#获取标签
votelabel = y_data[sortedDistances[i]]
# 统计标签数量
classCount[votelabel] = classCount.get(votelabel,0)+1
# 根据operator.itemgetter(1)-第一个值对classCount排序,然后再取倒序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#获取数量最多的标签
knnclass = sortedClassCount[0][0]
print(knnclass)