Преобразование объекта summary из statsmodels в DataFrame Pandas
Я выполняю множественную линейную регрессию с использованием statsmodels.formula.api
(версия 0.9.0) на Windows 10. После подгонки модели и получения сводной информации с помощью следующих строк, я получаю результат в формате объекта summary.
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
==============================================================================
Я хочу провести обратное исключение переменных, основываясь на P-значениях с уровнем значимости 0.05. Для этого мне нужно удалить предиктор с наивысшим P-значением и снова запустить код.
Хотелось бы узнать, есть ли способ извлечь P-значения из объекта summary, чтобы я мог запустить цикл с условием и найти значимые переменные, не повторяя шаги вручную.
Спасибо.
5 ответ(ов)
Простое решение заключается всего в одной строке кода:
LRresult = (result.summary2().tables[1])
Как упомянул ZaxR в своем комментарии, summary2
пока не считается стабильным, хотя он хорошо работает и с summary
. Поэтому правильным ответом может быть:
LRresult = (result.summary().tables[1])
Это даст вам объект DataFrame:
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
Эти шаги позволят вам построить новую модель с учетом только значимых переменных.
Вы можете использовать следующий код. Это будет простое решение, которое работает почти всегда:
lr.summary2()
Если у вас есть дополнительные вопросы или проблемы, не стесняйтесь задавать их!
Я всё ещё считаю, что нет однозначного ответа, который охватывал бы весь запрос в полном объёме. Вот один из способов представить всю информацию в двух датафреймах (один для средней таблицы и один для метрик в верхней и нижней частях).
def reform_df(dft):
# Небольшое и быстрое объединение столбцов 2 и 3 со столбцами 0 и 1
dfl = dft[[0, 1]]
dfr = dft[[2, 3]]
dfr.columns = 0, 1
dfout = pd.concat([dfl, dfr])
dfout.columns = ['Параметр', 'Значение']
return dfout
def model_summary_to_dataframe(model):
# Сначала создаём среднюю таблицу
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 = 'Параметр'
# Теперь добавим окружающую информацию
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
Данный код предоставляет возможность получить результаты модели и метрики в удобном формате для анализа.
Этот код помещает все метрики в словарь, доступный по ключу. Промежуточный результат — это DataFrame
, который вы можете использовать. Я не сделал коэффициенты в виде словаря, но вы можете применить аналогичный метод, создав словарь с двумя уровнями: 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']
Таким образом, вы получаете доступ к метрикам в удобно читаемом виде и можете легко работать с полученными данными.
Если вам нужно получить сопутствующую информацию, попробуйте следующий код:
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)
Этот код создает словарь dfs
, который заполняется данными из таблиц модели fa_model
. Сначала он обрабатывает данные из первой и третьей таблицы, очищая пробелы с помощью метода strip()
, и затем преобразует полученный словарь в объект pd.Series
. Надеюсь, это поможет вам получить нужную информацию!
Как изменить порядок столбцов в DataFrame?
Преобразование списка словарей в DataFrame pandas
Установить значение для конкретной ячейки в DataFrame pandas с использованием индекса
Выбор строки из pandas Series/DataFrame по целочисленному индексу
Получить все ключи из объекта GroupBy в Pandas