飞道的博客

【练习】线性回归与KNN回归对比

607人阅读  评论(0)

前言

本次练习,使用sklearn自带的波士顿房价数据集,主要为了对比无优化KNN回归模型与线性回归模型的效果对比;标准化特征集后的KNN效果提升,以及网格搜索优化后KNN模型及特征选择后线性回归模型的效果。

一、导入模块 & 数据

先导入一波需要用到的模块

# 导入模块
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

再导入数据集并切分训练集、测试集

# 导入数据集
x, y = load_boston(return_X_y=True)

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

二、KNN回归与线性回归基模型对比

  • 基模型效果对比

好了,准备工作完成,现在,创建KNN与LR的基模型,并对比效果

# LR基模型
lr = LinearRegression()
lr.fit(x_train, y_train)
y_hat_lr = lr.predict(x_test)

# KNN基模型
knn = KNeighborsRegressor(n_neighbors=4, weights='uniform')
knn.fit(x_train, y_train)
y_hat_knn = knn.predict(x_test)

# 两模型拟合系数评分
print("线性回归模型:",lr.score(x_test, y_test))
print("KNN回归模型:",knn.score(x_test, y_test))

  • 可视化效果对比
    LR模型效果
# LR模型、KNN模型预测值与真实值对比

plt.figure(figsize=(15,10))
plt.plot(y_test,'r-',marker='o',label='真实值',alpha=0.5)
plt.plot(y_hat_lr,'g--',marker='o',label='LR模型')
plt.title('LR模型效果')
plt.legend()
plt.grid()

KNN模型效果对比

# LR模型、KNN模型预测值与真实值对比

plt.figure(figsize=(15,10))
plt.plot(y_test,'r-',marker='o',label='真实值',alpha=0.5)
plt.plot(y_hat_knn,'b--',marker='o',label='KNN模型')
plt.title('KNN模型效果')
plt.legend()
plt.grid()

我们可以发现,未经优化的LR与KNN基模型,在效果上都不是很突出

三、标准化特征集及效果对比

考虑到数据集的特征数据未经过标准化处理,可能会对模型的效果产生影响(实际上对于线性回归模型几乎没有影响),所以,我们对数据集进行标准化处理后,再进行对比

scaler = [StandardScaler(), MinMaxScaler()]
desc = ['均值标准差标准化','最小最大值标准化']
for s,d in zip(scaler, desc):
    x_train_scaler = s.fit_transform(x_train)
    x_test_scaler = s.transform(x_test)
    knn = KNeighborsRegressor(n_neighbors=3, weights='uniform')
    knn.fit(x_train_scaler,y_train)
    print(d, knn.score(x_test_scaler, y_test))

# 对特征集进行标准化处理

standar = StandardScaler()

x_train_scaler = standar.fit_transform(X=x_train)
x_test_scaler = standar.transform(x_test)

# 使用标准化处理后的数据训练LR模型
lr.fit(x_train_scaler,y_train)
y_hat_lr_s = lr.predict(x_test_scaler)
# 使用标准化处理后的数据训练KNN模型
knn.fit(x_train_scaler, y_train)
y_hat_knn_s = knn.predict(x_test_scaler)

# 模型评分
print("LR模型:",lr.score(x_test_scaler, y_test))
print("KNN模型:",knn.score(x_test_scaler, y_test))

从结果可以看出,使用经过标准化处理后的数据集,使得KNN模型的效果有了较明显的提升,但是对于LR模型来说,性能缺没有提升。

  • 这是因为对于线性回归模型来说,它的核心算法是求解方程中的每一个特征的权重w的值,而w在其对应特征值量纲较大时,会缩小自身以限制该特征,从而使得该特征及其权重的乘积不变;
  • 而对于KNN来说,它实际上是求解K个邻居的目标值y的均值,所以当其多个特征中某个特征的量纲较大时,就会使得该特征的影响最大,从而导致其他特征的被忽略。
  • 综上所述,特征集存在较大量纲差异时,对KNN算法的影响较大,对线性回归几乎无影响,但是由于数据标准化不会产生负面影响,所以,建议在建模前,对数据进行标准化处理

四、KNN优化-网格搜索

经过数据标准化处理后,KNN模型的效果有了较明显的提升,那么,在这个基础上,我们再进行一下网格搜索优化,又会对KNN回归模型产生怎样的影响呢?

# KNN回归模型网格搜索优化

grid = {"n_neighbors":range(1,41,1),
       "weights":['uniform','distance'],
       "p":[1,2]}
gs = GridSearchCV(estimator=knn, param_grid=grid, scoring='r2', n_jobs=-1, cv=9,verbose=10)
gs.fit(x_train_scaler,y_train)
# 最优评分
print(gs.best_score_)
# 最佳参数组合
print(gs.best_params_)
# 获取最佳参数组合训练的KNN回归模型
knn_gs = gs.best_estimator_

来对比一下网格搜索优化前后的KNN回归模型

print("KNN基模型:",knn.score(x_test_scaler, y_test))
print("KNN优化后模型:",knn_gs.score(x_test_scaler, y_test))

五、线性回归优化-RFECV

既然KNN模型有网格搜索,那么,对于线性回归模型,有什么方式进行优化呢?答案就是特征选择-RFECV

# 筛选后剩余的特征数量
print(rfecv.n_features_)
# 每个特征的重要性
print(rfecv.ranking_)
# 对应数量特征交叉验证的评分
print(rfecv.grid_scores_)
# 获取使用缩减特征训练后的模型
lr_rf = rfecv.estimator_


我们可以发现,经过特征选择后,最终剩余11个特征,比最初时少了两个特征,我们可视化一下对应数量下的拟合系数评分

plt.plot(rfecv.grid_scores_,'r--')
plt.xlabel("特征数量")
plt.ylabel("交叉验证R2值")
plt.grid()

看一下最终的效果:

# 最终效果对比
x_train_eli = rfecv.transform(x_train_scaler)
x_test_eli = rfecv.transform(x_test_scaler)

print("LR优化后模型:",lr_rf.score(x_test_eli, y_test))
print("KNN优化后模型:",knn_gs.score(x_test_scaler, y_test))

进过最终优化后,模型的效果还是不尽人意,可能是还需要另外的方法流程对数据集及模型进行优化,相关内容后期更新。


转载:https://blog.csdn.net/weixin_39039932/article/details/105712409
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场