K-近邻算法(K-Nearst Neighbor)基本是机器学习过程中接触的第一个算法。接下来,我们从以下几个方面来讲解下该算法:
-
K-近邻算法实现思路
-
K-近邻算法基本要素
-
sklearn 代码实现
-
K-近邻算法实现思路 {#title-0}
K-近邻算法的思路是:在训练样本中,如果一个测试样本附近的 K 个最接近的训练样本的大多数属于某一个类别,则该测试样本也属于这个类别。
我们将该算法的实现步骤分解如下:
- 获得一个测试样本 s;
- 计算该测试样本 s 到所有训练样本 t~1~, t~2~ ... t~n~ 的距离;
- 获得 K 个距离测试样本 s 最近的训练样本;
- 如果 K 个样本中,多数属于 C 类别,则认为测试样本 s 也属于 C 类别。
请继续看下面的示意图:
假设:我们现在要判断一个测试样本(绿色圆形)属于哪个分类,按照 K-近邻算法思路,其过程如下:
首先,计算测试样本(绿色圆形)到其他的每一个训练样本(所有蓝色的方块、红色的三角形)之间的距离。
然后,找到距离测试样本(绿色圆形)最近的 K 个训练样本:
如上图所示,如果 K 的值为 3,则实线圆圈范围内是选出的训练样本,由于红色三角形比较多,所以,就认为绿色圆形属于红色三角形所属的类别。
如果 K 的值是 5,则虚线圆圈范围内是选出的训练样本,由于蓝色方块比较多,所以,就认为绿色圆形属于蓝色方块所属的类别。
- K-近邻算法基本要素 {#title-1}
在 K-近邻算法中,我们可以看到有几个基本要素:
2.1 分类规则 {#title-2}
K-近邻算法使用多数表决来确定类别,即由输入测试样本的 K 个近邻的训练样本中的多数决定测试样本的类别。
2.2 距离计算 {#title-3}
实际上,距离的度量方式有很多,不同的度量方式会导致临近点是不同的。
2.3 K 值确定 {#title-4}
K 值得选择会影响到测试样本邻近的训练样本数量,并影响最终的结果。
如果确定的 K 值较小时,意味着选取的邻近训练样本个数少,只有距离测试样本较近的训练样本才会对结果起作用,近似误差会减少,但是估计误差会增大,近邻的训练样本会对结果影响较大。所以,K 值一般选择较小的整数,具体的数值需要经过反复测试来获得。
- sklearn 代码实现 {#title-5} ==========================
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def iris_data():
"""
鸢尾花数据信息
"""
# 1. 加载红酒数据集
dataset = load_iris()
# 样本数量
print("样本数量:", len(dataset.data))
# 类别名称
print("类别名称:", dataset.target_names)
# 特征名称
print("特征名称:", dataset.feature_names)
# 样本类别
print("样本类别:", dataset.target)
# 样本数据
print("样本数据:", dataset.data)
# knn API
def knn_api():
# 1. 加载鸢尾花数据
iris_dataset = load_iris()
# 2. 创建 knn 分类对象
knn = KNeighborsClassifier(n_neighbors=3)
# 3. 将数据集划分为训练集和测试集[测试集占所有数据集的20%]
X_train, X_test, y_train, y_test = \
train_test_split(iris_dataset.data, iris_dataset.target, test_size=0.2)
# 4. 训练数据
knn.fit(X_train, y_train)
# 5. 进行预测
for index in range(len(X_test)):
# 5.1 计算当前测试样本属于哪个分类
class_label = knn.predict([X_test[index]])
# 5.2 计算当前测试样本属于每个分类的概率
class_proba = knn.predict_proba([X_test[index]])
# 5.3 返回距离当前测试样本最近的 N 个样本
nearest_neighbors = knn.kneighbors([X_test[index]], 5, False)
# 预测准确率
predict_score = knn.score(X_test, y_test, sample_weight=None)
print("准确率:", predict_score)
if __name__ == "__main__":
knn_api()