如何处理R警告:glm.fit算法未收敛

1,424 阅读3分钟

你在R中可能遇到的一个常见警告是:

glm.fit: algorithm did not converge

当你试图在R中拟合一个逻辑回归模型,并且遇到完全分离的情况时,往往会出现这种警告--也就是说,一个预测变量能够将响应变量完全分离成0和1。

下面的例子显示了如何在实践中处理这个警告。

如何重现该警告

假设我们试图在R中拟合以下逻辑回归模型:

#create data frame
df <- data.frame(x=c(.1, .2, .3, .4, .5, .6, .7, .8, .9, 1, 1, 1.1, 1.3, 1.5, 1.7),
                 y=c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1))

#attempt to fit logistic regression model
glm(y~x, data=df, family="binomial")

Call:  glm(formula = y ~ x, family = "binomial", data = df)

Coefficients:
(Intercept)            x  
     -409.1        431.1  

Degrees of Freedom: 14 Total (i.e. Null);  13 Residual
Null Deviance:	    20.19 
Residual Deviance: 2.468e-09 	AIC: 4
Warning messages:
1: glm.fit: algorithm did not converge 
2: glm.fit: fitted probabilities numerically 0 or 1 occurred 

注意,我们收到了警告信息:glm.fit:算法没有收敛

我们收到这个消息是因为预测变量x能够完美地将响应变量y分成0和1。

请注意,对于每个小于1的x值,y等于0;而对于每个等于或大于1的x值,y等于1。

下面的代码显示了这样一种情况:预测变量不能完美地将响应变量分成0和1。

#create data frame
df <- data.frame(x=c(.1, .2, .3, .4, .5, .6, .7, .8, .9, 1, 1, 1.1, 1.3, 1.5, 1.7),
                 y=c(0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1))

#fit logistic regression model
glm(y~x, data=df, family="binomial")

Call:  glm(formula = y ~ x, family = "binomial", data = df)

Coefficients:
(Intercept)            x  
     -2.112        2.886  

Degrees of Freedom: 14 Total (i.e. Null);  13 Residual
Null Deviance:	    20.73 
Residual Deviance: 16.31 	AIC: 20.31

我们没有收到任何警告信息,因为预测变量不能完美地将响应变量分成0和1。

如何处理警告

如果我们遇到了完全分离的情况,有两种方法可以处理它。

方法一:使用惩罚性回归

一种选择是使用某种形式的惩罚性逻辑回归,如拉索逻辑回归或弹性网正则化。

关于如何在R中实现惩罚性逻辑回归的选项,请参考glmnet包。

方法2:用预测变量来完美预测响应变量

如果你怀疑人口中可能存在这种完美分离,你可以简单地使用该预测变量来完美预测响应变量的值。

例如,在上面的情景中,我们看到,当预测变量x小于1时,响应变量y总是等于0。

如果我们怀疑这种关系在整个人群中成立,我们可以直接预测当x小于1时y的值将等于0,而不必担心拟合一些惩罚性的逻辑回归模型。

其他资源

下面的教程提供了关于在R中使用glm()函数的额外信息:

R中glm和lm的区别
如何在R中使用glm的predict函数
如何处理:glm.fit:拟合的概率在数值上发生了0或1