1. 程式人生 > >線性迴歸-如何對資料進行迴歸分析

線性迴歸-如何對資料進行迴歸分析

> **公號:碼農充電站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