我是一个沉重的R用户,我最近正在学习python。 我有一个关于statsmodels.api如何处理重复功能的问题。 据我所知,这个函数是R包中glm的python版本。所以我期待函数返回最大似然估计(MLE)。
我的问题是statsmodels采用哪种算法来获取MLE? 特别是算法如何处理具有重复特征的情况?
为了澄清我的问题,我使用单个协变量x1从Bernoullie分布生成大小为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()
返回:
估计系数或多或少类似于真实值(= 0.5)。 然后我创建一个重复的列,即x2,并再次适合逻辑回归模型。 (R包中的glm将为x2返回NA)
cov["x2"] = cov["x1"]
fit = sm.GLM(resp,cov,family=sm.families.Binomial(sm.families.links.logit)).fit()
fit.summary()
输出:
令人惊讶的是,这种方法和x1和x2的系数估计完全相同(= 0.1182)。由于先前拟合返回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背后采用了什么样的算法?
答案 0 :(得分:1)
答案简短:
在这种情况下,GLM使用Moore-Penrose广义逆,pinv,其对应于主成分回归,其中具有零特征值的分量被丢弃。零特征值由numpy.linalg.pinv中的默认阈值(rcond)定义。
statsmodels对共线性没有系统的政策。当矩阵逆运算失败时,一些非线性优化例程会引发异常。但是,线性回归模型OLS和WLS默认使用广义逆,在这种情况下我们会看到上述行为。
GLM.fit
中的默认优化算法是迭代重加权最小二乘irls
,它使用WLS并继承WLS对于奇异设计矩阵的默认行为。
statsmodels master中的版本还可以选择使用标准的scipy优化器,其中关于奇异或近似奇异设计矩阵的行为将取决于优化算法的细节。