一 線性回歸(Linear Regression )
1. 線性回歸概述
回歸的目的是預測數值型數據的目標值,最直接的方法就是根據輸入寫出一個求出目標值的計算公式,也就是所謂的回歸方程,例如y = ax1+bx2,其中求回歸系數的過程就是回歸。那么回歸是如何預測的呢?當有了這些回歸系數,給定輸入,具體的做法就是將回歸系數與輸入相乘,再將結果加起來就是最終的預測值。說到回歸,一般指的都是線性回歸,當然也存在非線性回歸,在此不做討論。
假定輸入數據存在矩陣x中,而回歸系數存放在向量w中。那么對於給定的數據x1,預測結果可以通過y1 = x1Tw給出,那么問題就是來尋找回歸系數。一個最常用的方法就是尋找誤差最小的w,誤差可以用預測的y值和真實的y值的差值表示,由於正負差值的差異,可以選用平方誤差,也就是對預測的y值和真實的y值的平方求和,用矩陣可表示為:
現在問題就轉換為尋找使得上述矩陣值最小的w,對w求導為:xT(y - xw),令其為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
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為每個數據點賦予的權重,那么怎樣求權重呢,核函數可以看成是求解點與點之間的相似度,在此可以采用核函數,相應的根據預測點與附近點之間的相似程度賦予一定的權重,在此選用最常用的高斯核,則權重可以表示為:
其中K為寬度參數,至於此參數的取值,目前仍沒有一個確切的標准,只有一個范圍的描述,所以在算法的應用中,可以采用不同的取值分別調試,進而選取最好的結果。
三 嶺回歸
1.概述
為了解決上述問題,統計學家引入了“嶺回歸”的概念。簡單說來,嶺回歸就是在矩陣XTX上加上一個λr,從而使得矩陣非奇異,從而能對XTX + λx求逆。其中矩陣r為一個m*m的單位矩陣,對角線上的元素全為1,其他元素全為0,而λ是一個用戶定義的數值,這種情況下,回歸系數的計算公式將變為:
其中I是一個單位矩陣。
嶺回歸就是用了單位矩陣乘以常量λ,因為只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增加一個限定條件,能達到和回歸一樣的效果:
當λ足夠小時,一些影響較弱的系數會因此被迫縮減到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的逆不能直接計算,這時可以考慮嶺回歸。
