常见机器学习方法的优缺点及适用场景:K近邻(KNN)

K近邻(KNN)

  1. KNN建立过程:

    a. 给定测试样本,计算它与训练集中的每个样本的距离;

    b. 找到距离最近的K个训练样本,作为测试样本的K近邻;

    c. 根据K近邻归属的类别来确定该测试样本的类别(少数服从多数)。

  2. 类别的判定

    a. 投票决定,少数服从多数,取样本数最对的类别最为测试样本的类别

    b. 加权投票法:依据计算得出距离的函数作为权重,对不同近邻的投票进行加权;一般函数取距离平方的倒数

  3. 应用:即能做分类又能做回归, 还能用来做数据预处理的缺失值填充

  4. 原理:

  分类问题进行表决投票;

  回归问题使用加权平均或者直接平均的方法。

  knn算法中我们最需要关注两个问题:k值的选择和距离的计算。 kNN中的k是一个超参数,需要我们进行指定,一般情况下这个k和数据有很大关系,都是交叉验证进行选择,但是建议使用交叉验证的时候,k∈[2,20],使用交叉验证得到一个很好的k值。

  k值还可以表示我们的模型复杂度,当k值越小意味着模型复杂度变大,更容易过拟合,(用极少数的样例来绝对这个预测的结果,很容易产生偏见,这就是过拟合)。我们有这样一句话,k值越大学习的估计误差越小,但是学习的近似误差就会增大

  近似误差:可以理解为对现有训练集的训练误差,太小更容易过拟合。
  估计误差:可以理解为对测试集的测试误差。

  5. 实战(sklearn)

 

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

 

# ipython下载
# 下载需要用到的数据集
!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
# 回归:from sklearn.neighbors import KNeiborsRegressor # 用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:数据导入&分析" # 数据中有”?“值,没办法分析,需要先使用KNNImputer进行空值填充 "Step4: KNNImputer空值填充--欧式距离的计算" # 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 ]                   # numpy可以用列表当切片 # 查看所有特征的缺失值个数和缺失率 for i in range (df_data.shape[ 1 ]): n_miss = df_data[[i]].isnull(). sum ()        # df_data[[i]]:表示pd中完整一列 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()))

输出结果:

 

"step5: 基于pipeline模型训练&可视化"
"K折交叉验证的选择"
# 什么是Pipeline, 我这里直接翻译成数据管道。任何有序的操作有可以看做pipeline

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(X, y, test_size = 0.2 )
        pipe.fit(X_train, y_train)
        # 验证model
        score  = pipe.score(X_test, y_test)
        scores.append(score)
    # 保持result
    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()

输出结果:

 

posted @ 2022-04-18 10:57  Gentle_Jan  阅读(866)  评论(0)    收藏  举报