Statsmodels简单使用

Statsmodels是用于探索数据、估计模型,并运行统计检验的Python包。在这里,让我们使用它来构建一个简单的线性回归模型,为setosa类中花萼长度和花萼宽度之间的关系进行建模。

首先,通过散点图来目测这两者的关系。

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.font_manager import *

#定义自定义字体
myfont = FontProperties(fname='/temp/msyh.ttf')

df = pd.read_csv("/temp/iris.data",names=['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度', '类别'])

fig, ax = plt.subplots(figsize=(7,7))

ax.scatter(df['花萼宽度'][:50], df['花萼长度'][:50])

ax.set_ylabel(u'花萼长度',fontproperties=myfont)

ax.set_xlabel(u'花萼宽度',fontproperties=myfont)

ax.set_title(u'花萼长度 花萼宽度', fontproperties=myfont,fontsize=14, y=1.02)

plt.show()

我们可以看到,似乎有一个正向的线性关系,也就是说,随着花萼宽度的增加,花萼长度也会增加。接下来我们使用statsmodels,在这个数据集上运行一个线性回归模型,来预估这种关系的强度。

import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
from matplotlib.font_manager import *

#定义自定义字体
myfont = FontProperties(fname='/temp/msyh.ttf')

df = pd.read_csv("/temp/iris.data",names=['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度', '类别'])




y = df['花萼长度'][:50]

x = df['花萼宽度'][:50]

X = sm.add_constant(x)

results = sm.OLS(y, X).fit()

print(results.summary())

输出

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   花萼长度   R-squared:                       0.558
Model:                            OLS   Adj. R-squared:                  0.548
Method:                 Least Squares   F-statistic:                     60.52
Date:                Fri, 08 Sep 2017   Prob (F-statistic):           4.75e-10
Time:                        17:21:06   Log-Likelihood:                 2.0879
No. Observations:                  50   AIC:                           -0.1759
Df Residuals:                      48   BIC:                             3.648
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const          2.6447      0.305      8.660      0.000       2.031       3.259
花萼宽度           0.6909      0.089      7.779      0.000       0.512       0.869
==============================================================================
Omnibus:                        0.252   Durbin-Watson:                   2.517
Prob(Omnibus):                  0.882   Jarque-Bera (JB):                0.436
Skew:                          -0.110   Prob(JB):                        0.804
Kurtosis:                       2.599   Cond. No.                         34.0
==============================================================================

由于这是一个线性回归,该模型的格式为Y = Β0+Β1X,其中B0为截距而B1是回归系数。在这里,最终公式是花萼长度 = 2.6447 + 0.6909 × 花萼宽度。

我们也可以看到,该模型的R2值是一个可以接受的0.558,而p值 (Prob)是非常显著的——至少对于这个类而言。

 

获取从模型所得的回归线。

import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
from matplotlib.font_manager import *
from pylab import *

#定义自定义字体
myfont = FontProperties(fname='/temp/msyh.ttf')
#解决负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus']=False
mpl.rcParams['font.sans-serif'] = ['SimHei']

df = pd.read_csv("/temp/iris.data",names=['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度', '类别'])


y = df['花萼长度'][:50]

x = df['花萼宽度'][:50]

X = sm.add_constant(x)

results = sm.OLS(y, X).fit()

fig, ax = plt.subplots(figsize=(7,7))

ax.plot(x, results.fittedvalues, label=u'回归线')

ax.scatter(x, y, label=u'数据点', color='r')

ax.set_ylabel('花萼长度',fontproperties=myfont)

ax.set_xlabel('花萼宽度',fontproperties=myfont)

ax.set_title('花萼长度 花萼宽度', fontproperties=myfont,fontsize=14, y=1.02)

ax.legend(loc=2)

plt.show()