天天看點

【skLearn 回歸模型】Lasso <linear_model.Lasso>

文章目錄

  • ​​Lasso概念​​
  • ​​• 定義​​
  • ​​• Lasso處理多重共線性原理​​
  • ​​二、linear_model.Lasso 類​​
  • ​​案例:Lasso特征選取​​
  • ​​① 讀取資料集​​
  • ​​② 劃分訓練集、測試集​​
  • ​​③ 對線性回歸、嶺回歸、Lasso進行對比​​
  • ​​④ 學習曲線​​

Lasso概念

• 定義

​LASSO​

​是由1996年Robert Tibshirani首次提出,全稱Least absolute shrinkage and selection operator。該方法​

​是一種壓縮估計​

​。它通過構造一個懲罰函數得到一個較為精煉的模型,使得它壓縮一些回歸系數,即強制系數絕對值之和小于某個固定值;同時設定一些回歸系數為零。是以保留了子集收縮的優點,是一種處理具有複共線性資料的有偏估計。

除了嶺回歸之外,最常被人們提到就是模型 Lasso。和嶺回歸一樣,Lasso來作用于多重共線性問題的算法,不過 ​

​Lasso使用的是系數w的L1範式​

​(​

​L1範式則是系數w的絕對值​

​)​

​乘以系數α​

​,是以 Lasso的損失函數表達式為:

【skLearn 回歸模型】Lasso <linear_model.Lasso>

​​傳回頂部​​

• Lasso處理多重共線性原理

一般來說, Lasso與嶺回歸非常相似,都是利用正則項來對原本的損失函數形成一個懲罰,以此來防止多重共線性。但是其實這種說法不是非常嚴謹,我們來看看 Lasso的數學過程。當我們使用最小二乘法來求解 Lasso中的參數w,我們依然對損失函數進行求導:

【skLearn 回歸模型】Lasso <linear_model.Lasso>
【skLearn 回歸模型】Lasso <linear_model.Lasso>

所有這些讓 Lasso成為了一個神奇的算法,盡管它是為了限制多重共線性被創造出來的,然而大部分地方并不使用它來抑制多重共線性,反而接受了它在其他方面的優勢。在邏輯回歸中涉及到,L1和L2正則化一個核心差異就是他們對系數w的影響:​

​兩個正則化都會壓縮系數w的大小,對标簽貢獻更少的特征的系數會更小,也會更容易被壓縮​

​。不過,​

​L2正則化隻會将系數壓縮到盡量接近0​

​,但​

​L1正則化主導稀疏性,是以會将系數壓縮到0​

​。這個性質,讓 Lasso成為了線性模型中的特征選擇工具首選,接下來,我們就來看看如何使用 Lasso來選擇特征。

​​傳回頂部​​

二、linear_model.Lasso 類

class sklearn.linear_model.Lasso(alpha=1.0, *, fit_intercept=True, normalize=False, precompute=False, 
                                 copy_X=True, max_iter=1000, tol=0.0001, warm_start=False, 
                                 positive=False, random_state=None, selection='cyclic')[source]      

sklearn中我們使用Lasso類來調用lasso回歸,衆多參數中我們需要比較在意的就是參數α,正則化系數。要注意的就是​

​參數 positive.當這個參數為True的時候,我們要求 Lasso回歸處的系數必須為正數​

​,以此證我們的α一定以增大來控制正則化的程度。

在skLearn中的Lasso使用的損失函數是:

【skLearn 回歸模型】Lasso <linear_model.Lasso>

案例:Lasso特征選取

① 讀取資料集

# -*- coding: utf-8
#  @Time    : 2021/1/15 15:14
#  @Author  : ZYX
#  @File    : Example6_Lasso.py
# @software: PyCharm
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.linear_model import Lasso,Ridge,LinearRegression
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.datasets import fetch_california_housing as fch

# 擷取資料集
house_value = fch()
x = pd.DataFrame(house_value.data)
y = house_value.target
x.columns = ["住戶收入中位數","房屋使用年代中位數","平均房間數目","平均卧室數目","街區人口","平均入住率","街區的緯度","街區的經度"]      

​​傳回頂部​​

② 劃分訓練集、測試集

# 劃分測試集和訓練集
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3,random_state=420)
# 重置索引
for i in [xtrain,xtest]:
    i.index = range(i.shape[0])      

​​傳回頂部​​

③ 對線性回歸、嶺回歸、Lasso進行對比

# 線性回歸進行拟合
reg = LinearRegression().fit(xtrain,ytrain)
reg_list = (reg.coef_*100).tolist()
#[43.73589305968403, 1.0211268294494038, -10.780721617317715, 62.64338275363783, 5.216125353178735e-05, -0.33485096463336095, -41.30959378947711, -42.621095362084674]
# 嶺回歸進行拟合
Ridge_ = Ridge(alpha=0).fit(xtrain,ytrain)
Ridge_list = (Ridge_.coef_*100).tolist()
#[43.735893059684045, 1.0211268294494151, -10.780721617317626, 62.64338275363741, 5.2161253532713044e-05, -0.3348509646333588, -41.3095937894767, -42.62109536208427]
# Lasso進行拟合
Lasso_ = Lasso(alpha=0).fit(xtrain,ytrain)
Lasso_list = (Lasso_.coef_*100).tolist()
#[43.735893059684045, 1.0211268294494151, -10.780721617317626, 62.64338275363741, 5.2161253532713044e-05, -0.3348509646333588, -41.3095937894767, -42.62109536208427]      

我們可以看出,當嶺回歸和Lasso中的alpha都設定為0的時候,拟合的w都幾乎差不了多少。但是Lasso盡管運作除了結果,卻報了三個UserWarning:

UserWarning: With alpha=0, this algorithm does not converge well. You are advised to use the LinearRegression estimator
  Lasso_ = Lasso(alpha=0).fit(xtrain,ytrain)
UserWarning: Coordinate descent with no regularization may lead to unexpected results and is discouraged.
  positive)
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Duality gap: 3769.8607714139102, tolerance: 1.917255476913148
  positive)      

這三條分别是這樣的内容:

  • 1.正則化系數為0,這樣算法不可收斂!如果你想讓正則化系數為0,請使用線性回歸吧
  • 2.沒有正則項的​

    ​坐标下降法​

    ​可能會導緻意外的結果,不鼓勵這樣做!
  • 3.目标函數沒有收斂,你也許想要增加疊代次數,使用一個非常小的 alpha來拟合模型可能會造成精确度問題!

看到這三條内容,大家可能會難以了解 ---- 怎麼出現了坐标下降?這是由于 sklearn中的Lasso類不是使用最小二乘法來進行求解,而是使用坐标下降。考慮一下 Lasso既然不能夠從根本解決多重共線性引起的最小二乘法無法使用的問題,那我們為什麼要堅持最小二乘法呢?明明有其他更快更好的求解方法,比如​​坐标下降​​。

【skLearn 回歸模型】Lasso <linear_model.Lasso>

有了坐标下降,就有​

​疊代​

​和​

​收斂​

​的問題,是以 sklearn不推薦我們使用0這樣的正則化系數。如果我們的确希望取到0,那我們可以使用一個比較很小的數,比如0.01,或者10*e-3這樣的值:

# 更改alpha
# 嶺回歸進行拟合
Ridge_ = Ridge(alpha=0.01).fit(xtrain,ytrain)
Ridge_list1 = (Ridge_.coef_*100).tolist()
#[43.73575720621605, 1.0211292318121836, -10.780460336251702, 62.64202320775686, 5.217068073243689e-05,
# -0.3348506517067627, -41.3095714322911, -42.62105388932374]
# Lasso進行拟合
Lasso_ = Lasso(alpha=0.01).fit(xtrain,ytrain)
Lasso_list1 = (Lasso_.coef_*100).tolist()
# [40.10568371834486, 1.0936292607860143, -3.7423763610244487, 26.524037834897207, 
# 0.0003525368511503945, -0.3207129394887799, -40.06483047344844, -40.81754399163315]      
[43.73589305968403, 1.0211268294494038, -10.780721617317715, 62.64338275363783, 5.216125353178735e-05, 
 -0.33485096463336095, -41.30959378947711, -42.621095362084674]      

通過對比可以發現,Lasso相對于嶺回歸而言,對于alpha的變化十分敏感。

假設我們對alpha再進行更改:

# 嶺回歸進行拟合
Ridge_ = Ridge(alpha=10**4).fit(xtrain,ytrain)
Ridge_list2 = (Ridge_.coef_*100).tolist()
#[34.620815176076945, 1.5196170869238694, 0.3968610529210133, 0.9151812510354866, 0.002173923801224843, 
# -0.34768660148101016, -14.736963474215257, -13.43557610252691]
# Lasso進行拟合
Lasso_ = Lasso(alpha=10**4).fit(xtrain,ytrain)
Lasso_list2 = (Lasso_.coef_*100).tolist()
# [0.0, 0.0, 0.0, -0.0, -0.0, -0.0, -0.0, -0.0]      

将alpha擴大至10000的時候,可以發現嶺回歸和Lasso的結果完全不同,嶺回歸僅有部分特征被壓縮至趨近于0,而Lasso的所有特征全部壓縮至了等于0,由此再次可以說明Lasso對于alpha的敏感。

​​傳回頂部​​

④ 學習曲線

reg = LinearRegression().fit(xtrain,ytrain)
Ridge_ = Ridge(alpha=10**4).fit(xtrain,ytrain)
Lasso_ = Lasso(alpha=1).fit(xtrain,ytrain)
# 繪制學習曲線
plt.plot(range(1,9),(reg.coef_*100).tolist(),color='red',label='LR')
plt.plot(range(1,9),(Ridge_.coef_*100).tolist(),color='green',label='Ridge')
plt.plot(range(1,9),(Lasso_.coef_*100).tolist(),color='black',label='Lasso')
plt.plot(range(1,9),[0]*8,color='grey',linestyle='--')
plt.xlabel('w')
plt.legend()
plt.show()      

通過圖像可以看出,通過Lasso可以将特征系數壓縮為0,而嶺回歸可以将特征系數壓縮的無限逼近于0。可見,比起嶺回歸, Lasso所帶的L1正則項對于系數的懲罰要重得多,并且它會将系數壓至0,可以被用來做特征選擇。也是以,我們往往讓 Lasso正則化系數a在很小的空間中變動,以此來尋找最佳的正則化系數。

繼續閱讀