本文采用编译器:jupyter
k近邻(简称kNN)算法是一种常用的监督学习算法, 其工作机制非常简单 : 给定测试样本,基于某种距离度量找出训练集中与其最靠近的 k个训练样本,然后基于这 k个"邻居"的信息来进行预测。
通常, 在分类任务中可使用"投票法" 即选择这 k个样本中出现最多的类别标记作为预测结果;还可基于距离远近进行加权平均或加权投票,距离越近的样本权重越大。
kNN算法的示意图如下,可以很明显的看出当k取值不同时,判别结果可能产生较大的差异。
可以看出它天然的可以解决多分类问题,思想简单却十分强大!
01 kNN基础
以下为数据准备阶段
# 导入所需要的两个包 import numpy as np import matplotlib.pyplot as plt # 各数据点 raw_data_X = [[3.3935, 2.3312], [3.1100, 1.7815], [1.3438, 3.3683], [3.5822, 4.6791], [2.2803, 2.8669], [7.4234, 4.6965], [5.7450, 3.5339], [9.1721, 2.5111], [7.7927, 3.4240], [7.9398, 0.7916] ] # 各数据点所对应的标记 raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] X_train = np.array(raw_data_X) y_train = np.array(raw_data_y) #绘制散点图 plt.scatter(X_train[y_train==0, 0], X_train[y_train==0, 1], color='g') plt.scatter(X_train[y_train==1, 0], X_train[y_train==1, 1], color='r') plt.show() # 模拟待分类数据 x = np.array([8.0936, 3.3657]) plt.scatter(X_train[y_train==0, 0], X_train[y_train==0, 1], color='g') plt.scatter(X_train[y_train==1, 0], X_train[y_train==1, 1], color='r') plt.scatter(x[0], x[1], color='b') plt.show()
执行结果:
kNN的过程
1.计算待测数据与所有数据点的“距离”
2.指定k的大小
3.找出模型中与待测点最近的k个点
4.应用“投票法”预测出分类结果
# 计算欧拉距离所需跟方操作 from math import sqrt distances = [] for x_train in X_train: d = sqrt(np.sum((x_train - x) ** 2)) # Universal distances.append(d) # distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in X_train] nearest = np.argsort(distances) # 找离x最近的k个点的索引 # 指定k k = 6 # 计算最近点k个点 topK_y = [y_train[i] for i in nearest[:k]] # 使用Counter方法统计标签类别 from collections import Counter votes = Counter(topK_y) votes.most_common(1) # 找出票数最多的那1个类别, # Out[22]: # [(1, 5)] predict_y = votes.most_common(1)[0][0] # 预测结果 predict_y # Out[27]: # 1
02 使用scikit_learn中的kNN
python标准库scikit_learn中也为我们封装好了kNN算法
# 导入kNN算法 from sklearn.neighbors import KNeighborsClassifier # 创建分类器对象 kNN_classifier = KNeighborsClassifier(n_neighbors=6) kNN_classifier.fit(X_train, y_train) # 先训练模型 “”“ fit方法返回对象本身 Out[7]: KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=6, p=2, weights='uniform') ”“” X_predict = x.reshape(1, -1) # 传入的数据需要是一个矩阵,这里待预测的x只是一个向量 X_predict # Out[9]: # array([[ 8.0936, 3.3657]]) y_predict = kNN_classifier.predict(X_predict) y_predict[0] # Out[13]: # 1