关于机器学习:机器学习算法三基于horsecolic数据的KNN近邻knearest-neighbors预测分类

2次阅读

共计 14863 个字符,预计需要花费 38 分钟才能阅读完成。

机器学习算法(三):基于 horse-colic 数据的 KNN 近邻 (k-nearest neighbors) 预测分类

我的项目链接参考:https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc

1 KNN 的介绍和利用

1.1 KNN 的介绍

kNN(k-nearest neighbors),中文翻译 K 近邻。咱们经常听到一个故事:如果要理解一个人的经济程度,只须要晓得他最好的 5 个敌人的经济能力,
对他的这五个人的经济程度求均匀就是这个人的经济程度。这句话外面就蕴含着 kNN 的算法思维。

<img src=’https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/knn_demo.png’/>

示例:如上图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果 K =3,因为红色三角形所占比例为 2 /3,绿色圆将被赋予红色三角形那个类,如果 K =5,因为蓝色四方形比例为 3 /5,因而绿色圆被赋予蓝色四方形类。

1) KNN 建设过程

1 给定测试样本,计算它与训练集中的每一个样本的间隔。2 找出间隔近期的 K 个训练样本。作为测试样本的近邻。3 根据这 K 个近邻归属的类别来确定样本的类别。

2) 类别的断定

①投票决定,多数遵从少数。取类别最多的为测试样本类别。

②加权投票法,根据计算得出间隔的远近,对近邻的投票进行加权,间隔越近则权重越大,设定权重为间隔平方的倒数。

1.2 KNN 的利用

KNN 尽管很简略,然而人们常说 ” 大道至简 ”,一句 ” 物以类聚,人以群分 ” 就能揭开其面纱,看似简略的 KNN 即能做分类又能做回归,
还能用来做数据预处理的缺失值填充。因为 KNN 模型具备很好的解释性,个别状况下对于简略的机器学习问题,咱们能够应用 KNN 作为
Baseline,对于每一个预测后果,咱们能够很好的进行解释。举荐零碎的中,也有着 KNN 的影子。例如文章举荐零碎中,
对于一个用户 A,咱们能够把和 A 最相近的 k 个用户,浏览过的文章推送给 A。

机器学习畛域中,数据往往很重要,有句话叫做:” 数据决定工作的下限, 模型的指标是有限靠近这个下限 ”。
能够看到好的数据十分重要,然而因为各种起因,咱们失去的数据是有缺失的,如果咱们可能很好的填充这些缺失值,
就可能失去更好的数据,以至于训练进去更鲁棒的模型。接下来咱们就来看看 KNN 如果做分类,怎么做回归以及怎么填充空值。

2 实验室手册

2.1 试验环境

1. python3.7
2. numpy >= '1.16.4'
3. sklearn >= '0.23.1'

2.2 学习指标

  1. 理解 KNN 怎么做分类问题
  2. 理解 KNN 如何做回归
  3. 理解 KNN 怎么做空值填充, 如何应用 knn 构建带有空值的 pipeline

2.3 代码流程

  1. 二维数据集 –knn 分类

    • Step1: 库函数导入
    • Step2: 数据导入
    • Step3: 模型训练 & 可视化
    • Step4: 原理简析
  2. 莺尾花数据集 –kNN 分类

    • Step1: 库函数导入
    • Step2: 数据导入 & 剖析
    • Step3: 模型训练
    • Step4: 模型预测 & 可视化
  3. 模仿数据集 –kNN 回归

    • Step1: 库函数导入
    • Step2: 数据导入 & 剖析
    • Step3: 模型训练 & 可视化
  4. 马绞痛数据 –kNN 数据预处理 +kNN 分类 pipeline

    • Step1: 库函数导入
    • Step2: 数据导入 & 剖析
    • Step3: KNNImputer 空值填充 – 应用和原理介绍
    • Step4: KNNImputer 空值填充 – 欧式间隔的计算
    • Step5: 基于 pipeline 模型预测 & 可视化

2.4 算法实战

2.4.1 Demo 数据集 –kNN 分类

Step1: 库函数导入

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets

Step2: 数据导入

# 应用莺尾花数据集的前两维数据,便于数据可视化
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target

Step3: 模型训练 & 可视化

k_list = [1, 3, 5, 8, 10, 15]
h = .02
# 创立不同色彩的画布
cmap_light = ListedColormap(['orange', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])

plt.figure(figsize=(15,14))
# 依据不同的 k 值进行可视化
for ind,k in enumerate(k_list):
    clf = KNeighborsClassifier(k)
    clf.fit(X, y)
    # 画出决策边界
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    # 依据边界填充色彩
    Z = Z.reshape(xx.shape)

    plt.subplot(321+ind)  
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    # 数据点可视化到画布
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.title("3-Class classification (k = %i)"% k)

plt.show()

Step4: 原理简析

如果抉择较小的 K 值,就相当于用较小的畛域中的训练实例进行预测,例如当 k = 1 的时候,在分界点地位的数据很容易受到部分的影响,图中蓝色的局部中还有局部绿色块,次要是数据太部分敏感。当 k =15 的时候,不同的数据根本依据色彩离开,过后进行预测的时候,会间接落到对应的区域,模型绝对更加鲁棒。

2.4.2 莺尾花数据集 –kNN 分类

Step1: 库函数导入
Step2: 数据导入 & 剖析

import numpy as np
# 加载莺尾花数据集
from sklearn import datasets
# 导入 KNN 分类器
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
# 导入莺尾花数据集
iris = datasets.load_iris()

X = iris.data
y = iris.target
# 失去训练汇合和验证汇合, 8: 2
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

Step3: 模型训练

这里咱们设置参数 k(n_neighbors)=5, 应用欧式间隔(metric=minkowski & p=2)

# 训练模型
clf = KNeighborsClassifier(n_neighbors=5, p=2, metric="minkowski")
clf.fit(X_train, y_train)

Step4: 模型预测 & 可视化

# 预测
X_pred = clf.predict(X_test)
acc = sum(X_pred == y_test) / X_pred.shape[0]
print("预测的准确率 ACC: %.3f" % acc)

预测的准确率 ACC: 0.933

咱们用表格来看一下 KNN 的训练和预测过程。这里用表格进行可视化:

  1. 训练数据[表格对应 list]
feat_1 feat_2 feat_3 feat_4 label
5.1 3.5 1.4 0.2 0
4.9 3. 1.4 0.2 0
4.7 3.2 1.3 0.2 0
4.6 3.1 1.5 0.2 0
6.4 3.2 4.5 1.5 1
6.9 3.1 4.9 1.5 1
5.5 2.3 4. 1.3 1
6.5 2.8 4.6 1.5 1
5.8 2.7 5.1 1.9 2
7.1 3. 5.9 2.1 2
6.3 2.9 5.6 1.8 2
6.5 3. 5.8 2.2 2
  1. knn.fit(X, y)的过程能够简略认为是表格存储
feat_1 feat_2 feat_3 feat_4 label
5.1 3.5 1.4 0.2 0
4.9 3. 1.4 0.2 0
4.7 3.2 1.3 0.2 0
4.6 3.1 1.5 0.2 0
6.4 3.2 4.5 1.5 <font color=”coral”>1</font>
6.9 3.1 4.9 1.5 <font color=”coral”>1</font>
5.5 2.3 4. 1.3 <font color=”coral”>1</font>
6.5 2.8 4.6 1.5 <font color=”coral”>1</font>
5.8 2.7 5.1 1.9 <font color=”lilac”>2</font>
7.1 3. 5.9 2.1 <font color=”lilac”>2</font>
6.3 2.9 5.6 1.8 <font color=”lilac”>2</font>
6.5 3. 5.8 2.2 <font color=”lilac”>2</font>
  1. knn.predict(x)预测过程会计算 x 和所有训练数据的间隔
    这里咱们应用欧式间隔进行计算, 预测过程如下

$$
x = [5. , 3.6, 1.4, 0.2] \\
y=0
$$

step1: 计算 x 和所有训练数据的间隔

feat_1 feat_2 feat_3 feat_4 间隔 label
5.1 3.5 1.4 0.2 <font color=”green”>0.14142136</font> 0
4.9 3. 1.4 0.2 <font color=”green”>0.60827625</font> 0
4.7 3.2 1.3 0.2 <font color=”green”>0.50990195</font> 0
4.6 3.1 1.5 0.2 <font color=”green”>0.64807407</font> 0
6.4 3.2 4.5 1.5 <font color=”green”>3.66333182</font> <font color=”coral”>1</font>
6.9 3.1 4.9 1.5 <font color=”green”>4.21900462</font> <font color=”coral”>1</font>
5.5 2.3 4. 1.3 <font color=”green”>3.14801525</font> <font color=”coral”>1</font>
6.5 2.8 4.6 1.5 <font color=”green”>3.84967531</font> <font color=”coral”>1</font>
5.8 2.7 5.1 1.9 <font color=”green”>4.24617475</font> <font color=”lilac”>2</font>
7.1 3. 5.9 2.1 <font color=”green”>5.35070089</font> <font color=”lilac”>2</font>
6.3 2.9 5.6 1.8 <font color=”green”>4.73075047</font> <font color=”lilac”>2</font>
6.5 3. 5.8 2.2 <font color=”green”>5.09607692</font> <font color=”lilac”>2</font>

step2: 依据间隔进行编号排序

间隔升序编号 feat_1 feat_2 feat_3 feat_4 间隔 label
<font color=”indigo”>1</font> 5.1 3.5 1.4 0.2 <font color=”green”>0.14142136</font> 0
<font color=”indigo”>3</font> 4.9 3. 1.4 0.2 <font color=”green”>0.60827625</font> 0
<font color=”indigo”>2</font> 4.7 3.2 1.3 0.2 <font color=”green”>0.50990195</font> 0
<font color=”indigo”>4</font> 4.6 3.1 1.5 0.2 <font color=”green”>0.64807407</font> 0
<font color=”indigo”>6</font> 6.4 3.2 4.5 1.5 <font color=”green”>3.66333182</font> <font color=”coral”>1</font>
<font color=”indigo”>8</font> 6.9 3.1 4.9 1.5 <font color=”green”>4.21900462</font> <font color=”coral”>1</font>
<font color=”indigo”>5</font> 5.5 2.3 4. 1.3 <font color=”green”>3.14801525</font> <font color=”coral”>1</font>
<font color=”indigo”>7</font> 6.5 2.8 4.6 1.5 <font color=”green”>3.84967531</font> <font color=”coral”>1</font>
<font color=”indigo”>9</font> 5.8 2.7 5.1 1.9 <font color=”green”>4.24617475</font> <font color=”lilac”>2</font>
<font color=”indigo”>12</font> 7.1 3. 5.9 2.1 <font color=”green”>5.35070089</font> <font color=”lilac”>2</font>
<font color=”indigo”>10</font> 6.3 2.9 5.6 1.8 <font color=”green”>4.73075047</font> <font color=”lilac”>2</font>
<font color=”indigo”>11</font> 6.5 3. 5.8 2.2 <font color=”green”>5.09607692</font> <font color=”lilac”>2</font>

step3: 咱们设置 k =5, 抉择间隔最近的 k 个样本进行投票

间隔升序编号 feat_1 feat_2 feat_3 feat_4 间隔 label
<font color=”red”>1</font> 5.1 3.5 1.4 0.2 <font color=”red”>0.14142136</font> 0
<font color=”red”>3</font> 4.9 3. 1.4 0.2 <font color=”red”>0.60827625</font> 0
<font color=”red”>2</font> 4.7 3.2 1.3 0.2 <font color=”red”>0.50990195</font> 0
<font color=”red”>4</font> 4.6 3.1 1.5 0.2 <font color=”red”>0.64807407</font> 0
<font color=”indigo”>6</font> 6.4 3.2 4.5 1.5 <font color=”green”>3.66333182</font> <font color=”coral”>1
<font color=”indigo”>8</font> 6.9 3.1 4.9 1.5 <font color=”green”>4.21900462</font> <font color=”coral”>1
<font color=”red”>5</font> 5.5 2.3 4. 1.3 <font color=”red”>3.14801525</font> <font color=”coral”>1 </font>
<font color=”indigo”>7</font> 6.5 2.8 4.6 1.5 <font color=”green”>3.84967531</font> <font color=”coral”>1</font>
<font color=”indigo”>9</font> 5.8 2.7 5.1 1.9 <font color=”green”>4.24617475</font> <font color=”lilac”>2</font>
<font color=”indigo”>12</font> 7.1 3. 5.9 2.1 <font color=”green”>5.35070089</font> <font color=”lilac”>2</font>
<font color=”indigo”>10</font> 6.3 2.9 5.6 1.8 <font color=”green”>4.73075047</font> <font color=”lilac”>2</font>
<font color=”indigo”>11</font> 6.5 3. 5.8 2.2 <font color=”green”>5.09607692</font> <font color=”lilac”>2</font>

step4: k 近邻的 label 进行投票

nn_labels = [0, 0, 0, 0, 1] –> 失去最初的后果 0。

2.4.3 模仿数据集 –kNN 回归

Step1: 库函数导入

#Demo 来自 sklearn 官网
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor
np.random.seed(0)
# 随机生成 40 个 (0, 1) 之前的数,乘以 5,再进行升序
X = np.sort(5 * np.random.rand(40, 1), axis=0)
# 创立 [0, 5] 之间的 500 个数的等差数列, 作为测试数据
T = np.linspace(0, 5, 500)[:, np.newaxis]
# 应用 sin 函数失去 y 值,并拉伸到一维
y = np.sin(X).ravel()
# Add noise to targets[y 值减少噪声]
y[::5] += 1 * (0.5 - np.random.rand(8))

Step3: 模型训练 & 预测可视化

# #############################################################################
# Fit regression model
# 设置多个 k 近邻进行比拟
n_neighbors = [1, 3, 5, 8, 10, 40]
# 设置图片大小
plt.figure(figsize=(10,20))
for i, k in enumerate(n_neighbors):
    # 默认应用加权均匀进行计算 predictor
    clf = KNeighborsRegressor(n_neighbors=k, p=2, metric="minkowski")
    # 训练
    clf.fit(X, y)
    # 预测
    y_ = clf.predict(T)
    plt.subplot(6, 1, i + 1)
    plt.scatter(X, y, color='red', label='data')
    plt.plot(T, y_, color='navy', label='prediction')
    plt.axis('tight')
    plt.legend()
    plt.title("KNeighborsRegressor (k = %i)" % (k))

plt.tight_layout()
plt.show()

Step4: 模型剖析

当 k = 1 时,预测的后果只和最近的一个训练样本相干,从预测曲线中能够看出当 k 很小时候很容易产生过拟合。

当 k =40 时,预测的后果和最近的 40 个样本相干,因为咱们只有 40 个样本,此时是所有样本的平均值,此时所有预测值都是均值,很容易产生欠拟合。

个别状况下,应用 knn 的时候,依据数据规模咱们会从 [3, 20] 之间进行尝试,抉择最好的 k,例如上图中的 [3, 10] 绝对 1 和 40 都是还不错的抉择。

2.4.4 马绞痛数据 –kNN 数据预处理 +kNN 分类 pipeline

# 下载须要用到的数据集
!wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/horse-colic.csv

# 下载数据集介绍
!wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/horse-colic.names

Step1: 库函数导入

import numpy as np
import pandas as pd
# kNN 分类器
from sklearn.neighbors import KNeighborsClassifier
# kNN 数据空值填充
from sklearn.impute import KNNImputer
# 计算带有空值的欧式间隔
from sklearn.metrics.pairwise import nan_euclidean_distances
# 穿插验证
from sklearn.model_selection import cross_val_score
# KFlod 的函数
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

Step2: 数据导入 & 剖析

2,1,530101,38.50,66,28,3,3,?,2,5,4,4,?,?,?,3,5,45.00,8.40,?,?,2,2,11300,00000,00000,2
1,1,534817,39.2,88,20,?,?,4,1,3,4,2,?,?,?,4,2,50,85,2,2,3,2,02208,00000,00000,2
2,1,530334,38.30,40,24,1,1,3,1,3,3,1,?,?,?,1,1,33.00,6.70,?,?,1,2,00000,00000,00000,1
1,9,5290409,39.10,164,84,4,1,6,2,2,4,4,1,2,5.00,3,?,48.00,7.20,3,5.30,2,1,02208,00000,00000,1
2,1,530255,37.30,104,35,?,?,6,2,?,?,?,?,?,?,?,?,74.00,7.40,?,?,2,2,04300,00000,00000,2
......

数据集介绍:horse-colic.names

数据中的 ’?’ 示意空值,如果咱们应用 KNN 分类器,’?’ 不能数值,不能进行计算,因而咱们须要进行数据预处理对空值进行填充。

这里咱们应用 KNNImputer 进行空值填充,KNNImputer 填充的原来很简略,计算每个样本最近的 k 个样本,进行空值填充。

咱们先来看下 KNNImputer 的运行原理:

Step3: KNNImputer 空值填充 – 应用和原理介绍

X = [[1, 2, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 7]]
imputer = KNNImputer(n_neighbors=2, metric='nan_euclidean')
imputer.fit_transform(X)

array([[1. , 2. , 4.],

   [3. , 4. , 3.],
   [5.5, 6. , 5.],
   [8. , 8. , 7.]])

带有空值的欧式间隔计算公式

nan_euclidean_distances([[np.nan, 6, 5], [3, 4, 3]], [[3, 4, 3], [1, 2, np.nan], [8, 8, 7]])

Step4: KNNImputer 空值填充 – 欧式间隔的计算

样本[1, 2, np.nan] 最近的 2 个样本是: [3, 4, 3] [np.nan, 6, 5], 计算间隔的时候应用欧式间隔,只关注非空样本。
[1, 2, np.nan] 填充之后失去 [1, 2, (3 + 5) / 2] = [1, 2, 4]

失常的欧式间隔

$$
x = [3, 4, 3], y = [8, 8, 7] \\
\sqrt{(3-8)^2 + (4-8)^2 + (3-7)^2} = \sqrt{33} = 7.55
$$

带有空值的欧式聚类

$$
x = [1, 2, np.nan], y = [np.nan, 6, 5] \\
\sqrt{\frac{3}{1}(2-6)^2} = \sqrt{48} = 6.928
$$

只计算所有非空的值,对所有空加权到非空值的计算上,上例中,咱们看到一个有 3 维,只有第二维全副非空,
将第一维和第三维的计算加到第二维上,所有须要乘以 3。

表格中距离度量应用的是带有空值欧式间隔计算类似度,应用简略的加权均匀进行填充。

带有空值的样本 最相近的样本 1 最相近的样本 2 填充之后的值
[1, 2, <font color=’red’>np.nan</font>] [3, 4, 3]; 3.46 [np.nan, 6, 5]; 6.93 [1, 2, <font color=’greed’>4</font>]
[<font color=’red’>np.nan</font>, 6, 5] [3, 4, 3]; 3.46 [8, 8, 7]; 3.46 [<font color=’greed’>5.5</font>, 6, 5]
# load dataset, 将? 变成空值
input_file = './horse-colic.csv'
df_data = pd.read_csv(input_file, header=None, na_values='?')

# 失去训练数据和 label, 第 23 列示意是否产生病变, 1: 示意 Yes; 2: 示意 No. 
data = df_data.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]

# 查看所有特色的缺失值个数和缺失率
for i in range(df_data.shape[1]):
    n_miss = df_data[[i]].isnull().sum()
    perc = n_miss / df_data.shape[0] * 100
    if n_miss.values[0] > 0:
        print('>Feat: %d, Missing: %d, Missing ratio: (%.2f%%)' % (i, n_miss, perc))

# 查看总的空值个数
print('KNNImputer before Missing: %d' % sum(np.isnan(X).flatten()))
# 定义 knnimputer
imputer = KNNImputer()
# 填充数据集中的空值
imputer.fit(X)
# 转换数据集
Xtrans = imputer.transform(X)
# 打印转化后的数据集的空值
print('KNNImputer after Missing: %d' % sum(np.isnan(Xtrans).flatten()))


Feat: 0, Missing: 1, Missing ratio: (0.33%)
Feat: 3, Missing: 60, Missing ratio: (20.00%)
Feat: 4, Missing: 24, Missing ratio: (8.00%)
Feat: 5, Missing: 58, Missing ratio: (19.33%)
Feat: 6, Missing: 56, Missing ratio: (18.67%)
Feat: 7, Missing: 69, Missing ratio: (23.00%)
Feat: 8, Missing: 47, Missing ratio: (15.67%)
Feat: 9, Missing: 32, Missing ratio: (10.67%)
Feat: 10, Missing: 55, Missing ratio: (18.33%)
Feat: 11, Missing: 44, Missing ratio: (14.67%)
Feat: 12, Missing: 56, Missing ratio: (18.67%)
Feat: 13, Missing: 104, Missing ratio: (34.67%)
Feat: 14, Missing: 106, Missing ratio: (35.33%)
Feat: 15, Missing: 247, Missing ratio: (82.33%)
Feat: 16, Missing: 102, Missing ratio: (34.00%)
Feat: 17, Missing: 118, Missing ratio: (39.33%)
Feat: 18, Missing: 29, Missing ratio: (9.67%)
Feat: 19, Missing: 33, Missing ratio: (11.00%)
Feat: 20, Missing: 165, Missing ratio: (55.00%)
Feat: 21, Missing: 198, Missing ratio: (66.00%)
Feat: 22, Missing: 1, Missing ratio: (0.33%)
KNNImputer before Missing: 1605
KNNImputer after Missing: 0

Step5: 基于 pipeline 模型训练 & 可视化

什么是 Pipeline, 我这里间接翻译成数据管道。任何有序的操作有能够看做 pipeline,例如工厂流水线,对于机器学习模型来说,这就是数据流水线。
是指数据通过管道中的每一个节点,后果除了之后,持续流向上游。对于咱们这个例子,数据是有空值,咱们会有一个 KNNImputer 节点用来填充空值,
之后持续流向下一个 kNN 分类节点,最初输入模型。

<img src=’https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/knn-pipeline.png’/>

results = list()
strategies = [str(i) for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 18, 20, 21]]
for s in strategies:
    # create the modeling pipeline
    pipe = Pipeline(steps=[('imputer', KNNImputer(n_neighbors=int(s))), ('model', KNeighborsClassifier())])
    # 数据屡次随机划分取均匀得分
    scores = []
    for k in range(20):
        # 失去训练汇合和验证汇合, 8: 2
        X_train, X_test, y_train, y_test = train_test_split(Xtrans, y, test_size=0.2)
        pipe.fit(X_train, y_train)
        # 验证 model
        score = pipe.score(X_test, y_test)
        scores.append(score)
    # 保留 results
    results.append(np.array(scores))
    print('>k: %s, Acc Mean: %.3f, Std: %.3f' % (s, np.mean(scores), np.std(scores)))
# print(results)
# plot model performance for comparison
plt.boxplot(results, labels=strategies, showmeans=True)
plt.show()
>k: 1, Acc Mean: 0.800, Std: 0.031
>k: 2, Acc Mean: 0.821, Std: 0.041
>k: 3, Acc Mean: 0.833, Std: 0.053
>k: 4, Acc Mean: 0.824, Std: 0.037
>k: 5, Acc Mean: 0.802, Std: 0.038
>k: 6, Acc Mean: 0.811, Std: 0.030
>k: 7, Acc Mean: 0.797, Std: 0.056
>k: 8, Acc Mean: 0.819, Std: 0.044
>k: 9, Acc Mean: 0.820, Std: 0.032
>k: 10, Acc Mean: 0.815, Std: 0.046
>k: 15, Acc Mean: 0.818, Std: 0.037
>k: 16, Acc Mean: 0.811, Std: 0.048
>k: 18, Acc Mean: 0.809, Std: 0.043
>k: 20, Acc Mean: 0.810, Std: 0.038
>k: 21, Acc Mean: 0.828, Std: 0.038

Step 6: 后果剖析

咱们的试验是每个 k 值下,随机切分 20 次数据, 从上述的图片中, 依据 k 值的减少,咱们的测试准确率会有先回升再降落再回升的过程。
[3, 5]之间是一个很好的取值,上文咱们提到,k 很小的时候会产生过拟合,k 很大时候会产生欠拟合,当遇到第一降落节点,此时咱们能够
简略认为不在产生过拟合,取以后的 k 值即可。

2.5 KNN 原理介绍

k 近邻办法是一种惰性学习算法,能够用于回归和分类,它的次要思维是投票机制,对于一个测试实例 x, 咱们在有标签的训练数据集上找到和最相近的 k 个数据,用他们的 label 进行投票,分类问题则进行表决投票,回归问题应用加权均匀或者间接均匀的办法。knn 算法中咱们最须要关注两个问题:k 值的抉择和间隔的计算。
kNN 中的 k 是一个超参数,须要咱们进行指定,个别状况下这个 k 和数据有很大关系,都是穿插验证进行抉择,然而倡议应用穿插验证的时候,k∈[2,20],应用穿插验证失去一个很好的 k 值。

k 值还能够示意咱们的模型复杂度,当 k 值越小意味着模型复杂度表白,更容易过拟合,(用极少树的样例来相对这个预测的后果,很容易产生偏见,这就是过拟合)。咱们有这样一句话,k 值越多学习的预计误差越小,然而学习的近似误差就会增大。


间隔 / 类似度的计算:

样本之间的间隔的计算,咱们个别应用对于个别应用 Lp 间隔进行计算。当 p = 1 时候,称为曼哈顿间隔(Manhattan distance),当 p = 2 时候,称为欧氏间隔(Euclidean distance),当 p =∞时候,称为极大间隔(infty distance), 示意各个坐标的间隔最大值, 另外也蕴含夹角余弦等办法。

个别采纳欧式间隔较多,然而文本分类则偏向于应用余弦来计算类似度。

对于两个向量 $(x_i,x_j)$, 个别应用 $L_p$ 间隔进行计算。假如特色空间 $X$ 是 n 维实数向量空间 $R^n$ , 其中,$x_i,x_j \in X$,
$x_{i}=\left(x_{i}^{(1)}, x_{i}^{(2)}, \ldots, x_{i}^{(n)}\right)$,$x_{j}=\left(x_{j}^{(1)}, x_{j}^{(2)}, \ldots, x_{j}^{(n)}\right)$
$x_i,x_j$ 的 $L_p$ 间隔定义为:

$$
L_{p}\left(x_{i}, x_{j}\right)=\left(\sum_{l=1}^{n}\left|x_{i}^{(l)}-x_{j}^{(l)}\right|^{p}\right)^{\frac{1}{p}}
$$

这里的 $p\geq1$. 当 $p=2$ 时候,称为欧氏间隔(Euclidean distance):

$$
L_{2}\left(x_{i}, x_{j}\right)=\left(\sum_{l=1}^{n}\left|x_{i}^{(l)}-x_{j}^{(l)}\right|^{2}\right)^{\frac{1}{2}}
$$

当 $p=1$ 时候,称为曼哈顿间隔(Manhattan distance):

$$
L_{1}\left(x_{i}, x_{j}\right)=\sum_{l=1}^{n}\left|x_{i}^{(l)}-x_{j}^{(l)}\right|
$$

当 $p=\infty$ 时候,称为极大间隔(infty distance), 示意各个坐标的间隔最大值:

$$
L_{p}\left(x_{i}, x_{j}\right)=\max _{l} n\left|x_{i}^{(l)}-x_{j}^{(l)}\right|
$$

正文完
 0