sklearn实现多项式回归

时间秒杀一切 提交于 2020-01-22 05:50:58

多项式回归


       一个数据集,用散点图画出来如下图,可以看到此时用一条直线(或者超平面)是不能拟合的,所以需要用一个多项式表示的曲线(或者超曲面)才能得到更好的拟合结果。

在这里插入图片描述
在这里插入图片描述
       下面可以看一个例子:有不同职位,分成10个等级,不同等级的工资不同,可以根据等级(横坐标)和工资(纵坐标)来画一个散点图,具体见下图:

在这里插入图片描述
       可以看到该散点图呈曲线分布,所以可以用多项式回归来拟合。上方的数据可以从该链接获取(https://pan.baidu.com/s/1fYR3VPFaldz0Bnzfm5wsvg),获取数据文件后,将文件导入到你用python编程的同一个目录下,接下来就是编程实现拟合了,代码如下:

 import numpy as np
 import matplotlib.pyplot as plt
 from sklearn.linear_model import LinearRegression
 # 下面导入的包是用来实现多项式的
 from sklearn.preprocessing import PolynomialFeatures

 # 载入数据
 data = np.genfromtxt("job.csv",delimiter= ",")
 x_data = data[1:,1]
 y_data = data[1:,2]
 # 下面是将取得的数据画一个散点图
 # plt.scatter(x_data,y_data)
 # plt.show()

 x_data = data[1:,1,np.newaxis]  # 或者x_data = x_data[:,np.newaxis]
 y_data = data[1:,2,np.newaxis]  # 或者y_data = y_data[:,np.newaxis]


 # 创建并拟合模型
 # model = LinearRegression()
 # model.fit(x_data,y_data)
 # 画图
 # plt.plot(x_data,y_data,'b.') #画一个蓝色点的图
 # plt.plot(x_data,model.predict(x_data),'r') # 此处用的线性回归模型进行预测,将预测值作为y值,画一个红色的直线拟合
 # plt.show()


 # 定义多项式回归,degree的值可以调节多项式的特征
 poly_reg = PolynomialFeatures(degree=5)
 # 特征处理
 x_poly = poly_reg.fit_transform(x_data)
 # 定义回归模型
 lin_reg = LinearRegression()
 # 训练模型
 lin_reg.fit(x_poly,y_data)

 # 画图
 plt.plot(x_data,y_data,'b.')
 plt.plot(x_data,lin_reg.predict(poly_reg.fit_transform(x_data)),c = 'r')
 plt.title('Truth or Bluff(Polynomial Regression)')
 plt.xlabel('Position level')
 plt.ylabel('Salary')
 plt.show()

       最后结果如下:

在这里插入图片描述
       代码被注释的11-13行,是画一个散点图;被注释掉的19-25行表示用线性回归来实现拟合(即用一条直线来拟合数据集),此运行结果与多项式回归(当degree=1时)的运行结果是一样的。代码中的x_poly,当degree=1时,x_poly表示在原始数据前面加一列(原始数据的0次方),当degree=2时,在原始数据前面加一列和后面加一列(原始数据的平方);其他类推,后面加3次方、4次方、5次方……degree的数值越大,拟合的结果也就越好。
原始数据:
[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 5.]
[ 6.]
[ 7.]
[ 8.]
[ 9.]
[10.]]
degree = 1:
[[ 1. 1.]
[ 1. 2.]
[ 1. 3.]
[ 1. 4.]
[ 1. 5.]
[ 1. 6.]
[ 1. 7.]
[ 1. 8.]
[ 1. 9.]
[ 1. 10.]]
degree = 2:
[[ 1. 1. 1.]
[ 1. 2. 4.]
[ 1. 3. 9.]
[ 1. 4. 16.]
[ 1. 5. 25.]
[ 1. 6. 36.]
[ 1. 7. 49.]
[ 1. 8. 64.]
[ 1. 9. 81.]
[ 1. 10. 100.]]
       可以看到上方的代码画出的多项式拟合的曲线还是不够平滑,这是因为取的点太少的缘故,我们可以在区间内把区间划分为更多小区间,再用predict函数去画曲线,只需要把上方代码的画图部分修改一下即可,具体代码如下:

 # 画图
 plt.plot(x_data,y_data,'b.') #用蓝色的点把数据集表示出来
 x_test = np.linspace(1,10,100) #linspace(a,b,c)表示划分区间[a,b],等分c份
 x_test = x_test[:,np.newaxis] #设置x_test数组格式为一列
 plt.plot(x_test,lin_reg.predict(poly_reg.fit_transform(x_test)),c = 'r')
 plt.title('Truth or Bluff(Polynomial Regression)')
 plt.xlabel('Position level')
 plt.ylabel('Salary')
 plt.show()在这里插入图片描述

       最后画出来的结果如下,可以看见曲线更加平滑了。
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!