Hike News
Hike News

機器學習-線性回歸分析(linear regression)

Introduction

  • 數據集的目標值(target)是一個連續型的值,便是一個回歸問題
  • 回歸問題應用於房價分析、銷售額預測、貸款額度
  • 回歸:在具有線性關係的點中,尋找一種能預測的趨勢
  • 回歸演算法為迭代演算法(訓練結果會使預測結果越來越好)
    • 訓練時會產生誤差且知道誤差,在訓練的過程中不斷地減少誤差

線性關係模型

一個通過屬性的線性組合來進行預測的函數:

$$
f(x) = w_1x_1 + w_2x_2 + … + w_dx_d + b
$$

  • w 為權重
  • b 稱為偏置項(截距),可以理解為:$w_0 \times 1$

線性回歸(linear regression)

線性回歸通過一個或者多個自變量(特徵)因變量(目標值) 之間進行建模的回歸分析,
其中可以為一個或多個 自變量(特徵)權重線性組合

  • 一元線性回歸:涉及到的變量只有一個
  • 多元線性回歸:涉及到的變量有兩個或兩個以上

公式

$$
h(w) = w_0 + w_1x_1 + w_2x_2 + … = w^Tx
$$

  • 其中w,x皆為一維矩陣:
    $$
    w = \begin{bmatrix} w_0 \ w_1 \ w_2 \ \end{bmatrix}
    $$

$$
x = \begin{bmatrix} 1 \ x_1 \ x_2 \ \end{bmatrix}
$$

損失函數(誤差大小, cost function)

在回歸演算法中都是會有屬於自己的cost function

定義:(又稱最小二乘法,對誤差求平方和)

$$
J(\theta) = (h_w(x_1) - y_1)^2 + (h_w(x_2) - y_2)^2 + … + (h_w(x_m)-y_m)^2
$$

$$
= \sum_{i=1}^m (h_w (x_i) - y_i)^2
$$

  • $y_i$為第$i$個訓練樣本的真實值
  • $h_w(x_i)$為第$i$個訓練樣本特徵值組合預測結果
  • 損失越少越好

優化

迭代(學習)的過程就是優化w權重的過程;求模型中的w值,使得損失為最小

正規方程

可直接求cost function的最小值,但較不適用於樣本非常多的情況

$$
w = (X^{T}X)^{-1}X^{T}y
$$

  • X 為特徵值矩陣
  • y 為目標值矩陣
  • 當特徵過於複雜,求解速度慢

梯度下降(Gradient descent)

Gradient descent

沿著這個函數下降的方向找,最後能找到山谷的最低點,每次跨出一步都會更新w值

  • 通常使用在面對訓練數據規模十分龐大的任務

以單變量中的w1,w0作為例子

$$
w_1 := -w_1 - \alpha \frac{\partial}{\partial w_1} J(w_0,w_1)
$$

$$
w_0 := -w_0 - \alpha \frac{\partial}{\partial w_1} J(w_0,w_1)
$$

  • $\alpha$:為學習速率,需要手動指定
  • $\alpha$後面的計算結果為梯度下降的方向
  • w值在訓練的過程中會不斷地更新,使得cost function越來越小

回歸性能評估

通常使用均方誤差(Mean Squared Error,MSE)評價機制
$$
MSE = \frac{1}{m} \sum_{i=1}^{m} (y^i - \widetilde{y})^2
$$

  • $y^i$為預測值
  • $\widetilde{y}$為真實值

sklearn中正規方程與梯度下降API

  • 正規方程使用sklearn.linear_model.LinearRegression
    • 可通過coef_屬性查看最後w值(權重);回歸係數
  • 梯度下降使用sklearn.linear_model.SGDRegressor
    • 可通過coef_屬性查看最後w值(權重);回歸係數
    • sklearn中已將學習率$\alpha$封裝,因此不需指定學習率
  • 使用線性回歸model時數據需經過標準化處理
    • 深怕某個特徵值特別大而影響目標值
    • 特徵值(x)須標準化處理
    • 目標值(y)是否標準化處理看需求

回歸性能評估

計算均方誤差使用sklearn.metrics.mean_squared_error(y_true, y_pred)

  • 計算均方誤差回歸損失
  • y_true: 真實值
  • y_pred: 預測值
  • return: float類型數值,越小越好
  • 注意:真實值與預測值均為標準化之前的值

Example LinearRegression

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

# 獲取數據
boston = load_boston()

def LinearRegression_test():
#分割訓練集及測試集
X_train,X_test,y_train,y_test = train_test_split(boston.data,boston.target,test_size=0.25)

#數據標準化處理
X_Stdscaler = StandardScaler()
X_train = X_Stdscaler.fit_transform(X_train)
X_test = X_Stdscaler.transform(X_test)

y_Stdscaler = StandardScaler()
y_train = y_Stdscaler.fit_transform(y_train.reshape(-1,1))

# estimatorm預測
LR = LinearRegression()
LR.fit(X_train,y_train)
print("w權重:\n", LR.coef_)

y_predict = LR.predict(X_test)
y_predict = y_Stdscaler.inverse_transform(y_predict)
print("預測的房價:\n",y_predict.reshape(1,-1))

# MeanSquaredError
print("均方誤差為:",mean_squared_error(y_test,y_predict))

if __name__ == '__main__':
LinearRegression_test()
  • sklearn中的任何transformer或是estimator用來fit或是transform的數據必須是一個二維的陣列,因此需要reshape

Result

1
2
3
4
5
6
7
8
9
10
11
12
w權重:
[[-0.10758616 0.06812624 0.07253587 0.07240224 -0.21829879 0.33539411
-0.03115752 -0.29252316 0.27082133 -0.21269287 -0.24595448 0.09319976
-0.39137572]]
預測的房價:
[[27.19703402 -0.3840721 20.25271244 26.82856768 18.68858977 12.58656872
24.88169586 20.35108225 17.49560551 33.10084889 34.46248469 24.78596238
...
...
16.91419754 22.38796794 10.94529887 12.72310632 22.87812591 18.91468558
22.79921829]]
均方誤差為: 25.70783805560611
  • 數據較簡單的情況下建議就直接使用LinearRegression

Example GradientDescent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.linear_model import SGDRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

boston = load_boston()

def SGD_test():
X_train,X_test,y_train,y_test = train_test_split(boston.data,boston.target,test_size=0.25)

X_Stdscaler = StandardScaler()
X_train = X_Stdscaler.fit_transform(X_train)
X_test = X_Stdscaler.transform(X_test)

SGD = SGDRegressor()
SGD.fit(X_train,y_train)
print("w權重:\n", SGD.coef_)

y_predict = SGD.predict(X_test)
print("預測的房價:\n",y_predict)

print("均方誤差為:",mean_squared_error(y_test,y_predict))
  • SGDRegressor的參數learning_rate不是一個具體的數值,內部已經有封裝,詳情請看文檔

Result

1
2
3
4
5
6
7
8
9
10
11
12
w權重:
[-0.68801761 0.33828819 -0.32654615 1.09123264 -0.59907588 3.12320933
-0.24405887 -1.86075997 0.74936682 -0.24540297 -1.89584165 1.14755048
-3.55851847]
預測的房價:
[13.59250283 21.1141011 13.46418833 12.12910793 32.15773134 30.42992058
37.16422439 15.07917749 19.87894082 19.6978997 30.42347672 22.04216396
...
...
36.10743071 19.64863248 29.92243733 19.50016195 23.00034865 11.65818568
33.69281417]
均方誤差為: 18.33685522657918
  • 數據量較大的情況下通常用梯度下降

tips

梯度下降(GradientDescent) 正規方程(LinearRegression)
需要選擇學習速率$\alpha$ 不需要
需要多次迭代(學習)過程 一次運算可得出結果
當特徵數量非常多時也能適用 需要計算$(X^{T}X)^{-1}$,如果特徵數量大時,運算代價較大
適用於各種類型模型(為一種通用的求解方式) 只適用於線性模型,不適合邏輯回歸模型等其他模型
  • LinearRegression 不能解決過擬合、欠擬合等問題