WHAT' CHA GONNA DO FOR ME?

Python、統計、機械学習、R、ファイナンスとか

OLS①

エコノメ最終奥義、OLSをPythonでやる。
PythonにはOLS用の関数が色々あるようなので何回かに分けて書きたい。

今回はstatsmodelsのOLSを使って、下記のような簡単な回帰式を推定したい。

{ 
y=2+1.5x+\epsilon\\
x \sim\ \mathcal{N}(1,1)\\
\epsilon \sim\ \mathcal{N}(0,1)\\
}

データは乱数から自分で作り、推定されたパラメータが、事前に決めたパラメータに近いことを確認する。

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import statsmodels.api as sm

#サンプリング数
N=1000

#データ生成
np.random.seed(0)
x=np.random.normal(1,1,N)
eps=np.random.normal(0,1,N)
y=2+1.5*x+eps

#OLS(statsmodels)
X=sm.add_constant(x, prepend=True) #1だけが詰まった列を左端に追加
model = sm.OLS(y,X)
results = model.fit()
print(results.summary())

#OLS(arrayでの手計算)
np.linalg.inv(X.T.dot(X)).dot(X.T.dot(y))

#OLS(matrixでの手計算)
X=np.mat(X)
y=np.mat(y).T #1×Nの行列になってしまうので最後に転置してN×1の行列にする
np.linalg.inv(X.T*X)*(X.T*y)

結果は次の通りで、大体想定通りの推定結果が得られた。また、statsmodelsのOLS関数と手計算結果が合うことも一応確認しておいた。
ただ、Nのarrayをmatrixに変換すると、N×1じゃなくて1×Nになるのはやめてほしい気がする。

In [77]: X=sm.add_constant(x, prepend=True) #1だけが詰まった列を左端に追加
    ...: model = sm.OLS(y,X)
    ...: results = model.fit()
    ...: print(results.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.692
Model:                            OLS   Adj. R-squared:                  0.692
Method:                 Least Squares   F-statistic:                     2241.
Date:                Wed, 11 Feb 2015   Prob (F-statistic):          2.28e-257
Time:                        18:26:09   Log-Likelihood:                -1386.1
No. Observations:                1000   AIC:                             2776.
Df Residuals:                     998   BIC:                             2786.
Df Model:                           1                                         
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const          2.0431      0.043     47.942      0.000         1.959     2.127
x1             1.4691      0.031     47.339      0.000         1.408     1.530
==============================================================================
Omnibus:                        1.076   Durbin-Watson:                   2.074
Prob(Omnibus):                  0.584   Jarque-Bera (JB):                1.155
Skew:                           0.059   Prob(JB):                        0.561
Kurtosis:                       2.883   Cond. No.                         2.53
==============================================================================
In [78]: np.linalg.inv(X.T.dot(X)).dot(X.T.dot(y))
Out[78]: array([ 2.04312405,  1.4690942 ])
In [79]: X=np.mat(X)
    ...: y=np.mat(y).T #なぜか1×Nの行列になってしまうので最後に転置してN×1の行列にする
    ...: np.linalg.inv(X.T*X)*(X.T*y)
Out[79]: 
matrix([[ 2.04312405],
        [ 1.4690942 ]])