常见机器学习方法的优缺点及适用场景: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
1 2 3 4 5 | # 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | "step1:库导入" import numpy as np import pandas as pd # KNN分类器 from sklearn.neighbors import KNeighborsClassifier<br> # 回归: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())) |
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | "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() |
输出结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南