機器學習入門線性迴歸 嶺迴歸與Lasso迴歸(二)

一 線性迴歸(Linear Regression )

1. 線性迴歸概述python

  迴歸的目的是預測數值型數據的目標值,最直接的方法就是根據輸入寫出一個求出目標值的計算公式,也就是所謂的迴歸方程,例如y = ax1+bx2,其中求迴歸係數的過程就是迴歸。那麼迴歸是如何預測的呢?當有了這些迴歸係數,給定輸入,具體的作法就是將回歸係數與輸入相乘,再將結果加起來就是最終的預測值。說到迴歸,通常指的都是線性迴歸,固然也存在非線性迴歸,在此不作討論。算法

  假定輸入數據存在矩陣x中,而回歸係數存放在向量w中。那麼對於給定的數據x1,預測結果能夠經過y1 = x1Tw給出,那麼問題就是來尋找回歸係數。一個最經常使用的方法就是尋找偏差最小的w,偏差能夠用預測的y值和真實的y值的差值表示,因爲正負差值的差別,能夠選用平方偏差,也就是對預測的y值和真實的y值的平方求和,用矩陣可表示爲:
\[ (y - xw)T(y - xw) \]
如今問題就轉換爲尋找使得上述矩陣值最小的w,對w求導爲:xT(y - xw),令其爲0,解得:
\[ w = (xTx)-1xTy \]
這就是採用此方法估計出來的.dom

案例: 糖尿病迴歸分析函數

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline

#導包讀取
from sklearn import datasets
diabetes = datasets.load_diabetes()

#生成DataFrame 與 Series對象
train = DataFrame(data = diabetes.data,columns = diabetes.feature_names)
target = diabetes.target

# 數據集拆分 訓練集和樣本集
# 模型選擇的包
from sklearn.model_selection import train_test_split

## train 數據樣本集
# target 樣本標籤
# test_size  測試集的比例
# random_state 隨機數種子,限定隨機取值的隨機順序,每個種子固定一組隨機數
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.1, random_state=42)

#導入線性迴歸與KNN模型
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor

#訓練數據
linear = LinearRegression()
linear.fit(X_train,y_train)
#預測數據
y_ = linear.predict(X_test)

plt.plot(y_,label='Predict')
plt.plot(y_test,label='True')
plt.legend()

# 線性迴歸模型的擬合度的好壞,就是看真實值和預測值之間的偏差的大小
# 殘差直方圖,評價迴歸模型的好壞,瘦高就是好,矮胖就是很差
plt.hist(y_test - y_,rwidth=0.9,bins=10)
plt.xlabel('cost-value')
plt.ylabel('numbers')

# 還能夠用r2_score來評估迴歸模型的好壞,擬合優度
# 比較不一樣的迴歸模型的r2的分值大小,越大越好
from sklearn.metrics import r2_score
r2_score(y_test,y_)
#0.5514251914993504
# 使用KNN迴歸器處理
knn = KNeighborsRegressor(n_neighbors=7)
knn.fit(X_train,y_train)
knn_y_ = knn.predict(X_test)

plt.plot(y_,label='Linear-Predict')
plt.plot(knn_y_,label='knn-Predict')
plt.plot(y_test,label='True')
plt.legend()

# 先用殘差直方圖比較KNN和Linear哪一個更好
plt.figure(figsize=(10,4))
axes1 = plt.subplot(1,2,1)
axes1.hist(knn_y_ - y_test,rwidth=0.9)
axes1.set_xlabel('cost-value')
axes1.set_ylabel('numbers')
axes1.set_title('KNN')

axes2 = plt.subplot(1,2,2)
axes2.hist(y_test - y_,rwidth=0.9,bins=10)
axes2.set_xlabel('cost-value')
axes2.set_ylabel('numbers')
axes2.set_title('Linear')

注意:工具

np.random.seed(1)
np.random.randint(0,10,size=10)測試

array([5, 8, 9, 5, 0, 0, 1, 7, 6, 9])

二 局部加權線性迴歸(Locally Weighted Linear Regression,LWLR)

1.概述優化

  針對於線性迴歸存在的欠擬合現象,能夠引入一些誤差獲得局部加權線性迴歸對算法進行優化。在該算法中,給待測點附近的每一個點賦予必定的權重,進而在所創建的子集上進行給予最小均方差來進行普通的迴歸,分析可得迴歸係數w可表示爲:
\[ w = (xTWx)-1xTWy, \]
其中W爲每一個數據點賦予的權重,那麼怎樣求權重呢,核函數能夠當作是求解點與點之間的類似度,在此能夠採用核函數,相應的根據預測點與附近點之間的類似程度賦予必定的權重,在此選用最經常使用的高斯核,則權重能夠表示爲:
\[ w(i,i) = exp(|x(i) - x| / -2k2), \]
其中K爲寬度參數,至於此參數的取值,目前仍沒有一個確切的標準,只有一個範圍的描述,因此在算法的應用中,能夠採用不一樣的取值分別調試,進而選取最好的結果。spa

三 嶺迴歸

1.概述調試

  爲了解決上述問題,統計學家引入了「嶺迴歸」的概念。簡單說來,嶺迴歸就是在矩陣XTX上加上一個λr,從而使得矩陣非奇異,從而能對XTX + λx求逆。其中矩陣r爲一個m*m的單位矩陣,對角線上的元素全爲1,其餘元素全爲0,而λ是一個用戶定義的數值,這種狀況下,迴歸係數的計算公式將變爲:
\[ w = (xTx+λI)-1xTy, \]
其中I是一個單位矩陣。code

  嶺迴歸就是用了單位矩陣乘以常量λ,由於只I貫穿了整個對角線,其他元素爲0,形象的就是在0構成的平面上有一條1組成的「嶺」,這就是嶺迴歸中嶺的由來。

  嶺迴歸最早是用來處理特徵數多與樣本數的狀況,如今也用於在估計中加入誤差,從而獲得更好的估計。這裏引入λ限制了全部w的和,經過引入該懲罰項,可以減小不重要的參數,這個技術在統計學上也叫作縮減。縮減方法能夠去掉不重要的參數,所以能更好的理解數據。選取不一樣的λ進行測試,最後獲得一個使得偏差最小λ。

優勢 :

  • 縮減方法能夠去掉不重要的參數,所以能更好地理解數據。此外,與簡單的線性迴歸相比,縮減法能取得更好的預測效果

  • 嶺迴歸是加了二階正則項的最小二乘,主要適用於過擬合嚴重或各變量之間存在多重共線性的時候,嶺迴歸是有bias的,這裏的bias是爲了讓variance更小。

    爲了獲得一致假設而使假設變得過分嚴格稱爲過擬合
    bias:指的是模型在樣本上的輸出與真實值的偏差
    variance:指的是每一個模型的輸出結果與全部模型平均值(指望)之間的偏差

特色

  • 1.嶺迴歸能夠解決特徵數量比樣本量多的問題
  • 2.嶺迴歸做爲一種縮減算法能夠判斷哪些特徵重要或者不重要,有點相似於降維的效果
  • 3.縮減算法能夠看做是對一個模型增長誤差的同時減小方差

應用場景:

  • 1.數據點少於變量個數
  • 2.變量間存在共線性(最小二乘迴歸獲得的係數不穩定,方差很大)

  • 3.應用場景就是處理高度相關的數據

    多重共線性(Multicollinearity)是指線性迴歸模型中的解釋變量之間因爲存在精確相關關係或高度相關關係而使模型估計失真或難以估計準確

案例: 嶺迴歸案例分析

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

n_samples = 5
n_features = 3

#生成5行3列的樣本數據
train = np.random.random(size=(n_samples,n_features))
target = [1,2,3,4,5]

from sklearn.linear_model import LinearRegression
#導入線性迴歸模型
linear = LinearRegression()
linear.fit(train,target)

# 比較普通線性迴歸和嶺迴歸的區別
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso

n_samples = 200
n_features = 10
#生成樣本數據
train = np.random.random(size=(n_samples,n_features))
target = np.random.randint(0,10,size=200)

# alpha就是嶺迴歸係數
# 嶺迴歸係數越大,原始係數被壓縮的越嚴重
# 嶺迴歸係數越小,原始係數越趨向於線性迴歸模型的係數
ridge = Ridge(alpha=10)

linear = LinearRegression()
# 嶺迴歸的懲罰係數
# 懲罰係數越大,原始係數的做用就越小
# 懲罰係數越小,原始係數的做用就越大
lasso = Lasso(alpha=0.1)

ridge.fit(train,target)
linear.fit(train,target)
lasso.fit(train,target)

import matplotlib.pyplot as plt
%matplotlib inline

ridge_coef = ridge.coef_
line_coef = linear.coef_
lasso_coef = lasso.coef_

plt.plot(ridge_coef,label='Ridge')
plt.plot(line_coef,label='Linear')
plt.plot(lasso_coef,label='Lasso')

plt.legend()
plt.title('coefs')

四 Lasso迴歸(least absolute shrinkage and selection operator)

1 概述

Lasso迴歸: 最小絕對值收縮和選擇算子

與嶺迴歸相似,它也是經過增長懲罰函數來判斷、消除特徵間的共線性。

對於參數w增長一個限定條件,能達到和迴歸同樣的效果:
\[ ∥w∥1=∑i=1d|wi|≤λ \]
當λ足夠小時,一些影響較弱的係數會所以被迫縮減到0

綜合案例 : 波士頓房價

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline

#導包解析數據
from sklearn import datasets
boston = datasets.load_boston()
train = boston.data
target = boston.target

#切分出樣本集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(train,target,test_size=0.2,random_state=2)

#用三種模型分別預測
linear = LinearRegression()
ridge = Ridge(alpha=0)
lasso = Lasso(alpha=0)

linear.fit(X_train,y_train)
ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)

y1_ = linear.predict(X_test)
y2_ = ridge.predict(X_test)
y3_ = lasso.predict(X_test)

print("linear:{},ridge:{},lasso:{}".format(r2_score(y_test,y1_),r2_score(y_test,y2_),r2_score(y_test,y3_)))

#linear:0.778720987477258,ridge:0.778720987477258,lasso:0.7787209874772579
# 應該採用普通線性迴歸處理
plt.plot(y1_,label='Predict')
plt.plot(y_test,label='True')
plt.xlabel('features')
plt.ylabel('prices')
plt.legend()

五 普通線性迴歸,嶺迴歸,Lasso迴歸

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 根據實際值與預測值,給模型打分
from sklearn.metrics import r2_score 

np.random.seed(42) #給numpy隨機數指定種子,這樣生成隨機數,就會固定
n_samples,n_features = 50,200
#生成樣本
x = np.random.randn(n_samples,n_features)
#係數,也就是W
coef = 3*np.random.randn(n_features)
#係數歸零化索引
inds = np.arange(n_features)
#打亂順序
np.random.shuffle(inds)
#對係數進行歸零化處理
coef[inds[10:]] = 0
#目標值
y = np.dot(x,coef)
#增長噪聲
y += 0.01*np.random.normal(n_samples)

#訓練數據
x_train,y_train = x[:n_samples//2],y[:n_samples//2]
#測試數據
x_test,y_test = x[n_samples//2:],y[n_samples//2:]
使用普通線性迴歸
#使用普通線性迴歸
from sklearn.linear_model import LinearRegression
lreg = LinearRegression()
#訓練數據
reg = lreg.fit(x_train,y_train)
#預測數據
y_pred = lreg.predict(x_test)
r2_score(y_test,y_pred)

#輸出  0.04200879234206356
使用嶺迴歸
#使用嶺迴歸
from sklearn.linear_model import Ridge
ridge = Ridge()
#訓練數據
reg2 = ridge.fit(x_train,y_train)
#預測數據
y_pred = ridge.predict(x_test)
#獲取迴歸模型的分數
r2_score(y_test,y_pred)

#輸出  0.04340880021578697
使用Lasso迴歸
from sklearn.linear_model import Lasso
lasso = Lasso()
reg3 = lasso.fit(x_train,y_train)
y_pred_lasso = lasso.predict(x_test)
r2_score(y_test,y_pred_lasso)

#輸出  0.2429444024252334
繪圖來查詢比較
# 畫出參數
plt.figure(figsize=(12,8))
#線性迴歸
plt.subplot(221)
plt.plot(reg.coef_,color = 'lightgreen',lw = 2,label = 'lr coefficients')
plt.legend()
#嶺迴歸
plt.subplot(222)
plt.plot(reg2.coef_,color = 'red',lw = 2,label = 'ridge coefficients')
plt.legend()
#Lasso迴歸
plt.subplot(223)
plt.plot(reg3.coef_,color = 'gold',lw = 2,label = 'lasso coefficients')
plt.legend()
#測試數據系統w
plt.subplot(224)
plt.plot(coef,color = 'navy',lw = 2,label = 'original coefficients')
plt.legend()

總結:

​ 與分類同樣,迴歸是預測目標值的過程。迴歸與分類的不一樣在於迴歸預測的是連續型變量,而分類預測的是離散型的變量。迴歸是統計學中最有力的工具之一。若是給定輸入矩陣x,xTx的逆若是存在的話迴歸法能夠直接使用,迴歸方程中的求得特徵對應的最佳迴歸係數的方法是最小化偏差的平方和,判斷迴歸結果的好壞能夠利用預測值和真實值之間的相關性判斷。當數據樣本總個數少於特徵總數時,矩陣x,xTx的逆不能直接計算,這時能夠考慮嶺迴歸。

相關文章
相關標籤/搜索