R语言如何修复:glm.fit: algorithm did not converge
在这篇文章中,我们将讨论如何在R编程语言中修复 “glm.fit: algorithm did not converge “错误。
glm.fit: algorithm did not converge 是R语言中的一个警告,在R语言中拟合逻辑回归模型时,在少数情况下会遇到这种情况。为了更好地理解,让我们看一下代码,其中变量x被认为是预测变量,y被认为是响应变量。为了产生警告,让我们以这样的方式来创建数据,即数据是完全可分离的。
产生警告的代码
下面的代码没有产生任何错误,因为程序的退出代码是0,但是遇到了一些警告,其中一个警告是glm.fit: algorithm did not converge。这是由于数据的完美分离造成的。从上述代码中使用的数据来看,对于每一个负的x值,y值为0,对于每一个正的x,y值为1。
# create random data which consists
# of 50 numbers
x < - rnorm(50)
# create data with fifty 1's
y < - rep(1, 50)
# if x value is less than 0 the at that
# index replace 1 with 0 in y
y[x < 0] < - 0
# create dataframe
data < - data.frame(x, y)
# first 6 rows
head(data)
# fitting logistic regression model
glm(y ~ x, data, family="binomial")
输出
x y
1 1.3295285 1
2 -0.9738028 0
3 0.6963700 1
4 -1.1586337 0
5 -1.1001865 0
6 -0.6252191 0
Call: glm(formula = y ~ x, family = “binomial”, data = data)
Coefficients:
(Intercept) x
-13.42 273.54
Degrees of Freedom: 49 Total (i.e. Null); 48 Residual
Null Deviance: 68.03
Residual Deviance: 1.436e-08 AIC: 4
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: fitted probabilities numerically 0 or 1 occurred
[Execution complete with exit code 0]
如何解决这个警告
为了克服这个警告,我们应该修改数据,使预测变量不能完全分离响应变量。为了做到这一点,我们需要在数据中加入一些噪音。下面是不会出现算法不收敛警告的代码。
# create random data which consists of
# 50 numbers
x <- rnorm(50)
# create data with fifty 1's
y <- rep(1, 50)
# if x value is less than 0 the at that
# index replace 1 with 0 in y
y[x < 0] <- 0
# create dataframe
data <- data.frame(x, y)
# first 6 rows
head(data)
# add noise
datax <- datax + rnorm(50)
# first 6 rows after data modification
head(data)
# fitting logistic regression model
glm(y ~ x, data, family = "binomial")
输出
x y
1 -0.5787936 0
2 0.1105818 1
3 -0.5324901 0
4 0.6043288 1
5 -0.2479408 0
6 1.2583220 1
x y
1 0.06909437 0
2 2.01936841 1
3 0.08818184 0
4 0.22230790 1
5 0.19720200 0
6 1.44250592 1
Call: glm(formula = y ~ x, family = “binomial”, data = data)
Coefficients:
(Intercept) x
0.09985 1.97047
Degrees of Freedom: 49 Total (i.e. Null); 48 Residual
Null Deviance: 69.23
Residual Deviance: 40.85 AIC: 44.85
[Execution complete with exit code 0]
在这里,预测变量的原始数据通过添加随机数据(噪声)而被改变。所以它扰乱了原始数据的完全可分性。这个过程是完全基于数据的。如果任何两个变量之间的相关性不自然地非常高,那么试着删除这些观测值并运行模型,直到警告信息不再出现。
警告处理
有两种方法来处理这个glm.fit:算法没有收敛的警告。它们列在下面–
- 使用惩罚性回归
- 使用预测变量来完美地预测响应变量
方法1:使用惩罚性回归
我们可以使用惩罚性的逻辑回归,如套索逻辑回归或弹性网正则化来处理没有收敛警告的算法。为了对数据进行惩罚性回归,使用了glmnet方法,它接受预测变量、响应变量、响应类型、回归类型等。让我们来看看它的语法
语法: glmnet(x, y, family = “binomial”, alpha = 1, lambda = NULL)
其中
- x是预测变量
- y是响应变量
- family表示响应类型,对于二进制响应(0,1)使用二项式
- alpha表示回归类型
- 1代表拉索回归
- 0代表山脊回归
Lambda定义了收缩率
以下是已实现的惩罚性回归代码
# import necessary libraries
library(glmnet)
# create random data which consists
# of 50 numbers
x < - rnorm(50)
# create data with fifty 1's
y < - rep(1, 50)
# if x value is less than 0 the at that
# index replace 1 with 0 in y
y[x < 0] < - 0
# fitting lasso regression model
glmnet(x, y, family="binomial", alpha=1, lambda=NULL)
方法2:使用预测变量来完美地预测响应变量
当给定的数据中存在完美的可分离性时,就很容易通过预测变量找到响应变量的结果。我们在本文中考虑的数据具有明显的可分离性,对于每一个负的预测变量,响应总是为0,对于每一个正的预测变量,响应是1。
例子
下面是在预测方法的帮助下使用预测变量预测响应变量的代码。
# create random data which consists of
# 5 numbers
x < - rnorm(5)
# create data with five 1's
y < - rep(1, 5)
# if x value is less than 0 the at that index
# replace 1 with 0 in y
y[x < 0] < - 0
# create dataframe
data1 < - data.frame(x, y)
data1
# create a linear model
model < - glm(y ~ x, data1, family="binomial")
# predicting response variables
predict(model, newdata=data.frame(y=c(0, 0, 1, 1, 1)))
输出
x y
1 -0.4057154 0
2 1.9408241 1
3 -0.2419725 0
4 0.2374463 1
5 -1.6208003 0
Warning message:
glm.fit: fitted probabilities numerically 0 or 1 occurred
1 2 3 4 5
-39.25575 189.68953 23.27980 23.49574 -157.80817
[Execution complete with exit code 0]