0

Преобразование объекта summary из statsmodels в DataFrame Pandas

34

Я выполняю множественную линейную регрессию с использованием 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 ответ(ов)

0

Простое решение заключается всего в одной строке кода:

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

Эти шаги позволят вам построить новую модель с учетом только значимых переменных.

0

Вы можете использовать следующий код. Это будет простое решение, которое работает почти всегда:

lr.summary2()

Если у вас есть дополнительные вопросы или проблемы, не стесняйтесь задавать их!

0

Я всё ещё считаю, что нет однозначного ответа, который охватывал бы весь запрос в полном объёме. Вот один из способов представить всю информацию в двух датафреймах (один для средней таблицы и один для метрик в верхней и нижней частях).

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

Данный код предоставляет возможность получить результаты модели и метрики в удобном формате для анализа.

0

Этот код помещает все метрики в словарь, доступный по ключу. Промежуточный результат — это 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']

Таким образом, вы получаете доступ к метрикам в удобно читаемом виде и можете легко работать с полученными данными.

0

Если вам нужно получить сопутствующую информацию, попробуйте следующий код:

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. Надеюсь, это поможет вам получить нужную информацию!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь