k近邻算法作为机器学习中可谓是最基础、最简单的一个算法,而且,它可以被认为是一个不需要构造模型只需要训练集经过计算处理就能得出结果的机器学习算法。那么,KNN算法到底是怎么实现的呢?
首先我们以判断肿瘤性质为案例,假如我们得到这样一个数据训练集:
raw_data_x = ([
[3.39353321, 2.33127338],
[3.21137674, 1.72371642],
[1.34657826, 3.34687858],
[3.58467832, 4.66841268],
[2.23684678, 2.86473684],
[7.45723474, 4.68964178],
[5.76727424, 3.46826478],
[9.13414325, 2.57938724],
[7.64781628, 3.46783268],
[7.93974896, 0.79486123]
])
每个小矩阵代表着不同病人的病例特征,第一个值为肿块的大小,第二个为发现肿瘤的时间
而这些病人肿瘤性质我们用0和1来表示,0代表良性,1代表恶性。所以有:
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
则我们可以绘制散点图:(红点为恶性,绿点为良性)
现在我们要来用kNN算法判断
exam_x = np.array([8.09632767, 3.64782264])
这组数据的病人的肿瘤性质。
我们定义一个k=3,然后对 待判断的点(用蓝点表示)进行判断到底属于红点还是绿点,我们就对这个点附近的区域最邻近的3(k)个点进行判断:
接下来我们就来计算这个待检测的点与邻近点的距离,由于训练集的特征值为n,即可能出现多维的情况,所以这里我们计算欧拉距离:
最后,只需要看和它最相似的这些样本中哪个类别的点最多,那么这个点就最有可能为对应类别的点。
以上的过程我们写成程序可以表示为:
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
from collections import Counter
raw_data_x = ([[3.39353321, 2.33127338],
[3.21137674, 1.72371642],
[1.34657826, 3.34687858],
[3.58467832, 4.66841268],
[2.23684678, 2.86473684],
[7.45723474, 4.68964178],
[5.76727424, 3.46826478],
[9.13414325, 2.57938724],
[7.64781628, 3.46783268],
[7.93974896, 0.79486123]])
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
x = np.array(raw_data_x)
y = np.array(raw_data_y)
exam_x = np.array([8.09632767, 3.64782264])
plt.scatter(x[y == 0, 0], x[y == 0, 1], color="g")
plt.scatter(x[y == 1, 0], x[y == 1, 1], color="r")
plt.scatter(exam_x[0], exam_x[1], color="b")
k = 6
distances = [(sqrt(np.sum(x - exam_x) ** 2)) for x in x]
nearest = np.argsort(distances)
top_y = [y[i] for i in nearest[:k]]
votes = Counter(top_y)
predict_y = votes.most_common(1)[0][0]
print(predict_y)
plt.show()
而在python中,已经有第三方库帮我们很好地封装了KNN算法,并且运用了严格地面向对象编程的形式
比如上面那个例子,我们可以写成:
from sklearn.neighbors import KNeighborClassifier
kNN_classifier=KNeighborClassifier(n_neighbors=6)
kNN_classifier.fit(x,y)
x_predict=exam_x.reshape(1,-1)
y_predict=kNN_classifier.predict(x_predict)
print(y_predict)
我们可以得到最后y_predict的值为1,也就是说,我们通过kNN算法计算出的待判断病人肿瘤性质比较可能为恶性。
希望对读者有所帮助,喜欢的话可以关注一下我的公众号,我会把学习笔记发在上面,大家可以一起共同学习!