欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

深入理解机器学习(二):邻近邻居(KNN)算法详解

最编程 2024-02-10 20:02:02
...

一、方法介绍

  • KNN法:又称K近邻法(1967年),核心思想是如果一个样本的前k个最相邻的样本大多属于某个类别,则该样本也属于这个类别,属于有监督的学习方法,可做分类、回归。
  • 距离的度量:欧氏距离、曼哈顿距离、马氏距离、夹角余弦
  • 算法步骤:计算有标签数据集的点与当前点的距离并按距离升序排列,选取前k个距离最小的点及其所属标签的频率,频率最高的标签即为分类结果。
  • 注意:当数据集的特征较多时,需要考虑不同特征的重要性(权重),同等重要时应该对特征数据进行归一化(或标准化,考虑量纲较大的数据特征会对结果产生很大影响)。
  • 超参数优化:k通过交叉验证法优化。k过小则较近的实例会影响预测结果,预测值会对临近点过于敏感,可能因噪音预测错误,也意味着整体模型更复杂容易发生过拟合;k过大则较远范围的实例也会影响预测结果,使预测发生错误。
  • 方法总结
优缺点 归纳
优点 1、思想简单,可以左分类和回归;2、惰性学习,无需训练(蛮力法),KD树的话需要建树;3、对异常点不敏感。
缺点 1、计算量大、速度慢;2、样本不平衡的适合对稀有类别的预测准确率低;3、KD树、球树之类的模型需要大量内存;4、相比决策树模型,KNN模型可解释性不强。

二、Python代码:案例——波士顿房价预测

  • 第一步:导包,导入数据
# 回归:线性回归、岭回归和拉索回归
from sklearn.linear_model import LinearRegression,Ridge,Lasso
# 数据标准化处理
from sklearn.preprocessing import StandardScaler
# 数据集
from sklearn.datasets import load_boston
# 数据集拆分
from sklearn.model_selection import train_test_split
# K近邻法
from sklearn.neighbors import KNeighborsRegressor
import matplotlib.pyplot as plt
# 加载数据集
ld=load_boston()
# 数据集拆分
x_train,x_test,y_train,y_test=train_test_split(ld.data,ld.target,test_size=0.25,random_state=4 )
# 数据集特征和标签
ld.data.shape
ld.target.shape
  • 第二步:标准化处理和建模
# 标准化处理:在数据集拆分之后,数据服从正态分布——标准化,否则归一化,一般以效果好为准
std_x = StandardScaler()
# 用训练集的标准差进行标准化(训练集的指标更准确)
x_train = std_x.fit_transform(x_train) 
x_test = std_x.transform(x_test)
# knn回归,建模并fit拟合,n_neighbors默认5
knn=KNeighborsRegressor().fit(x_train,y_train)
# R2系数
knn.score(x_test,y_test) 

knn回归模型的评分为0.753

# LinearRegression线性回归
lr=LinearRegression().fit(x_train,y_train)
lr.score(x_test,y_test)

线性回归模型的评分为0.731

  • 第三步:对knn模型进行参数优化
# 10折交叉验证,并画出k和score
from sklearn.model_selection import cross_val_score as CVS
score=[]
for i in range(2,21):
    knn = KNeighborsRegressor(n_neighbors=i)
    cvresult = CVS(knn,x_train, y_train,cv=10)
    score.append(cvresult.mean())
plt.plot(range(2,21),score,color='b',marker='*')
plt.xticks(range(2,21))
plt.xlabel('k')
plt.ylabel('score')
score.index(max(score))+2  #最大的score所对应的k值

输出结果显示k=3为最优超参数,此时的score=0.765。

  • 第四步:网格搜索交叉验证调参和建模(预测)
类型 评价指标 方法
分类 accuracy metrics.accuracy_score
分类 average_precision metrics.average_precision_score
分类 f1 metrics.f1_score
分类 f1_micro metrics.f1_score
分类 f1_macro metrics.f1_score
分类 f1_weighted metrics.metrics.f1_score
分类 f1_samples metrics.f1_score
分类 neg_log_loss metrics.log_loss
分类 precision metrics.precision_score
分类 recall metrics.recall_score
分类 roc_auc metrics.roc_auc_score
回归 neg_mean_absolute_error metrics.mean_absolute_error
回归 neg_mean_squared_error metrics.mean_squared_error
回归 neg_median_absolute_error metrics.median_absolute_error
回归 r2 metrics.r2_score
from sklearn.model_selection import GridSearchCV
# 搜索的参数:权重——同等重要、越近越重要;k值——2到20
params={'weights':['uniform','distance'],'n_neighbors':range(1,20)}
knn = KNeighborsRegressor()
# 10折交叉验证,可设置verbose=2输出信息
grid_search=GridSearchCV(knn,param_grid=params,cv=10)
grid_search.fit(x_train,y_train)
grid_search.best_params_

结果显示最优参数组合为:k=3和权重weights="distance"

grid_search.score(x_test,y_test)

在最优参数下建模的评分score=0.821。