線性迴歸-如何對資料進行迴歸分析
阿新 • • 發佈:2020-12-21
> **公號:碼農充電站pro**
> **主頁:**
**線性迴歸模型**用於處理迴歸問題,也就是預測連續型數值。線性迴歸模型是最基礎的一種迴歸模型,理解起來也很容易,我們從**解方程組**談起。
### 1,解方程組
相信大家對**解方程**都不陌生,這是我們初中時期最熟悉的數學知識。
假如我們有以下方程組:
- 2x + y = 3 —— ①
- 5x - 2y = 7 —— ②
要解上面這個方程組,我們可以將第一個方程的等號兩邊都乘以2:
- 4x + 2y = 6 —— ③
再將第2 個方程與第3 個方程的等號兩邊分別相加:
- 9x = 13 —— ④
這樣我們就將**變數y 消去**了,就可以求解出**x** 的值。然後再將**x** 的值**代入**第1或第2個方程中,就可以解出**y** 的值。
以上這個解方程的過程就是**高斯消元法**。
### 2,線性迴歸模型
如果將上面方程組中的任意一個表示式單拿出來,那麼**x** 和 **y** 都是一種**線性**關係,比如:
- y = 3 - 2x
該表示式中,我們將**x** 叫做**自變數**,**y** 叫作**因變數**。
如果將其擴充套件到機器學習中,那麼**特徵集**就相當於**自變數X**,**目標集**就相當於**因變數Y**。
當自變數的個數大於1時,就是**多元迴歸**;當因變數的個數大於1 時,就是**多重回歸**。
**線性迴歸模型**的目的就是想找出一種**特徵集**與**目標集**之間的**線性關係**,使得我們可以通過已知的特徵資料預測出目標資料。
通常,我們的模型是通過多個特徵值來預測一個目標值,那麼線性迴歸模型的數學公式為:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219162507534.png)
其中:
- y 表示我們要預測的目標值。
- x1,x2...xn 代表每個特徵,一共有n 個特徵。
- b1,b2...bn 代表每個特徵的係數,特徵係數也代表了某個特徵對目標值的影響。
- b0 是一個常數,稱為截距。
- ε 表示模型的誤差,也被稱作損失函式。
線性迴歸模型與數學中的解方程不同,後者的結果是精確解,而前者則是一個近似解。因此在公式中存在一個 **ε** 。
我們的目標是求得一組使得 **ε** 最小的特徵係數(b1,b2...bn),當有了新的特徵時,就可以根據特徵係數求得預測值。
***迴歸一詞的來源***
**1875** 年,英國科學家**弗朗西·斯高爾頓**(達爾文的表弟)嘗試尋找父代身高與子代身高之間的關係。
在經過了**1078** 份資料的分析之後,最終他得出結論:人類的身高維持在相對穩定的狀態,他稱之為**迴歸效應**,並給出了歷史上第一個**迴歸**公式:
- `Y = 0.516X + 33.73`
公式中的 **Y** 代表子代身高,**X** 代表父代身高,單位為英寸。
### 3,線性擬合
線性擬閤中不存在精確解,但是存在最優解,也就是使得 **ε** 最小的解。
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219173255171.png?)
上圖中有3 個座標系:
- 在第1個圖中只有兩個點,這時候存在一條唯一的直線能夠同時穿過這兩個點,這條直線就是精確解。
- 當座標中的點多於兩個時,比如第2個圖,這時候就不可能存在一條直線,同時穿過這些點。但是會存在多條直線,會盡可能多的穿過更多的點,就像圖3。而這些直線中會有一條直線,是這些點的最好的**擬合**。
如何才能找到這條最好的擬合的直線呢?
### 4,最小二乘法
**最小二乘法**可以用來求解這個最優直線。
最小二乘法的主要思想是讓**真實值**與**預測值**之差(即誤差)的平方和達到最小。用公式表示如下:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219174127251.png)
上面的公式中:
- yi 是資料的真實值。
- y^ 是資料的預測值。
- ε 是我們要找的最小誤差,它是所有的**真實值與預測值之差的平方**的和。
方程組除了可以使用高斯消元法求解之外,還可以使用**矩陣**來求解。
將上面的 **ε** 公式寫成矩陣的形式就是:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020121917501890.png)
其中:
- B 為係數矩陣
- X 為特徵矩陣
- Y 為目標矩陣
我們的目標就是找到一個向量B,使得向量 XB 與 Y 之間**歐氏距離**的平方數最小。
經過一系列的推導之後,係數矩陣B 為:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219175505415.png)
其中:
- `X'` 是 `X` 的轉置矩陣。
- `(X'X)`-1 是`(X'X)` 的逆矩陣。
### 5,用 numpy 庫進行矩陣運算
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219202016672.png)
[NumPy](https://numpy.org/) 是一個使用Python 進行科學計算的軟體包,其中就實現了我們需要的矩陣運算:
- `x.transpose()`:矩陣x 的轉置運算。
- `x.dot(y)`:矩陣x 點乘矩陣y。
- `x.I`:返回可逆矩陣x 的逆矩陣。
那麼根據公式:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219175505415.png)
我們可以編寫求B 的函式:
```python
def get_B(X, Y):
_X = X.transpose()
B = (_X.dot(X)).I.dot(_X).dot(Y)
return B
```
假設我們有以下資料集,要對該資料集進行線性擬合:
| 特徵x1 | 特徵x2 | 目標y|
|--|--|--|
| 0 | 1 | 1.4 |
| 1 | -1 | -0.48 |
| 2 | 8 | 13.2 |
我們知道線性迴歸的公式為:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219162507534.png)
那麼上面表格的資料轉化為方程組:
- b0 + b1**⋅0** + b2**⋅1** = 1.4
- b0 + b1**⋅1** - b2**⋅1** = −0.48
- b0 + b1**⋅2** + b2**⋅8** = 13.2
那麼矩陣**X** 為:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201219203922435.png?)
轉化為程式碼如下:
```python
from numpy import *
X = mat([
[1,0,1],
[1,1,-1],
[1,2,8]
])
Y = mat([[1.4],[-0.48],[13.2]])
```
計算係數矩陣B:
```python
> >> get_B(X, Y)
matrix([[-0.01454545], # b0
[ 0.94909091], # b1
[ 1.41454545]]) # b2
```
這樣就得出了各個係數項,我們可以用這些係數項進行資料預測。
### 6,sklearn 對線性迴歸的實現
**sklearn** 庫中的 [LinearRegression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html) 類是對線性迴歸的實現。
**LinearRegression** 類的原型:
```python
LinearRegression(
fit_intercept=True,
normalize=False,
copy_X=True,
n_jobs=None)
```
來看下其引數的含義:
- **fit_intercept**:擬合模型時,是否存在截距`b0`,預設為`True`,即存在。
- **normalize**:在擬合模型之前,是否要對特徵集進行標準化處理。
- 當 **fit_intercept** 為 `False` 時,該引數被忽略。
- **copy_X**:是否複製特徵集`X`。
- **n_jobs**:用於計算的作業數,只對多重回歸且比較複雜的資料進行加速。
接下來,使用 **LinearRegression** 類對上面表格資料進行擬合。(為了方便檢視,我將表格放在這裡)
| 特徵x1 | 特徵x2 | 目標y|
|--|--|--|
| 0 | 1 | 1.4 |
| 1 | -1 | -0.48 |
| 2 | 8 | 13.2 |
將該表格資料轉化成 **Python** 變數,如下:
```python
X = [(0, 1), [1, -1], [2, 8]]
Y = [1.4, -0.48, 13.2]
```
建立線性迴歸物件:
```python
from sklearn.linear_model import LinearRegression
reg = LinearRegression() # 均使用預設引數
```
擬合數據:
```python
reg.fit(X, Y)
```
`coef_` 屬性是特徵係數列表:
```python
>>> reg.coef_
array([0.94909091, 1.41454545])
```
`intercept_` 屬性是截距 `b0` 的值:
```python
>>> reg.intercept_
-0.014545454545452863
```
通過`coef_` 和`intercept_` 屬性可以看到,使用 **LinearRegression** 類和使用 **NumPy** 得到的結果是一樣的。
需要注意的是,只有當資料集的特徵集與目標集是**線性關係**時,才能使用線性迴歸擬合出一個不錯的結果。如果不是線性關係,則擬合結果一般不會很好。
對於**非線性關係的**迴歸問題,可以使用[樹迴歸](https://scikit-learn.org/stable/modules/tree.html#regression)等其它模型。
那如何判斷特徵集與目標集是否是線性關係呢?有兩個指標:
- **決定係數 R2**:該指標使用了迴歸平方和與總平方和之比,是反映模型擬合度的重要指標。
- 它的取值在 0 到 1 之間,越接近於 1 表示擬合的程度越好、資料分佈越接近線性關係。
- **校正的決定係數 Rc2**:如果特徵非常多,那麼Rc2 指標將更加可靠。
**LinearRegression** 類中的 `score` 方法就是**R2 指標**的實現:
```python
>>> reg.score(X, Y)
1.0 # 結果是 1,說明特徵集與目標集是非常好的線性關係。
```
### 7,對波士頓房價進行線性分析
對於[波士頓房價資料集](https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/datasets/data/boston_house_prices.csv),之前的文章中,已經多次使用過,這次我們對其使用**線性迴歸模型**進行分析。
首先載入資料:
```python
from sklearn.datasets import load_boston
boston = load_boston()
features = boston.data # 特徵集
prices = boston.target # 目標集
```
建立線性迴歸物件:
```python
from sklearn.linear_model import LinearRegression
# 在擬合之前對資料進行標準化處理
reg = LinearRegression(normalize=True)
```
擬合數據:
```python
reg.fit(features, prices)
```
對模型進行評分:
```python
>>> reg.score(features, prices)
0.7406426641094095
```
通過評分可知,最終的準確率為**74.1%**,雖談不上很高,但也還說得過去。
### 8,總結
使用**最小二乘法**訓練出的[線性迴歸模型](https://scikit-learn.org/stable/modules/linear_model.html#ordinary-least-squares)是最簡單基礎的一種線性模型,只有當特徵集與目標集呈**線性關係**時,它才能擬合出比較好的結果。
在它的基礎之上,還有很多改進版的線性模型,比如:區域性加權線性迴歸,[嶺迴歸](https://scikit-learn.org/stable/modules/linear_model.html#ridge-regression-and-classification),[lasso](https://scikit-learn.org/stable/modules/linear_model.html#lasso) 等,你可以在 [Sklearn Linear Models](https://scikit-learn.org/stable/modules/linear_model.html) 進一步瞭解和學習。
(本節完。)
---
**推薦閱讀:**
[AdaBoost 演算法-分析波士頓房價資料集](https://www.cnblogs.com/codeshell/p/14149923.html)
[EM 演算法-對鳶尾花資料進行聚類](https://www.cnblogs.com/codeshell/p/14132408.html)
[Apriori 演算法-如何進行關聯規則挖掘](https://www.cnblogs.com/codeshell/p/14113600.html)
[PageRank 演算法-Google 如何給網頁排名](https://www.cnblogs.com/codeshell/p/14106948.html)
[K 均值演算法-如何讓資料自動分組](https://www.cnblogs.com/codeshell/p/14084190.html)
---
*歡迎關注作者公眾號,獲取更多技術乾貨。*
![碼農充電站pro](https://img-blog.csdnimg.cn/20200505082843773.png?#pic