使用statsmodels實現線性迴歸

statsmodels簡介

Statsmodels 是 Python 中一個強大的統計分析包,包含了迴歸分析、時間序列分析、假設檢
驗等等的功能。Statsmodels 在計量的簡便性上是遠遠不及 Stata 等軟件的,但它的優點在於可以與 Python 的其他的任務(如 NumPy、Pandas)有效結合,提高工作效率。在此,重點介紹最迴歸分析中最常用的 OLS(ordinary least square)功能。

當你需要在 Python 中進行迴歸分析時……
import statsmodels.api as sm!!!

關於統計模型

statsmodels是一個Python軟件包,爲scipy提供了補充,以進行統計計算,包括描述性統計以及統計模型的估計和推斷。

statsmodels主要包括如下子模塊:

迴歸模型:線性迴歸,廣義線性模型,穩健的線性模型,線性混合效應模型等等。

方差分析(ANOVA)。

時間序列分析:AR,ARMA,ARIMA,VAR和其它模型。

非參數方法: 核密度估計,核迴歸。

統計模型結果可視化。

比較:statsmodels更關注統計推斷,提供不確定估計和參數p-value。相反的,scikit-learn注重預測。

主要特點

線性迴歸模型:

普通最小二乘法
廣義最小二乘法
加權最小二乘法
具有自迴歸誤差的最小二乘
分位數迴歸
遞歸最小二乘法

具有混合效應和方差成分的混合線性模型
GLM:支持所有單參數指數族分佈的廣義線性模型
用於二項式和泊松的貝葉斯混合GLM
GEE:單向聚類或縱向數據的廣義估計方程

離散模型:

Logit 和 Probit
多項 logit (MNLogit)
泊松和廣義泊松迴歸
負二項式迴歸
零膨脹計數模型

RLM: 魯棒的線性模型,支持多個 M 估計器。

時間序列分析:時間序列分析模型
完整的StateSpace建模框架
季節性ARIMA和ARIMAX模型
VARMA和VARMAX模型
動態因子模型
未觀測到的組件模型

馬爾可夫切換模型(MSAR),也稱爲隱馬爾可夫模型(HMM)

單變量時間序列分析:AR,ARIMA
矢量自迴歸模型,VAR和結構VAR
矢量誤差修正模型,VECM
指數平滑,Holt-Winters
時間序列的假設檢驗:單位根,協整和其他
用於時間序列分析的描述性統計數據和過程模型

生存分析:

比例風險迴歸(Cox模型)
生存者函數估計(Kaplan-Meier)
累積發生率函數估計

多變量:

缺失數據的主成分分析
旋轉因子分析
MANOVA
典型相關

非參數統計:單變量和多變量核密度估計

數據集:用於示例和測試的數據集
統計:廣泛的統計檢驗
診斷和規格檢驗
擬合優度和正態性檢驗
多元測試函數
各種其他統計檢驗

其他模型

Sandbox:statsmodels包含一個 sandbox 文件夾,其中包含處於開發和測試各個階段的代碼, 因此不被視爲“生產就緒”。其中包括:
廣義矩法(GMM)估計器
核迴歸
scipy.stats.distributions的各種擴展
面板數據模型
信息理論測度

什麼是線性迴歸?

線性迴歸是利用數理統計中迴歸分析,來確定兩種或兩種以上變量間相互依賴的定量關係的一種統計分析方法。

在迴歸術語中,我們將被預測的變量稱爲因變量(dependent variable),用y表示。把用來預測應變量值的一個或多個變量稱爲自變量(predictor variable/independent variable),用x表示。

簡單線性迴歸案例

數據集說明

本文用於分析的樣本數據集手動定義,有利於結果一目瞭然,特別容易理解。

導入需要的工具包


import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("darkgrid")
import pandas as pd

如果電腦上面沒有安裝這些包,直接下載速度過慢,可以選擇在國內的網站上面下載安裝。

pip install statsmodels -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip install matplotlib -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip install seaborn -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip install pandas -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 

使用pandas生成數據

自定義的數據,可任意修改。注意:列名中,相當於把“a”列作爲主鍵,讓兩個數據集可以關聯起來。

a = pd.DataFrame([[1,2,20,4,5],
                  [2,3,21.2,34,45],
                  [3,4,22.1,34,45],
                  [4,5,22.9,34,45],
                  [5,6,24.1,34,46]],index=['1','2','3','4','5'],columns=list('aBCDE'))
print(a)
b = pd.DataFrame([[1,22,33,44,55],
                  [2, 'b42', 'b43', 'b44', 65.1],
                  [3, 'b42', 'b43', 'b44', 75.3],
                  [4, 'b42', 'b43', 'b44', 85],
                  [5, 'b52', 'b53', 'b54', 95.8]],index=list('12345'),columns=list('abcde'))
print(b)

輸出結果(瞭解數據樣式):
在這裏插入圖片描述

數據整理

我們現在已經成功生成了數據,使用Pandas的merge函數,將多個表格合併爲一張總表格,以便數據分析。

#相當於sql中的join on 連接數據
df = a.merge(b,on="a")
#顯示前十行數據,因爲只有五條,所以相當於把數據全部顯示
print(df.head(10))
df.to_csv("./df.csv")

輸出結果(瞭解數據樣式):
在這裏插入圖片描述

迴歸模型

簡單線性迴歸使用一個自變量來預測一個因變量,二者之間的關係可以用一條直線近似表示。

簡單線性迴歸模型: y = a + bx +c

其中:

y = 因變量

b = 迴歸係數

a = 截距 (自變量爲0時,因變量房價的平均值/期望)

x = 用於預測y的自變量

c = 隨機變量,稱爲模型誤差項,說明在y裏面但不能被x和y之間線性關係解釋的變異性

建模

我們將使用statsmodels中ols功能,構建B同e之間的模型。

Statsmodels是一個很強大的Python庫,用於擬合多種統計模型,執行統計測試以及數據探索和可視化。

對於線性迴歸linear regression,我們可以使用Statsmodels庫中最小二乘法OLS(Ordinary-Least-Square)的功能來實現,可以得到豐富的數據信息。

model = ols("B ~ e",data=df).fit()
model_summary = model.summary()

print(model_summary)

結果:
在這裏插入圖片描述
1) 修正判定系統Adj.R-squared:100.00%。自定義數據指數變異性的100.00%能被其與“a”列數據之間的線性關係解釋。

2)迴歸係數:0.0985。代表c列數值增加1個單位,a列數值將增加0.0985。和我們自定義的數據是符合的,差不多“e”列數據步長差不多是“a”列的10倍。

3)迴歸係數的標準誤差stand error:0.001,即b的估計的標準差。通過不同的數據,可以計算得到迴歸系統的標準誤差。迴歸係數標準誤差,是量度結果精密度的指標。這裏計算得出的標準誤差爲0.001,數值非常小,說明精確度是相當高的。
如果自定義數據比較離散,這個值會增大。

4)p>|t| 值爲0%。根據簡單線性迴歸顯著性的t檢驗,原假設“a”列與“e”列之間不存在線性關係,b爲0。
而現在p值爲0%,小於顯著性水平0.05。所以拒絕原假設,b顯著不等於0。我們足以斷定,“a”列與“e”列之間存在一個顯著的關係。

5)b的95%的置信區間:0.096 ~ 0.101。我們有95%的信心,迴歸係數b將落在置信區間 [0.096,0.101]中。換個角度來講,簡單線性迴歸顯著性的t檢驗,假設b爲0,而b=0並沒有包含在上述置信區間內,所以我們可以拒絕原假設,斷定“a”列與“e”列之間存在一個顯著的關係。

關於自變量的線性迴歸圖像

fig = plt.figure(figsize=(15,8))
fig = sm.graphics.plot_regress_exog(model,"e",fig=fig)
plt.show()
#也可以把圖片保存到本地,使用下面方法
#fig.savefig('./test.jpg', dpi=300)

圖片顯示如下:
在這裏插入圖片描述
圖像說明:

1)左上一圖 “Y and Fitted vs. X” ,刻畫了“a”列與“e”列同線性迴歸模型擬合的估計值之間的差距。同時,可以發現二者是正相關的,斜率β爲負。

2)右上一圖 “Residuals versus e”爲 關於自變量“e”的殘差圖。橫座標爲自變量“e”的值,縱軸表示自變量對應的殘差值,也就是左上一圖中藍圓點同橘色菱形間的距離差。
殘差圖是用來評價迴歸模型假定有效性的一種方法。通過這張殘差圖,總體印象爲所有的散點都在±0.04範圍的水平帶中間,我們有信心做出結論,簡單線性迴歸模型是合理的。 (殘差圖,直線上下的點分佈均勻且都在之間附近,效果越好)

3)左下一圖“Partial regression plot”偏回歸圖像顯示考慮新增其他自變量時,“a”列與“e”列之間的關係。 在多元線性迴歸當中,可以增加更多的自變量後同樣的圖像將產生怎樣的變化。

4)右下二圖“ (CCPR Plot)”圖像是偏回歸圖像的拓展,反映了考慮新增其他自變量後反應兩者關係的直線將如何變化。
現在這個是加了一個新變量c且值爲3。可以理解線性迴歸模型變成下面這樣:
簡單線性迴歸模型: y = a + bx + 3

置信區間

下面我們做圖畫出擬合線(綠色標記),樣本數據中的觀測值(藍色圓點),置信區間(紅色標記)。

# x爲自變量,y爲因變量
# 注意單個方括號爲series,兩個方括號爲dataframe
x=df[["e"]]
y=df[["B"]]

xxx,lower,upper = wls_prediction_std(model)
fig,ax = plt.subplots(figsize=(10,7))
ax.plot(x,y,'o',label="a")
ax.plot(x,model.fittedvalues,"g--",label="OLS")
ax.plot(x,upper,"r--")
ax.plot(x,lower,"r--")
ax.legend(loc="best")
plt.show()

結果如下如:
在這裏插入圖片描述

完整代碼

不想敲代碼的,直接複製下面

import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("darkgrid")
import pandas as pd

# a = pd.DataFrame(np.random.randn(4,5),index=[1,2,3,4 ],columns=list('abcde'))
a = pd.DataFrame([[1,2,20,4,5],
                  [2,3,21.2,34,45],
                  [3,4,22.1,34,45],
                  [4,5,22.9,34,45],
                  [5,6,24.1,34,46]],index=['1','2','3','4','5'],columns=list('aBCDE'))
print(a)
# b = pd.DataFrame({"a":pd.Series(np.random.randn(4),index=['b','c','d','e']),
#                   "two":pd.Series(np.random.randn(2),index=['b','c']),
#                   "three":pd.Series(np.random.randn(3),index=['b','c','d'])})
b = pd.DataFrame([[1,22,33,44,55],
                  [2, 'b42', 'b43', 'b44', 65.1],
                  [3, 'b42', 'b43', 'b44', 75.3],
                  [4, 'b42', 'b43', 'b44', 85],
                  [5, 'b52', 'b53', 'b54', 95.8]],index=list('12345'),columns=list('abcde'))
print(b)
#相當於sql中的join on 連接數據
df = a.merge(b,on="a")
print(df.head(10))
df.to_csv("./df.csv")
# df.info()

model = ols("B ~ e",data=df).fit()
model_summary = model.summary()

print(model_summary)

fig = plt.figure(figsize=(15,8))
fig = sm.graphics.plot_regress_exog(model,"e",fig=fig)
plt.show()

# x爲自變量,y爲因變量
# 注意單個方括號爲series,兩個方括號爲dataframe
x=df[["e"]]
y=df[["B"]]

xxx,lower,upper = wls_prediction_std(model)
fig,ax = plt.subplots(figsize=(10,7))
ax.plot(x,y,'o',label="a")
ax.plot(x,model.fittedvalues,"g--",label="OLS")
ax.plot(x,upper,"r--")
ax.plot(x,lower,"r--")
ax.legend(loc="best")
plt.show()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章