python 包中的 statsmodels,如何准确处理重复的特征?

statmodels in python package, How exactly duplicated features are handled?

我是 R 的重度用户,最近正在学习 python。 我有一个关于 statsmodels.api 如何处理重复特征的问题。 据我了解,此函数是 R 包中 glm 的 python 版本。所以我期望函数 return 是最大似然估计 (MLE)。

我的问题是 statsmodels 使用哪种算法来获得 MLE? 特别是算法如何处理重复特征的情况?

为了澄清我的问题,我从具有单个协变量 x1 的伯努利分布中生成了大小为 50 的样本。

import statsmodels.api as sm
import pandas as pd
import numpy as np
def ilogit(eta):
    return 1.0 - 1.0/(np.exp(eta)+1)

## generate samples
Nsample = 50
cov = {}
cov["x1"] = np.random.normal(0,1,Nsample)
cov = pd.DataFrame(cov)
true_value = 0.5
resp = {}
resp["FAIL"] =   np.random.binomial(1, ilogit(true_value*cov["x1"]))
resp = pd.DataFrame(resp)
resp["NOFAIL"] = 1 - resp["FAIL"]

然后将逻辑回归拟合为:

## fit logistic regrssion 
fit = sm.GLM(resp,cov,family=sm.families.Binomial(sm.families.links.logit)).fit()
fit.summary()

这个returns:

估计的系数与真实值(=0.5)或多或少相似。 然后我创建一个重复的列,即 x2,并再次拟合逻辑回归模型。 (R 包中的 glm 将 return NA for x2)

cov["x2"] = cov["x1"]
fit = sm.GLM(resp,cov,family=sm.families.Binomial(sm.families.links.logit)).fit()
fit.summary()

这输出:

令人惊讶的是,这有效并且 x1 和 x2 的系数估计完全相同 (=0.1182)。由于之前拟合returns x1 = 0.2364 的系数估计,估计减半。 然后我将重复特征的数量增加到 9 并拟合模型:

cov = cov
for icol in range(3,10):
    cov["x"+str(icol)] = cov["x1"]
fit = sm.GLM(resp,cov,family=sm.families.Binomial(sm.families.links.logit)).fit()
fit.summary()

不出所料,每个重复变量的估计值都相同 (0.0263),而且它们似乎比 x1 (0.2364) 的原始估计值小 9 倍。

我对最大似然估计的这种意外行为感到惊讶。您能解释一下为什么会这样吗?statsmodels.api 背后采用了什么样的算法?

简短回答:

GLM 使用 Moore-Penrose 广义逆函数 pinv,在这种情况下,它对应于主成分回归,其中特征值为零的成分被丢弃。零特征值由 numpy.linalg.pinv.

中的默认阈值 (rcond) 定义

statsmodels 没有针对共线性的系统策略。当矩阵求逆失败时,一些非线性优化例程会引发异常。但是,线性回归模型 OLS 和 WLS 默认使用广义逆,在这种情况下我们会看到上述行为。

GLM.fit 中的默认优化算法是迭代重新加权最小二乘 irls,它使用 WLS 并继承 WLS 对奇异设计矩阵的默认行为。 statsmodels master 中的版本还可以选择使用标准 scipy 优化器,其中关于奇异或接近奇异设计矩阵的行为将取决于优化算法的细节。