KNN算法原理

计算测试样本与每个训练样本的距离,取前k个距离最小的训练样本,最后选择这k个样本中出现最多的分类,作为测试样本的分类。
如图所示,绿色的为测试样本,当k取3时,该样本就属于红色类;当k取5时,就属于蓝色类了。所以k值的选择很大程度影响着该算法的结果,通常k的取值不大于20。
KNN算法原理

实战-糖尿病预测

数据的下载与导入

本数据可以再kaggle中进行下载, 也可以在百度网盘链接中进行下载
(链接:https://pan.baidu.com/s/1gqaGuQ9kWZFfc-SXbYFDkA 密码:lxfx)
该数据为csv格式文件,我们通过pandas读入:

  1. import numpy as np
  2. import pandas as pd
  3. data = pd.read_csv('./diabetes.csv')
  4. data.head()

image.png
我们简单看下各字段的意思:

  • Pregnancies:怀孕的次数
  • Glucose:血浆葡萄糖浓度
  • BloodPressure:舒张压
  • SkinThickness:肱三头肌皮肤皱皱厚度
  • Insulin: 胰岛素
  • BMI:身体质量指数
  • Dia….:糖尿病血统指数
  • Age:年龄
  • Outcone:是否糖尿病,1为是

    划分数据集

    在模型训练前, 需要将数据集切分为训练集和测试集(7,3开或者其它开), 这里选择28开,使用sklearn中的model_selection模块中的train_test_split方法.
    1. from sklearn.model_selection import train_test_split
    2. X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=22)
    3. print(X_train.shape)
    4. print(X_test.shape)
    5. print(Y_train.shape)
    6. print(Y_test.shape)

    (614, 8) (154, 8) (614,) (154,)

使用不同的k邻近算法进行分类

:::success sklearn.neighbors.KNeighborsClassifier(n_neighbors, weights)
n_neighbors: 整数, 也就是k值
weights: 默认为’uniform’, 这个参数可以针对不同的邻居指定不同的权重, 也就是说, 越近的可以权重越高, 默认是一样的权重, ‘distance’可以设置不同的权重 ::: :::tips 在sklearn.neighbors还有一个变种KNN算法,为RadiusNeighborsClassifier算法,可以使用一定半径的点来取代距离最近的k个点。
接下来,我们通过设置weight和RadiusNeighborsClassifier,对算法进行比较。 :::

  1. from sklearn.neighbors import KNeighborsClassifier, RadiusNeighborsClassifier
  2. model1 = KNeighborsClassifier(n_neighbors=2)
  3. model1.fit(X_train, Y_train.squeeze())
  4. score1 = model1.score(X_test, Y_test)
  5. print(score1)
  6. model2 = KNeighborsClassifier(n_neighbors=2, weights='distance')
  7. model2.fit(X_train, Y_train.squeeze())
  8. score2 = model2.score(X_test, Y_test)
  9. print(score2)
  10. model3 = RadiusNeighborsClassifier(radius=500.0)
  11. model3.fit(X_train, Y_train.squeeze())
  12. score3 = model3.score(X_test, Y_test)
  13. print(score3)

0.7142857142857143
0.7012987012987013 0.6493506493506493

:::info 可以看到使用三种不同的k邻近算法得到的结果
其中默认情况下的结果看起来是最好的, 但是不是最好, 还需要使用k折交叉验证 进行一下验证 :::

交叉验证

:::tips 通过上述结果可以看出:默认情况的KNN算法结果最好。这个判断准确么?答案是不准确,因为我们只是随机分配了一次训练和测试样本,可能下次随机选择训练和测试样本,结果就不一样了。这里的方法为:交叉验证。我们把数据集划分为10折,每次用9折训练,1折测试,就会有10次结果,求十次的平均即可。当然,可以设置cv的值,选择不同的折数。 :::

  1. from sklearn.model_selection import cross_val_score
  2. result1 = cross_val_score(model1, X, Y, cv=10)
  3. result2 = cross_val_score(model2, X, Y, cv=10)
  4. result3 = cross_val_score(model3, X, Y, cv=10)
  5. print(result1.mean(), result2.mean(), result3.mean())
  6. # result
  7. # 0.712235133288 0.67966507177 0.64976076555

:::info 可以看出,还是默认情况的KNN算法结果最好。 :::

参考链接

  1. https://www.jianshu.com/p/df868c254e4c