天天看點

08 解決過拟合 - L2(Ridge)和L1(LASSO)正則

用L2正則的線性回歸模型,稱為Ridge回歸 (嶺回歸)

用L1正則的線性回歸模型,稱為LASSO回歸

=== L2和L1的比較 ===

$color{red}{L2-norm正則}$,由于對于各個次元的參數縮放是在一個圓内縮放的,__(對各個次元的參數進行一個播報,在一個圓内進行播報)__,是以不可能導緻有次元參數變成0的情況,那麼也就不會産生$color{red}{稀疏解}$;實際應用中,資料的次元中是存在$color{red}{噪音}$和$color{red}{備援}$的,稀疏的解可以找到有用的次元并減少備援,提高預測的$color{red}{準确率}$和$color{red}{魯棒性}$(減少了overfitting)。

L1-norm可以達到最終解的稀疏性要求。

Ridge模型具有較高的準确性、魯棒性以及穩定性;

LASSO模型具有較高的求解速度;

如果即要考慮穩定性也考慮求解的速度,就使用Elastic Net。

什麼是稀疏解?

對于一組參數θk,其中有一個或多個θ等于0,或近似等于0。稱這組參數θk存在稀疏解。

如何了解:稀疏解可以找到有用的次元并減少備援?

y=ax1+bx2+c;

若求解得到 a=3; b=0; c=2;

我們發現x2特征對于結果的預測沒有任何幫助,是以可以将x2的特征删除。

注意:

L2-Ridge不産生稀疏解,L1-LASSO可以讓解去備援。

當我們覺得每個特征都是有用的,用L2。

如果想用回歸的手段确定特征的可用性,用L1。

L1-LASSO有相對比較快的求解速度。

=== L1、L2的圖像比較 ===

首先把特征降低至2維:

y=θ0+θ1x1+θ2x2

什麼是把資料播放到圓内?

L1(左圖)、L2(右圖)中兩團紅色的圈圈是三維圖像在二維平面上的映射。L1和L2兩張圖是中間圖像的俯視圖,要立體得去看:

先忽略正則項,隻看損失函數對應的圖像:

對于: y=θ0+θ1x1+θ2x2; θ1、θ2有一組對應的取值(Β1,Β2)

當θ向量取值為損失函數最小值的點,這個點就是Β^

Β^ 這一點是線性回歸取得損失函數最優點的那個解。Β^:(Β1,Β2)

每一個小橢圓上,損失函數的值是相等的。

以Β^為圓心,越往外的橢圓損失值越大。

現在損失加入正則的情況:

加入正則懲罰項後,意味着現在的取值加入了新的限制條件,使得θ值必須在我的限制條件内才能被認可。

圖像中,L1藍色方塊和L2藍色橢圓的區域就是正則懲罰項中允許的θ值。什麼時候能夠取得最優的θ值?

$color{red}{顯然當藍色區域和紅色橢圓“相切”的那一點就是最優的θ值。}$

回過頭再次思考稀疏解的問題:

何為稀疏解?系數為0的時候。

在圖中,即意味着Β1 = 0 或Β2 = 0 或Β1 = Β2 = 0;

在L1-norm和L2-norm中 (藍色區域) ,顯然Β1 = Β2 = 0 這點為圓心,相切的點不可能在圓心上,是以這點排除。

對于我們的L1和L2來說,損失函數中懲罰項的位置是固定的。

觀察L2圖像,為什麼不能生成稀疏解:

而損失函數前半段的圖像形狀(紅色橢圓),會根據y值(真實值)的改變而發生改變。如圖:

損失函數和懲罰相相切的位置可能存在于任何一點。既然在懲罰項的圓上每一點都有可能相切,那麼切到Β1 = 0或Β2 = 0的機率趨向于0。

是以,當選擇L2-norm後,基本不可能出現稀疏解。

觀察L1圖像,為什麼能夠生成稀疏解:

如果損失函數和懲罰項相切了,意味紅色橢圓和藍色四邊形的其他任意一點都不相交,意味着藍色四邊形邊上的其他任意一點到B^ 的距離都不如相切的這一點到B^ 的距離近。

該圖形中,各個點相切的機率不是相等的。切到頂點的機率是最高的。是以更容易産生稀疏解。

=== Elastic Net ===

同時使用L1正則和L2正則的線性回歸模型就稱為Elastic Net,$color{red}{彈性網絡算法}$

p、λ都是超參數。

超參數是在開始學習過程之前設定值的參數,而不是通過訓練得到的參數資料。通常情況下,需要對超參數進行優化,給學習機選擇一組最優超參數,以提高學習的性能和效果。

=== 案例 ===

根據四種不同的回歸模型,在不同階數下的回過結果如何。

## 建立模拟資料
## 使得随機資料可預測,即隻要seed的值一樣,後續生成的随機數都一樣。
np.random.seed(100)
np.set_printoptions(linewidth=1000, suppress=True)#顯示方式設定,每行的字元數用于插入換行符,是否使用科學計數法
N = 10
## linspace:x從0~6之間等步長取N個數 
## 由于seed(10),固定了一種随機方案,np.random.randn(N)每次結果都一緻
x = np.linspace(0, 6, N) + np.random.randn(N)
y = 1.8*x**3 + x**2 - 14*x - 7 + np.random.randn(N)
x.shape           
## 将其設定為矩陣
#無論多少資料,生成一列,反之1,-1生成一行
x.shape = -1, 1 
y.shape = -1, 1 
x.shape
y.shape           

将多個管道嵌套,共4個管道Pipeline

看看每個管道做了什麼操作

管道1:多形式擴充+線性回歸

管道2:多形式擴充+RidgeCV

管道3:多形式擴充+LassoCV

管道4:多形式擴充+ElasticNetCV

## RidgeCV和Ridge的差別是:前者可以進行交叉驗證

## 目标:比較不同階數的情況下,會不會出現過拟合的情況

models = [
    Pipeline([
            ('Poly', PolynomialFeatures(include_bias=False)),
            ('Linear', LinearRegression(fit_intercept=False))
        ]),
    Pipeline([
            ('Poly', PolynomialFeatures(include_bias=False)),
            ('Linear', RidgeCV(alphas=np.logspace(-3,2,50), fit_intercept=False))
        ]),
    Pipeline([
            ('Poly', PolynomialFeatures(include_bias=False)),
            ('Linear', LassoCV(alphas=np.logspace(0,1,10), fit_intercept=False))
        ]),
    Pipeline([
            ('Poly', PolynomialFeatures(include_bias=False)),
            ('Linear', ElasticNetCV(alphas=np.logspace(0,1,10), 
                l1_ratio=[.1, .5, .7, .9, .95, 1], fit_intercept=False))
        ])
]           
## 線性回歸、Lasso回歸、Ridge回歸、ElasticNet比較
plt.figure(facecolor='w')
degree = np.arange(1,N, 2) # 階
dm = degree.size
colors = [] # 顔色
for c in np.linspace(16711680, 255, dm):
    colors.append('#%06x' % int(c))
titles = [u'線性回歸', u'Ridge回歸', u'Lasso回歸', u'ElasticNet']

for t in range(4):
    model = models[t]#選擇了模型--具體的pipeline
    plt.subplot(2,2,t+1)
    plt.plot(x, y, 'ro', ms=10, zorder=N)

    for i,d in enumerate(degree):
        # 設定階數(多項式)
        model.set_params(Poly__degree=d)
        # 模型訓練
        model.fit(x, y.ravel())

        # 擷取得到具體的算法模型
        lin = model.get_params('Linear')['Linear']
        # 列印資料
        output = u'%s:%d階,系數為:' % (titles[t],d)
        print (output, lin.coef_.ravel())

        # 産生模拟資料
        x_hat = np.linspace(x.min(), x.max(), num=100) ## 産生模拟資料
        x_hat.shape = -1,1
        # 資料預測
        y_hat = model.predict(x_hat)
        # 計算準确率
        s = model.score(x, y)

        # 
        z = N - 1 if (d == 2) else 0
        label = u'%d階, 正确率=%.3f' % (d,s)
        plt.plot(x_hat, y_hat, color=colors[i], lw=2, alpha=0.75, label=label, zorder=z)
    
    plt.legend(loc = 'upper left')
    plt.grid(True)
    plt.title(titles[t])
    plt.xlabel('X', fontsize=16)
    plt.ylabel('Y', fontsize=16)
plt.tight_layout(1, rect=(0,0,1,0.95))
plt.suptitle(u'各種不同線性回歸過拟合顯示', fontsize=22)
plt.show()           

線性回歸:1階,系數為: [-44.14102611 40.05964256]

線性回歸:3階,系數為: [ -6.80525963 -13.743068 0.93453895 1.79844791]

線性回歸:5階,系數為: [ -5.60899679 -14.80109301 0.75014858 2.11170671 -0.07724668 0.00566633]

線性回歸:7階,系數為: [-41.70721172 52.38570529 -29.56451338 -7.66322829 12.07162703 -3.86969096 0.53286096 -0.02725536]

線性回歸:9階,系數為: [-2465.58381316 6108.63817712 -5111.99333504 974.74974891 1078.89649478 -829.50277842 266.13230658 -45.71741587 4.1158274 -0.15281063]

Ridge回歸:1階,系數為: [ 29.87629065]

Ridge回歸:3階,系數為: [-12.98191422 -0.50844765 1.98772916]

Ridge回歸:5階,系數為: [-18.76655299 -0.28947771 3.32509764 -0.35027494 0.02456036]

Ridge回歸:7階,系數為: [-17.34640888 -3.48657706 4.33150776 0.39729204 -0.45104331 0.08994449 -0.0056256 ]

Ridge回歸:9階,系數為: [-2.2521578 -2.27937783 -1.70299005 -1.0348803 0.85755012 0.37020601 -0.26024292 0.04709033 -0.00277978]

Lasso回歸:1階,系數為: [ 30.30898284]

Lasso回歸:3階,系數為: [-12.31558512 -0.50643475 1.96415216]

Lasso回歸:5階,系數為: [-12.49095935 -0.5462019 1.85689229 0.04796991 -0.00459415]

Lasso回歸:7階,系數為: [-0. -0.42783947 -0.52239776 0.41588259 0.0107619 -0.00095271 -0.00041016]

Lasso回歸:9階,系數為: [-12.78111829 -0.49882979 1.80841074 0.03631125 0.00358085 -0.0003109 -0.00003417 -0.00000479 -0.00000044]

ElasticNet:1階,系數為: [ 28.51169563]

ElasticNet:3階,系數為: [-10.72359515 -1.20646101 2.03645101]

ElasticNet:5階,系數為: [-5.90338414 -1.62213355 1.13077809 0.2390498 -0.01640652]

ElasticNet:7階,系數為: [-0. -0.501937 -0.51930136 0.42305198 0.00992334 -0.00096761 -0.00041003]

ElasticNet:9階,系數為: [-0.59980891 -0.53028001 -0.49033227 0.40675528 0.00848508 0.00000901 -0.00016187 -0.00002562 -0.00000379]

資料來源:

07 過拟合欠拟合 - 案例

繼續閱讀