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 优化器,其中关于奇异或接近奇异设计矩阵的行为将取决于优化算法的细节。
我是 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 优化器,其中关于奇异或接近奇异设计矩阵的行为将取决于优化算法的细节。