常用线性回归算法类库简介

常用线性回归算法类库简介:

  • LinearRegression

    LinearRegression类就是我们平时所说的普通线性回归;

  • Ridge

    由于LinearRegression没有考虑过拟合的问题,有可能导致泛化能力较差,这时损失函数可以加入正则化项,如果加入的是L2范数的正则化项,就是Ridge回归的损失函数;

    验证方法:Ridge类并没有用到交叉验证之类的验证方法,需要我们自己把数据集分成训练集和测试集,需要自己设置好超参数α,然后进行训练优化。

    使用场景:一般来说,只要我们觉得数据有线性关系,并且使用LinearRegression类拟合的不是特别好,需要正则化时,可以考虑用Ridge类。但是这个类最大的缺点是每次我们要自己指定一个超参数α,然后自己评估α的好坏,比较麻烦,一般都会使用下面将会讲到的RidgeCV类来跑Ridge回归,不推荐直接用这个Ridge类,除非你只是为了学习Ridge回归。

  • RidgeCV

    RidgeCV类的损失函数和损失函数的优化方法与Ridge类完全相同,区别在于验证方法。

    验证方法:RidgeCV类对超参数α使用了交叉验证,来帮助我们选择一个合适的α值。在初始化RidgeCV类时,我们可以提供一组备选的α值。RidgeCV类会帮我们选择一个合适的α值,免去了我们自己去一轮轮筛选α值的苦恼。

    使用场景:一般来说,只要我们觉得数据有线性关系,并且使用LinearRegression类拟合的不是特别好,需要正则化时,可以考虑使用RidgeCV类。为什么这里只是考虑使用RidgeCV类呢?因为线性回归正则化有很多的变种,Ridge只是其中的一种。如果输入特征的维度很高,而且是稀疏线性关系的话,RidgeCV类就不合适了。

  • Lasso

    线性回归的L1正则化通常称为Lasso回归,它和Ridge回归的区别是在损失函数上增加的是L1正则化项,而不是L2正则化项。

    Lasso回归可以使得一些特征的系数变小,甚至一些绝对值非常小的系数直接变为0,增强模型的泛化能力。

    Lasso回归的损失函数的优化方法常用的有两种,分别是坐标轴下降法和最小角回归法。Lasso类采用的是坐标轴下降法,后面讲到的LassoLars类采用的是最小角回归法。

    验证方法:Lasso类没有使用交叉验证之类的验证方法,和Ridge类类似,需要我们把数据集分成训练集和测试集,需要自己设置好超参数α,然后进行训练优化。

    使用场景:一般来说,对于高维的特征数据,尤其是线性关系稀疏的数据,我们会采用Lasso回归;或者是要在一堆特征里面找出主要的特征,那么Lasso回归更是首选了。但是Lasso类需要自己对α调优,所以不是Lasso回归的首选,一般使用下面将会讲到的LassoCV类。

  • LassoCV

    LassoCV类的损失函数和损失函数的优化方法与Lasso类完全相同,区别在于验证方法。

    验证方法:LassoCV类对超参数α使用了交叉验证,来帮助我们选择一个合适的α值。在初始化LassoCV类时,可以传一组备选的α值。LassoCV类会帮助我们选择一个合适的α值。免去了我们自己去一轮轮筛选α的苦恼。

    使用场景:LassoCV类是进行Lasso回归的首选。当我们面临在一堆高维特征中找出主要特征时,LassoCV类更是必选。当面对稀疏线性关系时,LassoCV也很好用。

  • LassoLars

    LassoLars类的损失函数和验证方法与Lasso类相同,区别在于损失函数的优化方法。

    Lasso回归的损失函数优化方法常用的有两种,分别是坐标轴下降法和最小角回归法。LassoLars类采用的是最小角回归法,前面讲的Lasso类采用的是坐标轴下降法。

    使用场景:LassoLars类需要我们自己对α值进行调优,所以不是Lasso回归的首选,一般使用下面将会讲到的LassoLarsCV类。

  • LassoLarsCV

    LassoLarsCV类的损失函数和损失函数的优化方法与LassoLars类完全相同,区别在于验证方法。

    验证方法:LassoLarsCV类对超参数α使用了交叉验证,来帮助我们选择一个合适的α值。在初始化LassoLarsCV类时,我们可以传一组备选的α值。LassoLarsCV类会帮我们选择一个合适的α值。免去了我们自己去一轮轮筛选α的苦恼。

    使用场景:LassoLarsCV类是进行Lasso回归的第二选择。第一选择是前面讲到的LassoCV类。那么LassoLarsCV类有没有适用的场景呢?换句话说,用最小角回归法什么时候比坐标轴下降法好呢?场景一:如果我们想探索超参数α更多的相关值的话,由于最小角回归可以看到回归路径,此时用LassoLarsCV比较好。场景二: 如果我们的样本数远小于样本特征数的话,用LassoLarsCV也比LassoCV好。其余场景最好用LassoCV。

  • LassoLarsIC

    LassoLarsIC类的损失函数和损失函数的优化方法与LassoLarsCV类完全相同,区别在于验证方法。

    验证方法:LassoLarsIC类对超参数α没有使用交叉验证,而是使用Akaike信息准则(AIC)和贝叶斯信息准则(BIC)。此时我们并不需要指定备选的α值,而是由LassoLarsIC类基于AIC和BIC自己选择。使用LassoLarsIC类我们可以一轮找到超参数α,而用K折交叉验证的话,我们需要K+1轮才能找到。相比之下LassoLarsIC类寻找α更快。

    使用场景:从验证方法可以看出,验证α,LassoLarsIC比LassoLarsCV快很多。那么是不是LassoLarsIC类一定比LassoLarsCV类好呢? 不一定!由于使用了AIC和BIC准则,我们的数据必须满足一定的条件才能使用LassoLarsIC类。这样的准则需要对解的自由度做一个适当的估计。该估计是来自大样本(渐近结果),并假设该模型是正确的(即这些数据确实是由假设的模型产生的)。当待求解的问题的条件数很差的时候(比如特征个数大于样本数量的时候),这些准则就会有崩溃的风险。所以除非我们知道数据是来自一个模型确定的大样本,并且样本数量够大,我们才能用LassoLarsIC。而实际上我们得到的数据大部分都不能满足这个要求,实际应用中很少使用这个看上去很美的类。

  • ElasticNet

    ElasticNet可以看做是Lasso和Ridge中庸化的产物。它也是对普通的线性回归做了正则化,但是它的损失函数既不全是L1正则化,也不全是L2正则化,而是用一个权重参数ρ来平衡L1和L2正则化的比重,形成了一个全新的损失函数;

    验证方法:ElasticNet类并没有用到交叉验证之类的验证方法,和Lasso类类似,需要我们自己把数据集分成训练集和测试集,需要自己设置好超参数α和ρ,然后进行训练优化。

    使用场景:ElasticNet类需要自己对α和ρ调优,所以不是ElasticNet回归的首选,一般使用下面将会讲的ElasticNetCV类。

  • ElasticNet

    ElasticNetCV类的损失函数和损失函数的优化方法与ElasticNet类完全相同,区别在于验证方法。

    验证方法:ElasticNetCV类对超参数α和ρ使用了交叉验证,来帮助我们选择合适的α值和ρ值。在初始化ElasticNetCV类时,我们可以传一组备选的α值和ρ。ElasticNetCV类会帮我们选择一个合适的α值和ρ值。免去了我们自己去一轮轮筛选α值和ρ值的苦恼。

    使用场景:ElasticNetCV类用在我们发现使用Lasso回归太过(太多特征被稀疏为0),而使用Ridge回归又正则化不够(回归系数衰减的太慢)的时候。一般不推荐拿到数据就直接使用ElasticNetCV类。

此部分参考文章:scikit-learn(sklearn)线性回归算法类库介绍

数据集来源于一个循环发电厂,共有9568个样本数据,每个数据有5列,分别是AT(温度),V(压力),AP(湿度),RH(压强)和PE(输出电力)。

import numpy as np
import pandas as pd
​
data = pd.read_excel('Folds5x2_pp.xlsx')
data.head()
data.shape
X = data[['AT','V','AP','RH']]
Y = data[['PE']]
# 划分训练集和测试集
from sklearn.model_selection import train_test_split
train_X,test_X,train_Y,test_Y = train_test_split(X,Y,test_size = 0.3,random_state = 1)
​
# 拟合训练集
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(train_X,train_Y)
# 打印模型系数
print(linreg.intercept_)
print(linreg.coef_)
​
# 评价模型好坏
from sklearn import metrics
test_Y_pred = linreg.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))
​
# 交叉验证持续优化模型
from sklearn.model_selection import cross_val_predict
Y_pred = cross_val_predict(linreg,X,Y,cv = 10)
print("10折交叉验证MSE:",metrics.mean_squared_error(Y,Y_pred))
print("10折交叉验证RMSE:",np.sqrt(metrics.mean_squared_error(Y,Y_pred)))
​
# 加入正则化项
​
## 加入L2正则化
from sklearn.linear_model import RidgeCV
# 在初始化RidgrCV类时,提供一组备选的α值,RidgeCV类会帮我们选择一个合适的α值
ridgecv = RidgeCV(alphas = [0.01,0.1,0.5,1,3,5,7,10,20,100],cv = 5)
# 拟合训练集
ridgecv.fit(train_X,train_Y)
# 打印最优α值
print("最优的alpha值:",ridgecv.alpha_)
# 打印模型的系数
print(ridgecv.intercept_)
print(ridgecv.coef_)
# 评价模型好坏
test_Y_pred = ridgecv.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))
​
## 加入L1正则化
### 坐标轴下降法
from sklearn.linear_model import LassoCV
lassocv = LassoCV(alphas = [0.01,0.1,0.5,1,3,5,7,10,20,100],cv = 5)
# 拟合训练集
lassocv.fit(train_X,train_Y.values.ravel())
print("最优的α值:",lassocv.alpha_)
print(lassocv.intercept_)
print(lassocv.coef_)
# 评价模型好坏
test_Y_pred = lassocv.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))
​
### 最小回归法
from sklearn.linear_model import LassoLarsCV
lassoLarscv = LassoLarsCV(cv = 5)
lassoLarscv.fit(train_X,train_Y.values.ravel())
print(lassoLarscv.intercept_)
print(lassoLarscv.coef_)
test_Y_pred = lassoLarscv.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))
​
## Lasso和Ridge中庸化的产物:ElasticNet
from sklearn.linear_model import ElasticNet
# 在初始化ElasticNet类时,指定超参数α和ρ,默认值分别是1.0和0.5
elasticNet = ElasticNet(alpha = 1.0,l1_ratio = 0.5)
elasticNet.fit(train_X,train_Y)
test_Y_pred = elasticNet.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))
**************************
from sklearn.linear_model import ElasticNetCV
elasticNetCV = ElasticNetCV(l1_ratio = 0.7,alphas = [0.01,0.1,0.5,1,3,5,7,10,20,100],cv = 5)
elasticNetCV.fit(train_X,train_Y.values.ravel())
print("最优的alpha值:",elasticNetCV.alpha_)
print(elasticNetCV.intercept_)
print(elasticNetCV.coef_)
test_Y_pred = elasticNetCV.predict(test_X)
print("测试集MSE:",metrics.mean_squared_error(test_Y,test_Y_pred))
print("测试集RMSE:",np.sqrt(metrics.mean_squared_error(test_Y,test_Y_pred)))

你可能感兴趣的:(常用线性回归算法类库简介)