内容参考了某_统计学习方法_。
KNN算法的主要实现步骤:
- 计算测试数据与各训练数据之间的距离。
- 按照距离的大小进行排序。
- 选择其中距离最小的k个样本点。
- 确定K个样本点所在类别的出现频率。
- 返回K个样本点中出现频率最高的类别作为最终的预测分类。
此次实现的方式是对数据进行一个测试,并且这个knn就是单纯的近邻,没有对距离采取加权处理,并且没有使用kd树,代码如下
'''
采用线性的方式实现KNN算法
'''
import numpy as np
from collections import Counter
class KNN:
def __init__(self,x_train,y_train,k):
self.k = k
self.x_train = x_train
self.y_train =y_train
self.p = 0
def predict(self,point):
distance = [
(np.linalg.norm(point-self.x_train[i]) , self.y_train[i])
for i in range(self.x_train.shape[0])
]
distance.sort(key= lambda x: x[0])
distance = distance[:self.k]
mat ={}
for i,elm in enumerate(distance):
if elm[1] in mat:
mat[elm[1]]+= 1
else:
mat[elm[1]] =1
mated = sorted(mat.items(), key=lambda x:x[1], reverse=True)
self.p = mated[0][1]/self.k
return mated[0][0]
def main():
x_train = np.array([
[5, 4],
[9, 6],
[4, 7],
[2, 3],
[8, 1],
[7, 2],
[5,2],
[5,4]
])
y_train = np.array([1,1,1,-1,-1,-1,-2,-2])
X_new = np.array([5,4])
for k in range(1,10,2):
clf = KNN(x_train,y_train,k=k)
yp = clf.predict(X_new)
print('k',k,'predictY',yp,'p',clf.p)
if __name__ == '__main__':
main()
在这个测试中,故意添加了一些噪声,来看一看噪声对KNN的影响,因此还是建议对距离进行加权。
常见的加权是倒数和高斯加权,本文不在叙述。