起步
本章介绍如何自行构造 KNN
分类器,这个分类器的实现上算是比较简单的了。不过这可能需要你之前阅读过这方面的知识。
前置阅读
欧拉公式衡量距离
关于距离的测量方式有多种,这边采用欧拉距离的测量方式:
$$ d(x,y) = \sqrt{\sum_{i=0}^n(x_i-y_i)^2} $$
对应的 python 代码:
import math
def euler_distance(point1: list, point2: list) -> float:
"""
计算两点之间的欧拉距离,支持多维
"""
distance = 0.0
for a, b in zip(point1, point2):
distance += math.pow(a - b, 2)
return math.sqrt(distance)
KNN 分类器
import collections
import numpy as np
class KNeighborsClass(object):
def __init__(self, n_neighbors=5):
self.n_neighbors = n_neighbors
def fit(self, data_set, labels):
self.data_set = data_set
self.labels = labels
def predict(self, test_row):
dist = []
for v in self.data_set:
dist.append(euler_distance(v, test_row))
dist = np.array(dist)
sorted_dist_index = np.argsort(dist) # 根据元素的值从大到小对元素进行排序,返回下标
# 根据K值选出分类结果, ['A', 'B', 'B', 'A', ...]
class_list = [ self.labels[ sorted_dist_index[i] ] for i in range(self.n_neighbors)]
result_dict = collections.Counter(class_list) # 计算各个分类出现的次数
ret = sorted(result_dict.items(), key=lambda x: x[1], reverse=True) # 采用多数表决,即排序后的第一个分类
return ret[0][0]
这个分类器不需要训练,因此在 fit
函数中仅仅保存其数据集和结果集即可。在预测函数中,需要依次计算测试样本与数据集中每个样本的距离。筛选出前 K
个,采用多数表决的方式。
测试
还是使用 sklearn
中提供的虹膜数据。
if __name__ == "__main__":
from sklearn import datasets
iris = datasets.load_iris()
knn = KNeighborsClass(n_neighbors=5)
knn.fit(iris.data, iris.target)
predict = knn.predict([0.1, 0.2, 0.3, 0.4])
print(predict) # output: 1