web-dev-qa-db-ja.com

statsmodelsサマリーオブジェクトをPandas Dataframeに変換する

Windows 10でstatsmodels.formula.api(ver 0.9.0)を使用して多重線形回帰を実行しています。モデルを適合させ、次の行で概要を取得した後、概要オブジェクト形式で概要を取得します。

X_opt  = X[:, [0,1,2,3]]
regressor_OLS = sm.OLS(endog= y, exog= X_opt).fit()
regressor_OLS.summary()


                          OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.951
Model:                            OLS   Adj. R-squared:                  0.948
Method:                 Least Squares   F-statistic:                     296.0
Date:                Wed, 08 Aug 2018   Prob (F-statistic):           4.53e-30
Time:                        00:46:48   Log-Likelihood:                -525.39
No. Observations:                  50   AIC:                             1059.
Df Residuals:                      46   BIC:                             1066.
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const       5.012e+04   6572.353      7.626      0.000    3.69e+04    6.34e+04
x1             0.8057      0.045     17.846      0.000       0.715       0.897
x2            -0.0268      0.051     -0.526      0.602      -0.130       0.076
x3             0.0272      0.016      1.655      0.105      -0.006       0.060
==============================================================================
Omnibus:                       14.838   Durbin-Watson:                   1.282
Prob(Omnibus):                  0.001   Jarque-Bera (JB):               21.442
Skew:                          -0.949   Prob(JB):                     2.21e-05
Kurtosis:                       5.586   Cond. No.                     1.40e+06
==============================================================================

有意水準0.05のP値の後方消去を行いたいです。このため、最高のP値を持つ予測変数を削除して、コードを再実行する必要があります。

サマリーオブジェクトからP値を抽出する方法があるかどうかを知りたかったので、条件付きステートメントでループを実行し、手順を手動で繰り返すことなく重要な変数を見つけることができました。

ありがとうございました。

9
Sagun Kayastha

@Michael Bからの回答はうまくいきますが、テーブルを「再作成」する必要があります。テーブル自体は、実際にはsummary()。tables属性から直接利用できます。この属性の各テーブル(テーブルのリスト)は SimpleTable であり、さまざまな形式を出力するメソッドがあります。その後、これらの形式のいずれかをpd.DataFrameとして読み戻すことができます。

import statsmodels.api as sm

model = sm.OLS(y,x)
results = model.fit()
results_summary = results.summary()

# Note that tables is a list. The table at index 1 is the "core" table. Additionally, read_html puts dfs in a list, so we want index 0
results_as_html = results_summary.tables[1].as_html()
pd.read_html(results_as_html, header=0, index_col=0)[0]
11
ZaxR

次のように、モデルフィットを変数resultsとして保存します。

import statsmodels.api as sm
model = sm.OLS(y,x)
results = model.fit()

次に、以下のような関数を作成します。

def results_summary_to_dataframe(results):
    '''take the result of an statsmodel results table and transforms it into a dataframe'''
    pvals = results.pvalues
    coeff = results.params
    conf_lower = results.conf_int()[0]
    conf_higher = results.conf_int()[1]

    results_df = pd.DataFrame({"pvals":pvals,
                               "coeff":coeff,
                               "conf_lower":conf_lower,
                               "conf_higher":conf_higher
                                })

    #Reordering...
    results_df = results_df[["coeff","pvals","conf_lower","conf_higher"]]
    return results_df

dir() を使用して印刷することで、resultsオブジェクトのすべての属性をさらに調査し、それを関数とdfに追加することができます。

11
Michael B

簡単な解決策は、たった1行のコードです。

LRresult = (result.summary2().tables[1])

これにより、データフレームオブジェクトが得られます。

type(LRresult)

pandas.core.frame.DataFrame

重要な変数を取得して、テストを再度実行するには:

newlist = list(LRresult[LRresult['P>|z|']<=0.05].index)[1:]
myform1 = 'binary_Target' + ' ~ ' + ' + '.join(newlist)

M1_test2 = smf.logit(formula=myform1,data=myM1_1)

result2 = M1_test2.fit(maxiter=200)
LRresult2 = (result2.summary2().tables[1])
LRresult2
5
Daniel Zhou

以下のように書くことができます。それは簡単な修正であり、毎回ほぼ適切に動作します。

lr.summary2()
0
Abhishek Singh

周辺情報が必要な場合は、次を試してください。

import pandas as pd
dfs = {}
fs = fa_model.summary()
for item in fs.tables[0].data:
    dfs[item[0].strip()] = item[1].strip()
    dfs[item[2].strip()] = item[3].strip()
for item in fs.tables[2].data:
    dfs[item[0].strip()] = item[1].strip()
    dfs[item[2].strip()] = item[3].strip()
dfs = pd.Series(dfs)
0
Griff

以下のコードは、すべてのメトリックをキーでアクセスできる辞書に入れます。中間結果は、実際に使用できるDataFrameです。係数をdictionaryにしたわけではありませんが、同様の方法を適用できますが、2レベルの深さdict[var][metric]

キーを簡単に入力できるようにするために、メトリック名の一部をより簡単に入力できるバージョンに変換しました。例えば。 「Prob(Omnibus):」はprob_omnibusになり、res_dict ['prob_omnibus']で値にアクセスできます。

import pandas as pd

res = sm.OLS(y, X).fit()
model_results_df = []
coefficient_df = None
for i, tab in enumerate(res.summary().tables):
    header, index_col = None, None
    if i == 1:
        coefficient_df = pd.read_html(tab.as_html(), header=0, index_col=0)[0]
    else:
        df = pd.read_html(tab.as_html())[0]
        model_results_df += [df.iloc[:,0:2], df.iloc[:,2:4]]

model_results_df = pd.DataFrame(np.concatenate(model_results_df), columns=['metric', 'value'])
model_results_df.dropna(inplace=True, axis=0)
model_results_df.metric = model_results_df.metric.apply(lambda x : x.lower().replace(' (', '_')
                                                        .replace('.', '').replace('(', '_')
                                                        .replace(')', '').replace('-', '_')
                                                       .replace(':', '').replace(' ', '_'))

res_dict = dict(Zip(model_results_df.metric.values, model_results_df.value.values))
res_dict['f_statistic']
0
Joop