Python数据拟合与广义线性回归算法学习

 更新时间:2021年04月20日 09:55:42   作者:lsldd  
这篇文章主要为大家详细介绍了Python数据拟合与广义线性回归算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

机器学习中的预测问题通常分为2类:回归与分类。

简单的说回归就是预测数值,而分类是给数据打上标签归类。

本文讲述如何用Python进行基本的数据拟合,以及如何对拟合结果的误差进行分析。

本例中使用一个2次函数加上随机的扰动来生成500个点,然后尝试用1、2、100次方的多项式对该数据进行拟合。

拟合的目的是使得根据训练数据能够拟合出一个多项式函数,这个函数能够很好的拟合现有数据,并且能对未知的数据进行预测。

代码如下:

import matplotlib.pyplot as plt 
import numpy as np 
import scipy as sp 
from scipy.stats import norm 
from sklearn.pipeline import Pipeline 
from sklearn.linear_model import LinearRegression 
from sklearn.preprocessing import PolynomialFeatures 
from sklearn import linear_model 
 
''''' 数据生成 ''' 
x = np.arange(0, 1, 0.002) 
y = norm.rvs(0, size=500, scale=0.1) 
y = y + x**2 
 
''''' 均方误差根 ''' 
def rmse(y_test, y): 
 return sp.sqrt(sp.mean((y_test - y) ** 2)) 
 
''''' 与均值相比的优秀程度,介于[0~1]。0表示不如均值。1表示完美预测.这个版本的实现是参考scikit-learn官网文档 ''' 
def R2(y_test, y_true): 
 return 1 - ((y_test - y_true)**2).sum() / ((y_true - y_true.mean())**2).sum() 
 
 
''''' 这是Conway&White《机器学习使用案例解析》里的版本 ''' 
def R22(y_test, y_true): 
 y_mean = np.array(y_true) 
 y_mean[:] = y_mean.mean() 
 return 1 - rmse(y_test, y_true) / rmse(y_mean, y_true) 
 
 
plt.scatter(x, y, s=5) 
degree = [1,2,100] 
y_test = [] 
y_test = np.array(y_test) 
 
 
for d in degree: 
 clf = Pipeline([('poly', PolynomialFeatures(degree=d)), 
     ('linear', LinearRegression(fit_intercept=False))]) 
 clf.fit(x[:, np.newaxis], y) 
 y_test = clf.predict(x[:, np.newaxis]) 
 
 print(clf.named_steps['linear'].coef_) 
 print('rmse=%.2f, R2=%.2f, R22=%.2f, clf.score=%.2f' % 
  (rmse(y_test, y), 
  R2(y_test, y), 
  R22(y_test, y), 
  clf.score(x[:, np.newaxis], y)))  
  
 plt.plot(x, y_test, linewidth=2) 
  
plt.grid() 
plt.legend(['1','2','100'], loc='upper left') 
plt.show() 

该程序运行的显示结果如下:

[-0.16140183  0.99268453]
rmse=0.13, R2=0.82, R22=0.58, clf.score=0.82
[ 0.00934527 -0.03591245  1.03065829]
rmse=0.11, R2=0.88, R22=0.66, clf.score=0.88
[  6.07130354e-02  -1.02247150e+00   6.66972089e+01  -1.85696012e+04
......
-9.43408707e+12  -9.78954604e+12  -9.99872105e+12  -1.00742526e+13
-1.00303296e+13  -9.88198843e+12  -9.64452002e+12  -9.33298267e+12
  -1.00580760e+12]
rmse=0.10, R2=0.89, R22=0.67, clf.score=0.89
显示出的coef_就是多项式参数。如1次拟合的结果为
y = 0.99268453x -0.16140183

这里我们要注意这几点:

1、误差分析。

做回归分析,常用的误差主要有均方误差根(RMSE)和R-平方(R2)。

RMSE是预测值与真实值的误差平方根的均值。这种度量方法很流行(Netflix机器学习比赛的评价方法),是一种定量的权衡方法。

R2方法是将预测值跟只使用均值的情况下相比,看能好多少。其区间通常在(0,1)之间。0表示还不如什么都不预测,直接取均值的情况,而1表示所有预测跟真实结果完美匹配的情况。
R2的计算方法,不同的文献稍微有不同。如本文中函数R2是依据scikit-learn官网文档实现的,跟clf.score函数结果一致。

而R22函数的实现来自Conway的著作《机器学习使用案例解析》,不同在于他用的是2个RMSE的比值来计算R2。
我们看到多项式次数为1的时候,虽然拟合的不太好,R2也能达到0.82。2次多项式提高到了0.88。而次数提高到100次,R2也只提高到了0.89。

2、过拟合。

使用100次方多项式做拟合,效果确实是高了一些,然而该模型的据测能力却极其差劲。
而且注意看多项式系数,出现了大量的大数值,甚至达到10的12次方。
这里我们修改代码,将500个样本中的最后2个从训练集中移除。然而在测试中却仍然测试所有500个样本。
clf.fit(x[:498, np.newaxis], y[:498])
这样修改后的多项式拟合结果如下:

[-0.17933531  1.0052037 ]
rmse=0.12, R2=0.85, R22=0.61, clf.score=0.85
[-0.01631935  0.01922011  0.99193521]
rmse=0.10, R2=0.90, R22=0.69, clf.score=0.90
...
rmse=0.21, R2=0.57, R22=0.34, clf.score=0.57

仅仅只是缺少了最后2个训练样本,红线(100次方多项式拟合结果)的预测发生了剧烈的偏差,R2也急剧下降到0.57。
而反观1,2次多项式的拟合结果,R2反而略微上升了。

这说明高次多项式过度拟合了训练数据,包括其中大量的噪音,导致其完全丧失了对数据趋势的预测能力。前面也看到,100次多项式拟合出的系数数值无比巨大。人们自然想到通过在拟合过程中限制这些系数数值的大小来避免生成这种畸形的拟合函数。

其基本原理是将拟合多项式的所有系数绝对值之和(L1正则化)或者平方和(L2正则化)加入到惩罚模型中,并指定一个惩罚力度因子w,来避免产生这种畸形系数。
这样的思想应用在了岭(Ridge)回归(使用L2正则化)、Lasso法(使用L1正则化)、弹性网(Elastic net,使用L1+L2正则化)等方法中,都能有效避免过拟合。更多原理可以参考相关资料。

下面以岭回归为例看看100次多项式的拟合是否有效。将代码修改如下:

clf = Pipeline([('poly', PolynomialFeatures(degree=d)),
                    ('linear', linear_model.Ridge ())])
clf.fit(x[:400, np.newaxis], y[:400])

结果如下:

[ 0.          0.75873781]
rmse=0.15, R2=0.78, R22=0.53, clf.score=0.78
[ 0.          0.35936882  0.52392172]
rmse=0.11, R2=0.87, R22=0.64, clf.score=0.87
[  0.00000000e+00   2.63903249e-01   3.14973328e-01   2.43389461e-01
   1.67075328e-01   1.10674280e-01   7.30672237e-02   4.88605804e-02
   ......
   3.70018540e-11   2.93631291e-11   2.32992690e-11   1.84860002e-11
   1.46657377e-11]
rmse=0.10, R2=0.90, R22=0.68, clf.score=0.90

可以看到,100次多项式的系数参数变得很小。大部分都接近于0.
另外值得注意的是,使用岭回归之类的惩罚模型后,1次和2次多项式回归的R2值可能会稍微低于基本线性回归。

然而这样的模型,即使使用100次多项式,在训练400个样本,预测500个样本的情况下不仅有更小的R2误差,而且还具备优秀的预测能力。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 用python完成一个分布式事务TCC

    用python完成一个分布式事务TCC

    这篇文章主要介绍了用python完成一个分布式事务TCC,文章里我们介绍了TCC的理论知识,也通过一个例子,完整给出了编写一个TCC事务的过程,涵盖了正常成功完成,以及成功回滚的情况,需要的朋友可以参考一下文章的具体内容
    2021-10-10
  • pycharm下载包的时候出现 no information available的解决

    pycharm下载包的时候出现 no information available的解决

    这篇文章主要介绍了pycharm下载包的时候出现 no information available的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Python应用开发频繁假死的问题分析及解决

    Python应用开发频繁假死的问题分析及解决

    最近在开发一款自动化的应用,但是,在测试时,却发现了问题,当我点击暂停任务后,此时子线程被阻塞,如果我这个时候点击停止,那么就会任务结束,之后,如果我再点击开始运行,整个应用就会卡死,所以本文介绍了Python应用开发频繁假死的问题分析及解决,需要的朋友可以参考下
    2024-08-08
  • Python smtplib实现发送邮件功能

    Python smtplib实现发送邮件功能

    这篇文章主要为大家详细介绍了Python smtplib实现发送邮件功能,包含文本、附件、图片等,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Python自定义简单图轴简单实例

    Python自定义简单图轴简单实例

    这篇文章主要介绍了Python自定义简单图轴简单实例,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • pymysql之cur.fetchall() 和cur.fetchone()用法详解

    pymysql之cur.fetchall() 和cur.fetchone()用法详解

    这篇文章主要介绍了pymysql之cur.fetchall() 和cur.fetchone()用法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • python管理包路径之pycharm自动解决包路径注册

    python管理包路径之pycharm自动解决包路径注册

    这篇文章主要介绍了python本管理包路径之pycharm自动解决包路径注册,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • python人工智能tensorflow构建卷积神经网络CNN

    python人工智能tensorflow构建卷积神经网络CNN

    学习神经网络已经有一段时间,从普通的BP神经网络到LSTM长短期记忆网络都有一定的了解,但是从未系统的把整个神经网络的结构记录下来,我相信这些小记录可以帮助我更加深刻的理解神经网络
    2022-05-05
  • 深度学习中shape[0]、shape[1]、shape[2]的区别详解

    深度学习中shape[0]、shape[1]、shape[2]的区别详解

    本文主要介绍了深度学习中shape[0]、shape[1]、shape[2]的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Python脚本实现12306火车票查询系统

    Python脚本实现12306火车票查询系统

    本文给大家分享我使用python3实现的12306火车票查询系统,小编分步骤给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2016-09-09

最新评论