本次,利用python的sklearn库自带的函数(线性回归,lasso回归,岭回归,弹性网络算法)对给定数据集进行预测分析。
在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合(自变量都是一次方)。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归。
优点:结果易于理解,计算上不复杂。
缺点:对非线性数据拟合不好。
适用数据类型:数值型和标称型数据。
算法类型:回归算法
线性回归的模型函数如下:
hθ=θTx
它的损失函数如下:
J(θ)=12m∑i=1m(hθ(x(i))−y(i))2
通过训练数据集寻找参数的最优解,即求解可以得到minJ(θ) 的参数向量θ ,其中这里的参数向量也可以分为参数和w和b ,分别表示权重和偏置值。
求解最优解的方法有最小二乘法和梯度下降法。
梯度下降法
梯度下降算法的思想如下(这里以一元线性回归为例):
首先,我们有一个代价函数,假设是J(θ0,θ1) ,我们的目标是minθ0,θ1J(θ0,θ1) 。
接下来的做法是:
• 首先是随机选择一个参数的组合(θ0,θ1) ,一般是设θ0=0,θ1=0 ;
• 然后是不断改变(θ0,θ1) ,并计算代价函数,直到一个局部最小值。之所以是局部最小值,是因为我们并没有尝试完所有的参数组合,所以不能确定我们得到的局部最小值是否便是全局最小值,选择不同的初始参数组合,可能会找到不同的局部最小值。
下面给出梯度下降算法的公式:
repeat until convergence{
θj:=θj−α∂∂θjJ(θ0,θ1)(forj=0andj=1)
}
也就是在梯度下降中,不断重复上述公式直到收敛,也就是找到局部最小值局部最小值 。其中符号:=是赋值符号的意思。
而应用梯度下降法到线性回归,则公式如下:
θ0:=θ0−α1m∑i=1m(hθ(x(i))−y(i)) θ1:=θ1−α1m∑i=1m((hθ(x(i))−y(i))⋅x(i))
公式中的α 称为学习率(learning rate),它决定了我们沿着能让代价函数下降程度最大的方向向下迈进的步子有多大。
在梯度下降中,还涉及都一个参数更新的问题,即更新(θ0,θ1) ,一般我们的做法是同步更新。
最后,上述梯度下降算法公式实际上是一个叫批量梯度下降(batch gradient descent),即它在每次梯度下降中都是使用整个训练集的数据,所以公式中是带有∑mi=1 。
以引入波士顿房价数据为例:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2019年5月12日
@author: wuluo
'''
__author__ = 'wuluo'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2019-05-12'
# 1.导入模块=========
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
import sklearn.datasets as datasets
#机器算法模型
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
#切割训练数据和样本数据
from sklearn.model_selection import train_test_split
#用于模型评分
from sklearn.metrics import r2_score
# 2.生成训练数据和测试数据========
boston = datasets.load_boston()
train = boston.data
target = boston.target
#切割数据样本集合测试集
X_train,x_test,y_train,y_true = train_test_split(train,target,test_size=0.2)
##创建学习模型==========
linear = LinearRegression()
ridge = Ridge()
lasso = Lasso()
elasticnet = ElasticNet()
##训练模型================
linear.fit(X_train,y_train)
ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)
elasticnet.fit(X_train,y_train)
##数据预测==============
y_pre_linear = linear.predict(x_test)
y_pre_ridge = ridge.predict(x_test)
y_pre_lasso = lasso.predict(x_test)
y_pre_elasticnet = elasticnet.predict(x_test)
##评分==============
linear_score=r2_score(y_true,y_pre_linear)
ridge_score=r2_score(y_true,y_pre_ridge)
lasso_score=r2_score(y_true,y_pre_lasso)
elasticnet_score=r2_score(y_true,y_pre_elasticnet)
display(linear_score,ridge_score,lasso_score,elasticnet_score)
##绘图===========
#Linear
plt.plot(y_true,label='true')
plt.plot(y_pre_linear,label='linear')
plt.legend()
#Ridge
plt.plot(y_true,label='true')
plt.plot(y_pre_ridge,label='ridge')
plt.legend()
#lasso
plt.plot(y_true,label='true')
plt.plot(y_pre_lasso,label='lasso')
plt.legend()
#elasticnet
plt.plot(y_true,label='true')
plt.plot(y_pre_elasticnet,label='elasticnet')
plt.legend()
if __name__ == "__main__":
pass
输出数据:
0.7598728190505353
0.766322169211523
0.6878028395908573
0.6957468697564252
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2019年5月12日
@author: wuluo
'''
__author__ = 'wuluo'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2019-05-12'
import numpy as np
import matplotlib.pyplot as mp
from sklearn import linear_model, datasets
np.random.seed(1)
"""创建随机样本"""
X, y, coef = datasets.make_regression(n_features=1, noise=9, coef=True)
# 增加异常数据
n_outliers = 5 # 异常值的数量
X[:n_outliers] = 3 + 0.5 * np.random.normal(size=(n_outliers, 1))
y[:n_outliers] = -3 + 10 * np.random.normal(size=n_outliers)
"""建模、拟合"""
# 线性回归
lr = linear_model.LinearRegression().fit(X, y)
# RANSAC(RANdom SAmple Consensus)
ransac = linear_model.RANSACRegressor()
ransac.fit(X, y)
inlier_mask = ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)
"""预测"""
line_X = np.arange(X.min(), X.max())[:, np.newaxis]
line_y = lr.predict(line_X)
line_y_ransac = ransac.predict(line_X)
# 回归系数的比较
print("Estimated coefficients (true, linear regression, RANSAC):")
print(coef, lr.coef_, ransac.estimator_.coef_)
"""可视化"""
mp.scatter(X[inlier_mask], y[inlier_mask], s=9, color='g', label='Inliers')
mp.scatter(X[outlier_mask], y[outlier_mask], s=9, color='y', label='Outliers')
mp.plot(line_X, line_y, color='y', label='Linear regressor')
mp.plot(line_X, line_y_ransac, label='RANSAC regressor')
mp.legend(loc='lower right')
mp.show()
if __name__ == "__main__":
pass
岭回归是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价,获得回归系数更为符合实际、更可靠的回归方法,对病态数据的耐受性远远强于最小二乘法。
岭回归分析法是从根本上消除复共线性影响的统计方法。岭回归模型通过在相关矩阵中引入一个很小的岭参数K(1>K>0),并将它加到主对角线元素上,从而降低参数的最小二乘估计中复共线特征向量的影响,减小复共线变量系数最小二乘估计的方法,以保证参数估计更接近真实情况。岭回归分析将所有的变量引入模型中,比逐步回归分析提供更多的信息。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2019年5月12日
@author: wuluo
'''
__author__ = 'wuluo'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2019-05-12'
import numpy as np # 快速操作结构数组的工具
import matplotlib.pyplot as plt # 可视化绘制
from sklearn.linear_model import Ridge, RidgeCV # Ridge岭回归,RidgeCV带有广义交叉验证的岭回归
# 样本数据集,第一列为x,第二列为y,在x和y之间建立回归模型
data = [
[0.067732, 3.176513], [0.427810, 3.816464], [0.995731, 4.550095], [
0.738336, 4.256571], [0.981083, 4.560815],
[0.526171, 3.929515], [0.378887, 3.526170], [0.033859, 3.156393], [
0.132791, 3.110301], [0.138306, 3.149813],
[0.247809, 3.476346], [0.648270, 4.119688], [0.731209, 4.282233], [
0.236833, 3.486582], [0.969788, 4.655492],
[0.607492, 3.965162], [0.358622, 3.514900], [0.147846, 3.125947], [
0.637820, 4.094115], [0.230372, 3.476039],
[0.070237, 3.210610], [0.067154, 3.190612], [0.925577, 4.631504], [
0.717733, 4.295890], [0.015371, 3.085028],
[0.335070, 3.448080], [0.040486, 3.167440], [
0.212575, 3.364266], [0.617218, 3.993482], [0.541196, 3.891471]
]
# 生成X和y矩阵
dataMat = np.array(data)
X = dataMat[:, 0:1] # 变量x
y = dataMat[:, 1] # 变量y
# ========岭回归========
model = Ridge(alpha=0.5)
model = RidgeCV(alphas=[0.1, 1.0, 10.0]) # 通过RidgeCV可以设置多个参数值,算法使用交叉验证获取最佳参数值
model.fit(X, y) # 线性回归建模
print('系数矩阵:\n', model.coef_)
print('线性回归模型:\n', model)
# print('交叉验证最佳alpha值',model.alpha_) # 只有在使用RidgeCV算法时才有效
# 使用模型预测
predicted = model.predict(X)
# 绘制散点图 参数:x横轴 y纵轴
plt.scatter(X, y, marker='x')
plt.plot(X, predicted, c='r')
# 绘制x轴和y轴坐标
plt.xlabel("x")
plt.ylabel("y")
# 显示图形
plt.show()
if __name__ == "__main__":
pass
LASSO回归是由1996年Robert Tibshirani首次提出,全称Least absolute shrinkage and selection operator。该方法是一种压缩估计。它通过构造一个惩罚函数得到一个较为精炼的模型,使得它压缩一些回归系数,即强制系数绝对值之和小于某个固定值;同时设定一些回归系数为零。因此保留了子集收缩的优点,是一种处理具有复共线性数据的有偏估计。
LASSO是在RSS最小化的计算中加入一个Lp范数作为罚约束。
Lp范数的好处是当r充分大时,可以把某些待估系数精确地收缩到零。
调整参数r的确定,通过交叉验证法:对r的给定值,进行交叉验证,选取交叉验证误差最小的r值。然后按照得到的 值,用全部数据重新拟合模型即可。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
u'''
Created on 2019年5月12日
@author: wuluo
'''
__author__ = 'wuluo'
__version__ = '1.0.0'
__company__ = u'重庆交大'
__updated__ = '2019-05-12'
import numpy as np # 快速操作结构数组的工具
import matplotlib.pyplot as plt # 可视化绘制
# Lasso回归,LassoCV交叉验证实现alpha的选取,LassoLarsCV基于最小角回归交叉验证实现alpha的选取
from sklearn.linear_model import Lasso, LassoCV, LassoLarsCV
# 样本数据集,第一列为x,第二列为y,在x和y之间建立回归模型
data = [
[0.067732, 3.176513], [0.427810, 3.816464], [0.995731, 4.550095], [
0.738336, 4.256571], [0.981083, 4.560815],
[0.526171, 3.929515], [0.378887, 3.526170], [0.033859, 3.156393], [
0.132791, 3.110301], [0.138306, 3.149813],
[0.247809, 3.476346], [0.648270, 4.119688], [0.731209, 4.282233], [
0.236833, 3.486582], [0.969788, 4.655492],
[0.607492, 3.965162], [0.358622, 3.514900], [0.147846, 3.125947], [
0.637820, 4.094115], [0.230372, 3.476039],
[0.070237, 3.210610], [0.067154, 3.190612], [0.925577, 4.631504], [
0.717733, 4.295890], [0.015371, 3.085028],
[0.335070, 3.448080], [0.040486, 3.167440], [
0.212575, 3.364266], [0.617218, 3.993482], [0.541196, 3.891471]
]
# 生成X和y矩阵
dataMat = np.array(data)
X = dataMat[:, 0:1] # 变量x
y = dataMat[:, 1] # 变量y
# ========Lasso回归========
model = Lasso(alpha=0.01) # 调节alpha可以实现对拟合的程度
# model = LassoCV() # LassoCV自动调节alpha可以实现选择最佳的alpha。
# model = LassoLarsCV() # LassoLarsCV自动调节alpha可以实现选择最佳的alpha
model.fit(X, y) # 线性回归建模
print('系数矩阵:\n', model.coef_)
print('线性回归模型:\n', model)
# print('最佳的alpha:',model.alpha_) # 只有在使用LassoCV、LassoLarsCV时才有效
# 使用模型预测
predicted = model.predict(X)
# 绘制散点图 参数:x横轴 y纵轴
plt.scatter(X, y, marker='x')
plt.plot(X, predicted, c='r')
# 绘制x轴和y轴坐标
plt.xlabel("x")
plt.ylabel("y")
# 显示图形
plt.show()
if __name__ == "__main__":
pass
另外,推荐一个链接:https://blog.csdn.net/cungudafa/article/details/90032644