https://blog.csdn.net/robert_chen1988/article/details/103551261
使用 python 做線性回歸分析有好幾種方式,常要的分別是 scipy 包,statsmodels 包,以及 sklearn 包。但是,這些包目前都不能處理共線性,即自動剔除部分共線性的變量,需要自己去編函數,這一點不如 spss 或 r 語言。
假設有下面的數據存儲在 excel 文件里面:
不良貸款 | 各項貸款余額 | 本年累計應收貸款 | 貸款項目個數 | 本年固定資產投資額 |
---|---|---|---|---|
0.9 | 67.3 | 6.8 | 5 | 51.9 |
1.1 | 111.3 | 19.8 | 16 | 90.9 |
4.8 | 173.0 | 7.7 | 17 | 73.7 |
3.2 | 80.8 | 7.2 | 10 | 14.5 |
7.8 | 199.7 | 16.5 | 19 | 63.2 |
2.7 | 16.2 | 2.2 | 1 | 2.2 |
1.6 | 107.4 | 10.7 | 17 | 20.2 |
12.5 | 185.4 | 27.1 | 18 | 43.8 |
1.0 | 96.1 | 1.7 | 10 | 55.9 |
2.6 | 72.8 | 9.1 | 14 | 64.3 |
0.3 | 64.2 | 2.1 | 11 | 42.7 |
4.0 | 132.2 | 11.2 | 23 | 76.7 |
0.8 | 58.6 | 6.0 | 14 | 22.8 |
3.5 | 174.6 | 12.7 | 26 | 117.1 |
10.2 | 263.5 | 15.6 | 34 | 146.7 |
3.0 | 79.3 | 8.9 | 15 | 29.9 |
0.2 | 14.8 | 0.6 | 2 | 42.1 |
0.4 | 73.5 | 5.9 | 11 | 25.3 |
1.0 | 24.7 | 5.0 | 4 | 13.4 |
6.8 | 139.4 | 7.2 | 28 | 64.3 |
11.6 | 368.2 | 16.8 | 32 | 163.9 |
1.6 | 95.7 | 3.8 | 10 | 44.5 |
1.2 | 109.6 | 10.3 | 14 | 67.9 |
7.2 | 196.2 | 15.8 | 16 | 39.7 |
3.2 | 102.2 | 12.0 | 10 | 97.1 |
首先使用 pandas 讀取 excel 數據:
import pandas as pd # 讀取 excel 數據,引號里面是 excel 文件在電腦的存儲位置 datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx')
- 1
- 2
- 3
- 4
1. 用 scipy 包
scipy.stats 中的 linregress 函數可以做一元線性回歸。假如因變量為 “不良貸款”,自變量為 “各項貸款余額”,全部 python 代碼如下:
import scipy.stats as st import pandas as pd datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2] # 自變量為第 3 列數據 # 線性擬合,可以返回斜率,截距,r 值,p 值,標准誤差 slope, intercept, r_value, p_value, std_err = st.linregress(x, y) print(slope)# 輸出斜率 print(intercept) # 輸出截距 print(r_value**2) # 輸出 r^2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
scipy 中的回歸分析比較簡單,目前只能做一元線性回歸,也不能用來做預測。
2. 用 statsmodels 包
import pandas as pd import statsmodels.api as sm import matplotlib.pyplot as plt datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2] # 自變量為第 3 列數據 x = sm.add_constant(x) # 若模型中有截距,必須有這一步 model = sm.OLS(y, x).fit() # 構建最小二乘模型並擬合 print(model.summary()) # 輸出回歸結果 # 畫圖 # 這兩行代碼在畫圖時添加中文必須用 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False predicts = model.predict() # 模型的預測值 x = datas.iloc[:, 2] # 自變量為第 3 列數據 plt.scatter(x, y, label='實際值') # 散點圖 plt.plot(x, predicts, color = 'red', label='預測值') plt.legend() # 顯示圖例,即每條線對應 label 中的內容 plt.show() # 顯示圖形
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
統計結果如下:
畫出的實際值與預測值如下圖:
注意:若導入包時使用命令 import statsmodels.formula.api as sm, 則在回歸分析時不用添加截距 add_constant,但是必須使用統計語言給出模型信息,代碼如下:
import pandas as pd import statsmodels.formula.api as sm import matplotlib.pyplot as plt datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 model = sm.ols('不良貸款~各項貸款余額', datas).fit() # 構建最小二乘模型並擬合, #此時不用單獨輸入 x,y了,而是將自變量與因變量用統計語言公式表示,將全部數據導入 print(model.summary()) # 輸出回歸結果 # 畫圖 # 這兩行代碼在畫圖時添加中文必須用 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False predicts = model.predict() # 模型的預測值 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2] # 自變量為第 3 列數據 plt.scatter(x, y, label='實際值') plt.plot(x, predicts, color = 'red', label='預測值') plt.legend() # 顯示圖例,即每條線對應 label 中的內容 plt.show() # 顯示圖形
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
在多元回歸中,只需把自變量改為多列數據即可,假如不良貸款為因變量,從第3列到第6列都是因變量,則使用 statsmodels 包的全部 python 代碼如下:
import pandas as pd import statsmodels.api as sm import matplotlib.pyplot as plt datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2:6] # 自變量為第 3 列到第 6 列數據 x = sm.add_constant(x) # 若模型中有截距,必須有這一步 model = sm.OLS(y, x).fit() # 構建最小二乘模型並擬合 print(model.summary()) # 輸出回歸結果
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
回歸結果:
3. 用 sklearn 包
sklearn 包機器學習中常見的 python 包,可以用來做統計分析時,但它並不能像 statsmodels 那樣生成非常詳細的統計分析結果。一元回歸時,自變量與因變量都需要處理下,對於上面同樣的例子:
import pandas as pd import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import LinearRegression datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2] # 自變量為第 3 列數據 # 將 x,y 分別增加一個軸,以滿足 sklearn 中回歸模型認可的數據 x = x[:, np.newaxis] y = y[:, np.newaxis] model = LinearRegression() # 構建線性模型 model.fit(x, y) # 自變量在前,因變量在后 predicts = model.predict(x) # 預測值 R2 = model.score(x, y) # 擬合程度 R2 print('R2 = %.2f' % R2) # 輸出 R2 coef = model.coef_ # 斜率 intercept = model.intercept_ # 截距 print(model.coef_, model.intercept_) # 輸出斜率和截距 # 畫圖 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2] # 自變量為第 3 列數據 plt.scatter(x, y, label='實際值') # 散點圖 plt.plot(x, predicts, color = 'red', label='預測值') plt.legend() # 顯示圖例,即每條線對應 label 中的內容 plt.show() # 顯示圖形
- 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
用 sklearn 做多元回歸時,自變量不需要單獨處理了,全部代碼如下:
import pandas as pd import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import LinearRegression datas = pd.read_excel(r'D:\Users\chen_\git\Statistics-book\datas\linear_regression.xlsx') # 讀取 excel 數據,引號里面是 excel 文件的位置 y = datas.iloc[:, 1] # 因變量為第 2 列數據 x = datas.iloc[:, 2:6] # 自變量為第 3 列到第 6 列數據 # 將 y 分別增加一個軸,以滿足 sklearn 中回歸模型認可的數據 # 此時由於 x 是多元變量,則不用添加新的軸了 y = y[:, np.newaxis] model = LinearRegression() # 構建線性模型 model.fit(x, y) # 自變量在前,因變量在后 predicts = model.predict(x) # 預測值 R2 = model.score(x, y) # 擬合程度 R2 print('R2 = %.3f' % R2) # 輸出 R2 coef = model.coef_ # 斜率 intercept = model.intercept_ # 截距 print(model.coef_, model.intercept_) # 輸出斜率和截距