Неожиданные стандартные ошибки с взвешенным методом наименьших квадратов в Python Pandas

В коде основного класса OLS в Python Pandas , я ищу помощь, чтобы уточнить, какие соглашения используются для стандартной ошибки и t-статистики, сообщаемой при выполнении взвешенного OLS.

Вот мой пример набора данных с некоторым импортом для использования Pandas и прямого использования scikits.statsmodels WLS:

import pandas
import numpy as np
from statsmodels.regression.linear_model import WLS

# Make some random data.
np.random.seed(42)
df = pd.DataFrame(np.random.randn(10, 3), columns=['a', 'b', 'weights'])

# Add an intercept term for direct use in WLS
df['intercept'] = 1 

# Add a number (I picked 10) to stabilize the weight proportions a little.
df['weights'] = df.weights + 10

# Fit the regression models.
pd_wls = pandas.ols(y=df.a, x=df.b, weights=df.weights)
sm_wls = WLS(df.a, df[['intercept','b']], weights=df.weights).fit()

Я использую %cpaste для выполнения этого в IPython, а затем печатаю сводки обеих регрессий:

In [226]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:import pandas
:import numpy as np
:from statsmodels.regression.linear_model import WLS
:
:# Make some random data.
np:np.random.seed(42)
:df = pd.DataFrame(np.random.randn(10, 3), columns=['a', 'b', 'weights'])
:
:# Add an intercept term for direct use in WLS
:df['intercept'] = 1
:
:# Add a number (I picked 10) to stabilize the weight proportions a little.
:df['weights'] = df.weights + 10
:
:# Fit the regression models.
:pd_wls = pandas.ols(y=df.a, x=df.b, weights=df.weights)
:sm_wls = WLS(df.a, df[['intercept','b']], weights=df.weights).fit()
:--

In [227]: pd_wls
Out[227]:

-------------------------Summary of Regression Analysis-------------------------

Formula: Y ~ <x> + <intercept>

Number of Observations:         10
Number of Degrees of Freedom:   2

R-squared:         0.2685
Adj R-squared:     0.1770

Rmse:              2.4125

F-stat (1, 8):     2.9361, p-value:     0.1250

Degrees of Freedom: model 1, resid 8

-----------------------Summary of Estimated Coefficients------------------------
      Variable       Coef    Std Err     t-stat    p-value    CI 2.5%   CI 97.5%
--------------------------------------------------------------------------------
             x     0.5768     1.0191       0.57     0.5869    -1.4206     2.5742
     intercept     0.5227     0.9079       0.58     0.5806    -1.2567     2.3021
---------------------------------End of Summary---------------------------------


In [228]: sm_wls.summ
sm_wls.summary      sm_wls.summary_old

In [228]: sm_wls.summary()
Out[228]:
<class 'statsmodels.iolib.summary.Summary'>
"""
                            WLS Regression Results
==============================================================================
Dep. Variable:                      a   R-squared:                       0.268
Model:                            WLS   Adj. R-squared:                  0.177
Method:                 Least Squares   F-statistic:                     2.936
Date:                Wed, 17 Jul 2013   Prob (F-statistic):              0.125
Time:                        15:14:04   Log-Likelihood:                -10.560
No. Observations:                  10   AIC:                             25.12
Df Residuals:                       8   BIC:                             25.72
Df Model:                           1
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
intercept      0.5227      0.295      1.770      0.115        -0.158     1.204
b              0.5768      0.333      1.730      0.122        -0.192     1.346
==============================================================================
Omnibus:                        0.967   Durbin-Watson:                   1.082
Prob(Omnibus):                  0.617   Jarque-Bera (JB):                0.622
Skew:                           0.003   Prob(JB):                        0.733
Kurtosis:                       1.778   Cond. No.                         1.90
==============================================================================
"""

Обратите внимание на несоответствие стандартных ошибок: Pandas утверждает, что стандартные ошибки равны [0.9079, 1.0191], а statsmodels говорит [0.295, 0.333]..

Вернемся к коду, ссылку на который я дал вверху сообщения Я пытался отследить, откуда берется несоответствие.

Во-первых, вы можете видеть, что стандартные ошибки являются отчетами функции:

def _std_err_raw(self):
    """Returns the raw standard err values."""
    return np.sqrt(np.diag(self._var_beta_raw))

Итак, глядя на self._var_beta_raw, я нахожу:

def _var_beta_raw(self):
    """
    Returns the raw covariance of beta.
    """
    x = self._x.values
    y = self._y.values

    xx = np.dot(x.T, x)

    if self._nw_lags is None:
        return math.inv(xx) * (self._rmse_raw ** 2)
    else:
        resid = y - np.dot(x, self._beta_raw)
        m = (x.T * resid).T

        xeps = math.newey_west(m, self._nw_lags, self._nobs, self._df_raw,
                               self._nw_overlap)

        xx_inv = math.inv(xx)
        return np.dot(xx_inv, np.dot(xeps, xx_inv))

В моем случае использования self._nw_lags всегда будет None, поэтому первая часть вызывает недоумение. Поскольку xx — это просто стандартный продукт матрицы регрессора: x.T.dot(x), мне интересно, как на это влияют веса. Термин self._rmse_raw происходит непосредственно из регрессии статистических моделей, подогнанной в конструкторе OLS, так что он определенно включает веса.

Это вызывает такие вопросы:

  1. Почему стандартная ошибка сообщается с весами, примененными в части RMSE, но не к переменным регрессора.
  2. Является ли это стандартной практикой, если вам нужны «непреобразованные» переменные (не могли бы вы также захотеть непреобразованный RMSE ??) Есть ли способ заставить Pandas вернуть полностью взвешенную версию стандартной ошибки?
  3. Почему все неправильное направление? В конструкторе вычисляется полная регрессия, подобранная статистическими моделями. Почему бы абсолютно каждой сводной статистике не браться прямо оттуда? Почему это смешивается и сопоставляется так, что некоторые из них получены из выходных данных statsmodels, а некоторые — из домашних вычислений Pandas?

Похоже, я могу согласовать вывод Pandas, выполнив следующие действия:

In [238]: xs = df[['intercept', 'b']]

In [239]: trans_xs = xs.values * np.sqrt(df.weights.values[:,None])

In [240]: trans_xs
Out[240]:
array([[ 3.26307961, -0.45116742],
       [ 3.12503809, -0.73173821],
       [ 3.08715494,  2.36918991],
       [ 3.08776136, -1.43092325],
       [ 2.87664425, -5.50382662],
       [ 3.21158019, -3.25278836],
       [ 3.38609639, -4.78219647],
       [ 2.92835309,  0.19774643],
       [ 2.97472796,  0.32996453],
       [ 3.1158155 , -1.87147934]])

In [241]: np.sqrt(np.diag(np.linalg.inv(trans_xs.T.dot(trans_xs)) * (pd_wls._rmse_raw ** 2)))
Out[241]: array([ 0.29525952,  0.33344823])

Меня просто очень смущают эти отношения. Это то, что распространено среди статистиков: включение весов с частью RMSE, но затем выбор, взвешивать переменные или нет при расчете стандартной ошибки коэффициента? Если это так, то почему сами коэффициенты также не будут отличаться между пандами и статистическими моделями, поскольку они аналогичным образом получаются из переменных, сначала преобразованных статистическими моделями?

Для справки, вот полный набор данных, использованный в моем игрушечном примере (на случай, если np.random.seed недостаточно для воспроизводимости):

In [242]: df
Out[242]:
          a         b    weights  intercept
0  0.496714 -0.138264  10.647689          1
1  1.523030 -0.234153   9.765863          1
2  1.579213  0.767435   9.530526          1
3  0.542560 -0.463418   9.534270          1
4  0.241962 -1.913280   8.275082          1
5 -0.562288 -1.012831  10.314247          1
6 -0.908024 -1.412304  11.465649          1
7 -0.225776  0.067528   8.575252          1
8 -0.544383  0.110923   8.849006          1
9  0.375698 -0.600639   9.708306          1

person ely    schedule 17.07.2013    source источник
comment
Проведя немного больше исследований, но, насколько это того стоит, R соглашается с цифрами статистических моделей. lm (формула = a ~ 1 + b, данные = df, веса = веса) дает 0,2953 и 0,3334   -  person TomAugspurger    schedule 18.07.2013


Ответы (1)


Не отвечая прямо на ваш вопрос здесь, но в целом вы должны предпочесть код statsmodels пандам для моделирования. Недавно были обнаружены некоторые проблемы с WLS в статистических моделях, которые теперь исправлены. Насколько я знаю, они также были исправлены в пандах, но по большей части код моделирования панд не поддерживается, и среднесрочная цель состоит в том, чтобы убедиться, что все, что доступно в пандах, устарело и было перемещено в statsmodels (следующий выпуск 0.6.0 для statsmodels должен это сделать).

Чтобы было немного понятнее, pandas теперь зависит от statsmodels. Вы можете передавать DataFrames в statsmodels или использовать формулы в statsmodels. Это предполагаемые отношения в будущем.

person jseabold    schedule 18.07.2013
comment
Это полезно, но в моем случае речь идет о системе, в которой есть как исследовательская, так и производственная ветки. Производственную ветвь очень сложно модифицировать, и такое изменение, как перенос большого количества кода с прямого использования pandas.ols на прямое использование WLS, было бы очень долгосрочным проектом. (Возможно, это все еще должно произойти, но между тем и сейчас нам все еще нужно поддерживать и понимать, что происходит с pandas.ols способом прохождения статистических моделей.) - person ely; 18.07.2013
comment
Тогда я бы предложил отправить отчет об ошибке с помощью pandas. Насколько я знаю, этот код не поддерживается и активно не развивается. Что касается того, почему pandas не использует результаты statsmodels, я не знаю. Я полагаю, была небольшая путаница в отношении того, какова была область действия панд / каким будет уровень взаимодействия между пандами и статистическими моделями на раннем этапе, но это было решено. Вы должны знать, что эта часть кода pandas не проверена на правильность, хотя AFAICT, хотя тестируются statsmodels. Я уверен, что они примут патч, но, как я уже сказал, этот код, скорее всего, исчезнет в будущем. - person jseabold; 20.07.2013
comment
Я думаю, я должен также добавить, что панды не могут иметь обратную зависимость от статистических моделей, поэтому, возможно, поэтому некоторые результаты не передаются. Однако я давно не смотрел на этот код. - person jseabold; 20.07.2013