基本概念
KNN(K-NearestNeighbor) K近邻算法,分类算法中最浅显易懂的一种有监督学习算法。
分类是根据距离最近的的K个点的类别来估计当前点的类别,因此距离的计算方式和K值的选择将影响分类结果。在参数确定后,临近K个点中出现类别最多的类别就是当前点的预测类型。
K值一般为奇数,通过交叉验证得到效果最好的K值,小于训练数样本的平方根。
距离计算方式一般选用欧式距离。
算法流程
- 计算测试样本与训练集每个点的距离
- 对距离进行升序排列
- 选出最近的前K个点
- 统计这K个点的类别频率,最高频率的类别即为预测类别
算法复杂度
时间复杂度和空间复杂度高,不合适大数据样本和数据特征维度高。
手动代码实现
import numpy as np
import matplotlib.pyplot as plt
# raw_data_x是特征,raw_data_y是标签,0为良性,1为恶性
raw_data_X = [[3.393533211, 2.331273381],
[3.110073483, 1.781539638],
[1.343853454, 3.368312451],
[3.582294121, 4.679917921],
[2.280362211, 2.866990212],
[7.423436752, 4.685324231],
[5.745231231, 3.532131321],
[9.172112222, 2.511113104],
[7.927841231, 3.421455345],
[7.939831414, 0.791631213]
]
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
# 设置训练组
X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)
print(X_train)
print(y_train)
print(X_train[y_train==0,0])
# 将数据可视化
plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1], color='b', label = 'Benign tumour')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1], color='y', label = 'Malignant tumor')
plt.legend()
plt.xlabel('Tumor Size')
plt.ylabel('Time')
plt.axis([0,10,0,5])
plt.show()
#计算预测点到样本点的距离
from math import sqrt
x=[8.90933607318, 3.365731514]
# 使用列表生成器,一行就能搞定,对于X_train中的每一个元素x_train都进行前面的运算,把结果生成一个列表
distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in X_train]
print(distances)
#对距离进行排序,升序,返回是索引
nearest = np.argsort(distances)
print(nearest)
#设定K为6,分别列出类别
k = 6
topK_y = [y_train[i] for i in nearest[:k]]
print(topK_y)
from collections import Counter
votes = Counter(topK_y)
print(votes)
#确定最大频率的类别,即为预测类别
# Counter.most_common(n) 找出票数最多的n个元素,返回的是一个列表,列表中的每个元素是一个元组,元组中第一个元素是对应的元素是谁,第二个元素是频次
print(votes.most_common(1))
predict_y = votes.most_common(1)[0][0]
print(predict_y)
sklearn 代码实现
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
import matplotlib.pyplot as plt
# raw_data_x是特征,raw_data_y是标签,0为良性,1为恶性
raw_data_X = [[3.393533211, 2.331273381],
[3.110073483, 1.781539638],
[1.343853454, 3.368312451],
[3.582294121, 4.679917921],
[2.280362211, 2.866990212],
[7.423436752, 4.685324231],
[5.745231231, 3.532131321],
[9.172112222, 2.511113104],
[7.927841231, 3.421455345],
[7.939831414, 0.791631213]
]
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
# 设置训练组
X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)
# 创建kNN_classifier实例
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
# kNN_classifier做一遍fit(拟合)的过程,没有返回值,模型就存储在kNN_classifier实例中
kNN_classifier.fit(X_train, y_train)
x=np.array([8.90933607318, 3.365731514])
# kNN进行预测predict,需要传入一个矩阵,而不能是一个数组。reshape()成一个二维数组,
#第一个参数是1表示只有一个数据,第二个参数-1,numpy自动决定第二维度有多少
y_predict = kNN_classifier.predict(x.reshape(1,-1))
print(y_predict)