1. 程式人生 > >scikit-learn機器學習(二)--嶺迴歸,Lasso迴歸和ElasticNet迴歸

scikit-learn機器學習(二)--嶺迴歸,Lasso迴歸和ElasticNet迴歸

多元線性迴歸模型中,為了是均方差誤差最小化,常見的做法是引入正則化,正則化就是給對模型的引數或者說是係數新增一些先驗假設,控制模型的空間,使模型的複雜度較小。
正則化目的:防止過擬合
正則化本質:約束要優化的引數
正則化會保留樣本的所有特徵向量,但是會減少樣本特徵的數量級

嶺迴歸,Lasso迴歸和ElasticNet迴歸是常見的線性迴歸正則化方法,方法如下:

這裡寫圖片描述

不同之處:
嶺迴歸是在損失函式中加入L2範數懲罰項來控制模型的複雜度
Lasso迴歸是基於L1範數的
ElasticNet是嶺迴歸和Lasso迴歸的融合,利用了L1和L2範數

L1範數和L2範數都可以用來度量向量間的差異,但是兩者不同:


L1範數:
表示向量x中非零元素的的絕對值之和,又稱為曼哈頓距離,最小絕對誤差等,
用於度量向量間差異,如:絕對誤差和
這裡寫圖片描述
x1和x2為兩個向量
L1範數功能:
可以實現特徵稀疏,去掉一些沒有資訊的特徵

**L2範數:
表示向量x中元素的平方和再開平方,如歐式距離,度量向量間差異,如平方差和
這裡寫圖片描述
L2範數功能:
防止模型為了迎合模型訓練而過於複雜出現過擬合能力,提高模型的泛化能力。

上面主要介紹了關於正則化和範數的問題,下面進入正題:

一丶嶺迴歸

在scikit-learn中Ridge類實現了嶺迴歸模型,依舊利用之前的糖尿病人資料樣本集

python實現:

from
sklearn import datasets,linear_model,discriminant_analysis import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split #載入資料 def load_data(): diabetes=datasets.load_diabetes() return train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0
) #定義嶺迴歸模型 def test_Ridge(*data): x_train,y_train,x_test,y_test=data regr=linear_model.Ridge() regr.fit(x_train,y_train) print('Coefficients:%s,intercept %.2f' % (regr.coef_, regr.intercept_)) print("Residual sum of square:%.2f" % np.mean((regr.predict(x_test) - y_test) ** 2)) print('Score:%.2f' % regr.score(x_test, y_test)) plt.grid() plt.show() x_train,x_test,y_train,y_test=load_data() test_ridge(x_train,x_test,y_train,y_test)

結果:
這裡寫圖片描述

與前面多元線性迴歸結果差不多
Ridge類中預設的正則化佔比為alpha=1,我們可以修改alpha的值,alpha值越大正則化想的佔比越大

不同alpha值,對預測效能的影響不同,給出檢測程式碼:

def test_Ridge_alpha(*data):
    x_train, x_test, y_train, y_test = data
    alphas=[0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000]#alpha列表
    scores=[]#預測效能
    for each in alphas:
        regr = linear_model.Ridge(alpha=each)
        regr.fit(x_train, y_train)
        score=regr.score(x_test,y_test)
        scores.append(score)
    #畫圖
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    ax.plot(alphas,scores)
    ax.set_xlabel(r"$\alpha$")
    ax.set_ylabel(r"score")
    ax.set_xscale('log')
    ax.set_title("Ridge")
    plt.show()

結果如下:
這裡寫圖片描述

二丶Lasso迴歸

python程式碼:
只需要換掉regr=linear_model.Ridge()換成Lasso即可

def test_Lasso(*data):
    x_train, x_test, y_train, y_test = data
    regr=linear_model.Lasso()
    regr.fit(x_train,y_train)
    print('Coefficients:%s,intercept %.2f' % (regr.coef_, regr.intercept_))
    print("Residual sum of square:%.2f" % np.mean((regr.predict(x_test) - y_test) ** 2))
    print('Score:%.2f' % regr.score(x_test, y_test))
    plt.grid()
    plt.show()

結果:
這裡寫圖片描述
不同alpha對效能的影響:
這裡寫圖片描述

三丶ElasticNet迴歸

ElasticNet迴歸是利用了L1和L2範數的融合,所以在引數中除了alpha之外還有L1_ratio
預設alpha=1,l1_ratio=0.5

python程式碼:

def test_ElasticNet(*data):
    x_train, x_test, y_train, y_test = data
    regr=linear_model.ElasticNet()
    regr.fit(x_train,y_train)
    print('Coefficients:%s,intercept %.2f' % (regr.coef_, regr.intercept_))
    print("Residual sum of square:%.2f" % np.mean((regr.predict(x_test) - y_test) ** 2))
    print('Score:%.2f' % regr.score(x_test, y_test))
    plt.grid()
    plt.show()

結果如下:
這裡寫圖片描述

不通alpha值和L1_ratio值對效能的影響:
python程式碼:

def test_ElasticNet_alpha_l1( *data):
    x_train, x_test, y_train, y_test = data
    alphas=np.logspace(-2,2)
    rhos=np.linspace(0.01,1)
    scores=[]
    for i in alphas:
        for j in rhos:
            regr=linear_model.ElasticNet(alpha=i,l1_ratio=j)
            regr.fit(x_train,y_train)
            scores.append(regr.score(x_test,y_test))
    ##繪圖
    alphas,rhos=np.meshgrid(alphas,rhos)
    scores=np.array(scores).reshape(alphas.shape)
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    fig=plt.figure()
    ax=Axes3D(fig)
    surf=ax.plot_surface(alphas,rhos,scores,rstride=1,cstride=1,cmap=cm.jet,linewidth=0,antialiased=False)
    fig.colorbar(surf,shrink=0.5,aspect=5)
    ax.set_title('ElasticNet')
    ax.set_xlabel(r"$\alpha$")
    ax.set_ylabel(r"$\rho$")
    ax.set_zlabel("score")
    plt.show()

結果:
這裡寫圖片描述
ρ影響的是其效能下降速度
α增大,預測效能下降

本部落格主要參考:
《Python大戰機器學習》