Capturando alta multi-colinealidad en statsmodels

Digamos que encajo un modelo en statsmodels

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

Cuando hago mod.summary() puedo ver lo siguiente:

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

A veces, la advertencia es diferente (por ejemplo, basada en valores propios de la matriz de diseño). ¿Cómo puedo capturar condiciones de alta colinealidad múltiple en una variable? ¿Esta advertencia está almacenada en algún lugar del objeto modelo?

Además, ¿dónde puedo encontrar una descripción de los campos en summary() ?

Puede detectar una alta colinealidad múltiple al inspeccionar los valores propios de la matriz de correlación . Un valor propio muy bajo muestra que los datos son colineales, y el vector propio correspondiente muestra qué variables son colineales.

Si no hay colinealidad en los datos, usted esperaría que ninguno de los valores propios estén cerca de cero:

 >>> 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]) 

Sin embargo, si diga x[4] - 2 * x[0] - 3 * x[2] = 0 , entonces

 >>> 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]) 

uno de los valores propios (aquí el primero) es cercano a cero. El vector propio correspondiente es:

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

Haciendo caso omiso de los coeficientes casi cero , lo anterior básicamente dice que x[0] , x[2] y x[4] son colineales (como se esperaba). Si uno estandariza los valores de xs y se multiplica por este vector propio, el resultado se mantendrá alrededor de cero con una pequeña varianza:

 >>> 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) 

Tenga en cuenta que ys.var() es básicamente el valor eigen que estuvo cerca de cero.

Por lo tanto, para capturar una alta linealidad, observe los valores propios de la matriz de correlación.

Basado en una pregunta similar para R, hay otras opciones que pueden ayudar a las personas. Estaba buscando un solo número que capturara la colinealidad, y las opciones incluyen el determinante y el número de condición de la matriz de correlación.

Según una de las respuestas de R, el determinante de la matriz de correlación “variará de 0 (colinealidad perfecta) a 1 (no colinealidad)”. Me pareció útil el rango acotado.

Ejemplo traducido para determinante:

 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 

Y de manera similar, el número de condición de la matriz de covarianza se aproximará al infinito con una dependencia lineal perfecta.

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