常见机器学习方法的优缺点及适用场景: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()
输出结果:


浙公网安备 33010602011771号