声明:未经允许,禁止转载
算法原理
k k k近邻算法是一种常见的懒惰监督学习算法,懒惰指的是该算法不需要训练,只需要计算测试样本到各个训练集样本的距离,然后找出距离测试样本最近的 k k k个训练样本:
- 对于分类任务,使用投票法,将 k k k个训练样本的大多数样本所属的类别作为该预测样本的类别;
- 对于回归任务,将 k k k个样本实值的均值作为预测结果。
在 k k k近邻算法中, k k k和距离度量的选择都十分重要, k k k取不同值时,分类结果可能会差异很大(见下图),而距离度量的不同会影响 k k k个近邻的选择。
算法实践
本文在鸢尾花数据集上进行 k k k近邻算法的实践。数据集按训练集和测试集 7 : 3 7:3 7:3的比例划分,具体实现代码如下:
import numpy as np
from scipy.spatial.distance import cdist
from scipy.stats import mode
from process import read_data
from sklearn.metrics import accuracy_score
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
class KNNClassifier:
def __init__(self, k, metric='euclidean'):
self.k = k
self.train_x = None
self.train_y = None
self.metric = metric
def fit(self, x, y):
self.train_x = x
self.train_y = y
def euclidean_distance(self, x1, x2):
return cdist(x1, x2, metric=self.metric)
def predict(self, test_x):
# 距离计算
dis_x = self.euclidean_distance(test_x, self.train_x)
# 获取测试样本对应的k个最近邻的索引
k_indices = np.argsort(dis_x, axis=1)[:, :self.k]
# 根据索引获取对应的标签
k_labels = self.train_y[k_indices]
# 对每个样本的k个最近邻的标签进行投票选出频率最高的作为预测概率
y_hat, _ = mode(k_labels, axis=1)
return y_hat
if __name__ == "__main__":
data_path = "../datasets/iris.csv"
metric = 'euclidean'
train_x, train_y, test_x, test_y = read_data(data_path)
k_max = 20
accs = []
for k in range(1, k_max + 1):
# 自建模型
cknn = KNNClassifier(k, metric)
cknn.fit(train_x, train_y)
cy_hat = cknn.predict(test_x)
custom_acc = accuracy_score(test_y.reshape(-1), cy_hat.reshape(-1))
# 调库
sknn = KNeighborsClassifier(n_neighbors=k, metric=metric)
sknn.fit(train_x, train_y)
sy_hat = sknn.predict(test_x)
sklearn_acc = accuracy_score(test_y.reshape(-1), sy_hat.reshape(-1))
accs.append(custom_acc)
print("k[{}]\tcustom acc[{}]\tsklearn acc[{}]".format(k, custom_acc, sklearn_acc))
x = np.arange(1, k_max + 1)
plt.figure()
plt.xlabel("k")
plt.ylabel("accuracy")
plt.xticks(x)
plt.plot(x, accs, marker="<")
plt.savefig("accuracy.png")
实践结果中计算了 k = [ 1 , 2 , 3 , . . . , 20 ] k=[1,2,3,...,20] k=[1,2,3,...,20]时的准确率,下图为对应的结果,横轴为 k k k的取值,纵轴为对应在测试集上的准确率:
结语
参考资料:《机器学习》周志华
源码地址:KNN
以上便是本文的全部内容,若有任何错误敬请批评指正,觉得不错的话可以支持一下,不胜感激!!!。