手记

【火炉炼AI】机器学习005-多项式回归器的创建和测试

【火炉炼AI】机器学习005-多项式回归器的创建和测试

(本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

前面讲到了简单线性回归器和岭回归器,这两类回归器都是将数据集拟合成直线,但现实生活中,有很多情况,数据集的分布并不是简单的线性关系,还有可能是曲线关系,聚类关系,随机分布关系等,对于这些不同的数据集分布关系,需要使用不同的回归器来拟合。


1. 分析数据集

由于缺少数据集,我自己用代码生成了一些数据,数据的生成过程和(【火炉炼AI】机器学习003-简单线性回归器的创建,测试,模型保存和加载)类似,如下代码所示。

# 构建服从多项式回归特性的数据集np.random.seed(37) # 使得每次运行得到的随机数都一样x=np.arange(2,102) 
x_shift=np.random.normal(size=x.shape)
x=x+x_shift # 构建的x含有100个数,通过在整数点引入偏差得到error=np.random.normal(size=x.shape)*800 # 构建噪音,*800是扩大噪音的影响y=1.19*x*x+0.82*x+5.95+error
plt.scatter(x,y) # 可以查看生成的数据集的分布情况dataset=[(i,j) for i,j in zip(x,y)]from sklearn.model_selection import train_test_split
train_set,test_set=train_test_split(dataset,test_size=0.2,random_state=37)
X_train=np.array([i for (i,j) in train_set]).reshape(-1,1) # 后面的fit需要先reshapey_train=np.array([j for (i,j) in train_set]).reshape(-1,1)
X_test= np.array([i for (i,j) in test_set]).reshape(-1,1)
y_test= np.array([j for (i,j) in test_set]).reshape(-1,1)

生成的数据集分布

########################小**********结###############################

1,数据集的构建可以采用在标准数据中引入误差的方式。

2,在回归或分类模型中,经常要将数据集映射到二维平面上,通过散点图的方式来查看数据集的空间分布,有了直观的初步印象后,才能选择更合适的回归或分类模型。

#################################################################


2. 简单线性回归器模型拟合数据集

图中显示的数据集好像服从线性关系,也好像服从多项式关系,对于这样的情况,可以先用简单线性回归器拟合得到回归模型,然后用测试集看看该模型的优劣。如下代码:

# 如果采用简单线性回归器进行拟合得到简单的拟合直线from sklearn import linear_model
linear_regressor=linear_model.LinearRegression() # 创建线性回归器对象linear_regressor.fit(X_train,y_train) # 使用训练数据集训练该回归器对象# 查看拟合结果y_predict=linear_regressor.predict(X_train) # 使用训练后的回归器对象来拟合训练数据plt.figure()
plt.scatter(X_train,y_train,label='train_set')
plt.scatter(X_test,y_test,color='r',label='test_set')
plt.plot(X_train,y_predict,'-b',linewidth=3,label='fitted_line')
plt.legend()# 用测试集看看该线性回归器模型的测试结果y_predict_test=linear_regressor.predict(X_test)import sklearn.metrics as metrics
print('简单线性回归器模型的评测结果----->>>')
print('均方误差MSE:{}'.format(
    round(metrics.mean_squared_error(y_predict_test,y_test),2)))
print('解释方差分:{}'.format(
    round(metrics.explained_variance_score(y_predict_test,y_test),2)))
print('简单线性回归器得到的直线方程为:y={:.3f}x+{:.3f}'
      .format(linear_regressor.coef_[0][0],linear_regressor.intercept_[0]))

-------------------------------------输---------出--------------------------------

简单线性回归器模型的评测结果----->>>
均方误差MSE:1906916.26
解释方差分:0.85
简单线性回归器得到的直线方程为:y=117.061x+-1924.904

--------------------------------------------完-------------------------------------

简单线性回归得到的拟合直线

########################小**********结###############################

1,使用简单线性回归器得到的模型在测试集上的MSE非常大,看来还有非常大的优化空间。

#################################################################


3. 采用多项式回归器

由于简单线性回归器模型在该数据集上的表现非常差,故而我们需要改进模型,所以尝试使用多项式回归器。

# 使用多项式回归器来对数据集进行拟合,得到多项式方程from sklearn.preprocessing import PolynomialFeatures
polynomial=PolynomialFeatures(degree=2) # 构建多项式回归器对象# degree是多项式的次数,此处初步的设置为2X_train_transformed=polynomial.fit_transform(X_train)# print(X_train_transformed) #transformed之后的数据是degree+1维from sklearn import linear_model
poly_regressor=linear_model.LinearRegression() # 也是构建线性回归器poly_regressor.fit(X_train_transformed,y_train) # 对多项式回归器进行训练# 查看拟合结果y_predict_polynomial=poly_regressor.predict(X_train_transformed) 
plt.figure()
plt.scatter(X_train,y_train,label='train_set')
plt.scatter(X_test,y_test,color='r',label='test_set')# print(y_predict_polynomial.shape) #(80, 1)plt.plot(X_train,y_predict_polynomial,'-b',linewidth=3,label='fitted_poly') 
# 上面的plot会产生很多条线。。。。。plt.legend()# 用测试集看看该线性回归器模型的测试结果X_test_transformed=polynomial.fit_transform(X_test)
y_predict_test=poly_regressor.predict(X_test_transformed)import sklearn.metrics as metrics
print('多项式回归器模型的评测结果----->>>')
print('均方误差MSE:{}'.format(
    round(metrics.mean_squared_error(y_predict_test,y_test),2)))
print('解释方差分:{}'.format(
    round(metrics.explained_variance_score(y_predict_test,y_test),2)))
print('得到的多项式方程为:y={:.3f}x^2+({:.3f}x)+{:.3f}'
      .format(poly_regressor.coef_[0][-1],
              poly_regressor.coef_[0][-2],
              poly_regressor.intercept_[0]))

-------------------------------------输---------出--------------------------------

多项式回归器模型的评测结果----->>>
均方误差MSE:525885.05
解释方差分:0.97
得到的多项式方程为:y=1.374x^2+(-22.187x)+487.664

--------------------------------------------完-------------------------------------

多项式回归得到的多条拟合直线

########################小**********结###############################

1,采用多项式回归器,首先需要将X特征向量经过fit_transform()函数转变到对应的维度,然后才能使用LinearRegression()对象的fit()进行训练。

2,虽然使用了多项式回归器进行拟合,但是得到的MSE仍然比较大,只是比线性回归器得到的MSE小一些而已。所以MSE这个指标是不是不靠谱?

3,从解释方差分上来看,多项式回归器对test set有了更大改进,数值为0.97

4,图中线条比较多,是因为19行plt.plot(X_train,y_predict_polynomial)绘制了多次所导致,我暂时没有明白为什么会plot多个线条 。

#################################################################


4. 对新数据进行预测

对于训练好的模型,不管是简单线性回归器还是稍复杂的多项式回归器,都要用来进行新数据的预测,下面我分别用这两个回归器预测一个新数据。

# 使用多项式回归器预测新的数据值data_X=[[66]] # 需要计算的数据点 X值print('用直线回归器得到的数值:{}'.format(linear_regressor.predict(data_X)))print('用拟合直线计算的数值:{}'.format(
    linear_regressor.coef_[0][0]*data_X[0][0]+linear_regressor.intercept_[0]))

data_X_transormed=polynomial.fit_transform(data_X)
data_X_predict=poly_regressor.predict(data_X_transormed)# print(poly_regressor.coef_, '\n',poly_regressor.intercept_)print('用多项式回归器得到的数值:{}'.format(data_X_predict))print('用多项式曲线计算的数值:{}'.format(
    poly_regressor.coef_[0][-1]*np.power(data_X[0][0],2)+
    poly_regressor.coef_[0][-2]*data_X[0][0]+
    poly_regressor.intercept_[0]))# 两者数据相等,代表predict的确是按照这个曲线方程来计算的。

-------------------------------------输---------出--------------------------------

用直线回归器得到的数值:[[5801.09012059]]
用拟合直线计算的数值:5801.090120592645
用多项式回归器得到的数值:[[5010.58753529]]
用多项式曲线计算的数值:5010.587535291616

--------------------------------------------完-------------------------------------

########################小**********结###############################

1,由于模型不同,对新数据进行预测,得到的结果也不同,但是由于多项式回归器模型对于test set的解释方差分要大一些,故而我们认为本例中多项式回归器模型更好一些,故而对新数据预测的结果更可靠一些。

2,如果某些数据集并不是服从简单的二项式,可以增加PolynomialFeatures(degree=2) 中degree的数值大小来提高x的最高次,得到的模型可能会更准确一些,但是要防止模型对train set的过拟合。

#################################################################


注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译



作者:炼丹老顽童
链接:https://www.jianshu.com/p/b1100087ae94


0人推荐
随时随地看视频
慕课网APP