将 statsmodels 摘要对象转换为 Pandas Dataframe
Converting statsmodels summary object to Pandas Dataframe
我在 Windows 10 上使用 statsmodels.formula.api
(版本 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 值,这样我就可以 运行 一个带有条件语句的循环并找到重要的变量,而无需手动重复这些步骤。
谢谢。
将模型拟合存储为变量 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 中。
@Michael B 的回答很好,但需要 "recreating" table。 table 本身实际上可以直接从 summary().tables 属性中获得。这个属性中的每个table(是table的列表)是一个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]
一个简单的解决方案就是一行代码:
LRresult = (result.summary2().tables[1])
正如 ZaxR 在以下评论中提到的,Summary2 尚未被认为是稳定的,但它也可以与 Summary 一起使用。所以这可能是正确答案:
LRresult = (result.summary().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
您可以这样写,因为 below.It 很容易修复并且几乎每次都能正常工作。
lr.summary2()
如果你想了解周边信息,请尝试以下方法:
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)
下面的代码将所有指标放入可通过键访问的字典中。中间结果其实是一个DataFrame
你可以用,我没有把系数做成一个dictionary
,但是你可以用类似的方法再深两层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']
我仍然不认为有一个清晰的答案可以完整地捕获查询。这是一种捕获两个数据帧中所有内容的方法(一个用于中间 table,一个用于顶部和底部的指标)。
def reform_df(dft):
# quick and dirty stacking of cols 2,3 on 0,1
dfl = dft[[0,1]]
dfr = dft[[2,3]]
dfr.columns = 0,1
dfout = pd.concat([dfl,dfr])
dfout.columns=['Parameter','Value']
return dfout
def model_summary_to_dataframe(model):
# first the middle table
results_df = pd.DataFrame(model.summary().tables[1])
results_df = results_df.set_index(0)
results_df.columns = results_df.iloc[0]
results_df = results_df.iloc[1:]
results_df.index.name='Parameter'
# now for the surrounding information
metrics_top = reform_df(pd.DataFrame(model.summary().tables[0]))
metrics_bot = reform_df(pd.DataFrame(model.summary().tables[2]))
metrics_df = pd.concat([metrics_top,metrics_bot])
return pd.DataFrame(results_df),metrics_df
它有效,但我在项目[3]中发现了一个小错误
这是修复:
import pandas as pd
dfs = {}
fs = stepwise_fit.summary()
for item in fs.tables[0].data:
#print("item " + str(item))
dfs[item[0].strip()] = item[1].strip()
dfs[item[2].strip()] = str(item[3]).strip()
for item in fs.tables[2].data:
dfs[item[0].strip()] = item[1].strip()
dfs[item[2].strip()] = str(item[3]).strip()
dfs = pd.Series(dfs)
print(type(dfs))
我在 Windows 10 上使用 statsmodels.formula.api
(版本 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 值,这样我就可以 运行 一个带有条件语句的循环并找到重要的变量,而无需手动重复这些步骤。
谢谢。
将模型拟合存储为变量 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 中。
@Michael B 的回答很好,但需要 "recreating" table。 table 本身实际上可以直接从 summary().tables 属性中获得。这个属性中的每个table(是table的列表)是一个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]
一个简单的解决方案就是一行代码:
LRresult = (result.summary2().tables[1])
正如 ZaxR 在以下评论中提到的,Summary2 尚未被认为是稳定的,但它也可以与 Summary 一起使用。所以这可能是正确答案:
LRresult = (result.summary().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
您可以这样写,因为 below.It 很容易修复并且几乎每次都能正常工作。
lr.summary2()
如果你想了解周边信息,请尝试以下方法:
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)
下面的代码将所有指标放入可通过键访问的字典中。中间结果其实是一个DataFrame
你可以用,我没有把系数做成一个dictionary
,但是你可以用类似的方法再深两层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']
我仍然不认为有一个清晰的答案可以完整地捕获查询。这是一种捕获两个数据帧中所有内容的方法(一个用于中间 table,一个用于顶部和底部的指标)。
def reform_df(dft):
# quick and dirty stacking of cols 2,3 on 0,1
dfl = dft[[0,1]]
dfr = dft[[2,3]]
dfr.columns = 0,1
dfout = pd.concat([dfl,dfr])
dfout.columns=['Parameter','Value']
return dfout
def model_summary_to_dataframe(model):
# first the middle table
results_df = pd.DataFrame(model.summary().tables[1])
results_df = results_df.set_index(0)
results_df.columns = results_df.iloc[0]
results_df = results_df.iloc[1:]
results_df.index.name='Parameter'
# now for the surrounding information
metrics_top = reform_df(pd.DataFrame(model.summary().tables[0]))
metrics_bot = reform_df(pd.DataFrame(model.summary().tables[2]))
metrics_df = pd.concat([metrics_top,metrics_bot])
return pd.DataFrame(results_df),metrics_df
它有效,但我在项目[3]中发现了一个小错误 这是修复:
import pandas as pd
dfs = {}
fs = stepwise_fit.summary()
for item in fs.tables[0].data:
#print("item " + str(item))
dfs[item[0].strip()] = item[1].strip()
dfs[item[2].strip()] = str(item[3]).strip()
for item in fs.tables[2].data:
dfs[item[0].strip()] = item[1].strip()
dfs[item[2].strip()] = str(item[3]).strip()
dfs = pd.Series(dfs)
print(type(dfs))