KNN手撕算法

KNN

knn属于机器学习中的一个预测模型,属于监督性学习

算法如下:

1.计算想要分类的点到其余点的距离
2.按距离升序排列,并选出前K(KNN的K)个点,也就是距离样本点最近的K个点
距离公式有:
欧式距离
明可夫距离
马氏距离
3.加权平均,得到答案

代码如下


import numpy as np
import matplotlib.pyplot as plt
def CanberraDistance(x, y):
   d = 0
   for i in range(len(x)):
        #if x[i] == 0 and y[i] == 0:
            #d += 0
        #else:
            #d += abs(x[i] - y[i]) / (abs(x[i]) + abs(y[i]))
       d += (x[i] - y[i])**3
   return abs(d)**(1/3)
data_path = "data2.txt"
data = []
labels = []
with open(data_path, "r") as f:
    lines = f.readlines()
    for line in lines:
        temp = line.split(",")
        data.append(list(map(float, temp[:-1])))
        labels.append(temp[-1].strip())
data = np.array(data)
labels = np.array(labels)
temp_data = data.copy()
data = (data - np.min(data, axis=0)) / (np.max(data, axis=0) - np.min(data, axis=0))

center = np.array([[1.687, 0.445,2.327,0.436], [0.914, 0.632, 2.536, 1.123], [0.753, 0.457, 2.323, 0.442], [2.051, 1.407, 1.993, 1.630]])
center = (center - np.min(temp_data, axis=0)) / (np.max(temp_data, axis=0) - np.min(temp_data, axis=0))

center_label = ["Slight-Right-Turn", "Move-Forward", "Sharp-Right-Turn", "Slight-Left-Turn"]
predict_label = []
for i in range(data.shape[0]):
    the_min = float("inf")
    this_label = ""
    for j, c in enumerate(center):
        d = CanberraDistance(data[i], c)
        if d < the_min:
            this_label = center_label[j]
            the_min = d
    predict_label.append(this_label)
predict_label = np.array(predict_label)
print(f"预测正确的概率为{sum(predict_label == labels) / len(labels):.2%}")
print(f"预测错误的概率为{1 - sum(predict_label == labels) / len(labels):.2%}")
maps = dict(zip(center_label, list(range(len(center_label)))))
predict_label = np.array([maps[x] for x in predict_label])

plt.scatter(data[:, 0], data[:, 1], c=predict_label, alpha=0.5)
plt.show()

你可能感兴趣的:(机器学习,机器学习)