Захват высокой многоколоничности в статистических моделях

Скажем, я подгоняю модель в statsmodels

mod = smf.ols('dependent ~ first_category + second_category + other', data=df).fit()

Когда я делаю mod.summary() я вижу следующее:

Warnings:
[1] The condition number is large, 1.59e+05. This might indicate that there are
strong multicollinearity or other numerical problems.

Иногда предупреждение отличается (например, на основе собственных значений проектной матрицы). Как я могу фиксировать условия с высокой множественностью коллинеарности в переменной? Это предупреждение хранится где-то в объекте модели?

Кроме того, где я могу найти описание полей в summary()?

Ответы

Ответ 1

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

Если в данных нет коллинеарности, вы ожидаете, что ни одно из собственных значений близко к нулю:

>>> xs = np.random.randn(100, 5)      # independent variables
>>> corr = np.corrcoef(xs, rowvar=0)  # correlation matrix
>>> w, v = np.linalg.eig(corr)        # eigen values & eigen vectors
>>> w
array([ 1.256 ,  1.1937,  0.7273,  0.9516,  0.8714])

Однако, если сказать x[4] - 2 * x[0] - 3 * x[2] = 0, то

>>> noise = np.random.randn(100)                      # white noise
>>> xs[:,4] = 2 * xs[:,0] + 3 * xs[:,2] + .5 * noise  # collinearity
>>> corr = np.corrcoef(xs, rowvar=0)
>>> w, v = np.linalg.eig(corr)
>>> w
array([ 0.0083,  1.9569,  1.1687,  0.8681,  0.9981])

одно из собственных значений (здесь самое первое) близко к нулю. Соответствующий собственный вектор:

>>> v[:,0]
array([-0.4077,  0.0059, -0.5886,  0.0018,  0.6981])

Игнорируя почти нулевые коэффициенты, в основном говорится, что x[0], x[2] и x[4] являются коллинеарными (как и ожидалось). Если стандартизировать значения xs и умножить на этот собственный вектор, результат будет колебаться вокруг нуля с малой дисперсией:

>>> std_xs = (xs - xs.mean(axis=0)) / xs.std(axis=0)  # standardized values
>>> ys = std_xs.dot(v[:,0])
>>> ys.mean(), ys.var()
(0, 0.0083)

Заметим, что ys.var() в основном является собственным значением, близким к нулю.

Итак, чтобы захватить высокую многолинейность, посмотрите на собственные значения корреляционной матрицы.

Ответ 2

На основании аналогичного вопроса для R есть некоторые другие варианты, которые могут помочь людям. Я искал одно число, которое фиксировало коллинеарность, а опции включают в себя определитель и номер условия корреляционной матрицы.

Согласно одному из ответов R, определитель корреляционной матрицы будет "находиться в диапазоне от 0 (совершенная коллинеарность) до 1 (без коллинеарности)". Я нашел ограниченный диапазон полезным.

Переведенный пример для определителя:

import numpy as np
import pandas as pd

# Create a sample random dataframe
np.random.seed(321)
x1 = np.random.rand(100)
x2 = np.random.rand(100)
x3 = np.random.rand(100)
df = pd.DataFrame({'x1': x1, 'x2': x2, 'x3': x3})

# Now create a dataframe with multicollinearity
multicollinear_df = df.copy()
multicollinear_df['x3'] = multicollinear_df['x1'] + multicollinear_df['x2']

# Compute both correlation matrices
corr = np.corrcoef(df, rowvar=0)
multicollinear_corr = np.corrcoef(multicollinear_df, rowvar=0)

# Compare the determinants
print np.linalg.det(corr) . # 0.988532159861
print np.linalg.det(multicollinear_corr) . # 2.97779797328e-16

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

print np.linalg.cond(corr) . # 1.23116253259
print np.linalg.cond(multicollinear_corr) . # 6.19985218873e+15