### 逻辑回归梯度下降算法与R内置GLM函数的系数差异

我一直在尝试用R语言编写一个逻辑回归的梯度下降算法,以便更好地理解它。在Andrew NG的机器学习课程中,他们似乎跳过了这部分,而是展示了高级优化方法。然而,我希望自己重新创建梯度下降方法。这是我的尝试:

###我的数据
X <- c(34.62366, 30.28671, 35.84741, 60.18260, 79.03274)
X <- cbind(rep(1,5),X)
y <- c(0, 0, 0, 1, 1)
###用于计算预测概率的sigmoid函数
sigmoid <- function(z) {
  #SIGMOID 计算sigmoid函数
  z <- as.matrix(z)
  g <- matrix(0,dim(z)[1],dim(z)[2])
  g <- 1 / (1 + exp(-1 * z))
  g
}
###梯度下降
theta <-  c(0,0)
iterations <- 15000
alpha <- 0.02
m <- length(y)
for (i in 1:iterations) {
  theta_prev = theta
  p = dim(X)[2]
  for (j in 1:p) {
    h <- sigmoid(X %*% theta_prev)
    #sigmoid的导数
    deriv <- (t(h - y) %*% X[,j]) / m
    theta[j] = theta_prev[j] - (alpha * deriv)
  }
}

这给我带来了最终的系数-11.95和0.24,而使用R中的GLM函数,我得到的是-90.87和1.89。有人知道我的代码哪里出错了么?

这是GLM模型的代码:

X <- X[,2]
mod <- glm(y ~ X, family = 'binomial')
coef(mod)

提前感谢!

编辑:使用这个更大的数据集,它没有完全分离,系数之间的差异仍然存在。即使使用更大的100个观测值的数据集,差异仍然存在。

X <- c(34.62366, 30.28671, 35.84741, 60.18260, 79.03274, 45.08328, 61.10666,   75.02475, 76.09879, 84.43282, 95.86156, 75.01366, 82.30705, 69.36459, 39.53834)
X <- cbind(rep(1,5),X)
y <- c(0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0)

使用这个稍大的数据集,我的尝试返回的系数是-18.46和0.15,而R的GLM返回的是-4.12和0.07。


回答:

你看到的问题是由于你的数据引起的。你的数据可以被多个平面分开。查看这个讨论 http://r.789695.n4.nabble.com/glm-fit-quot-fitted-probabilities-numerically-0-or-1-occurred-quot-td849242.html

请注意,当我尝试使用glm()时,我得到了一个警告

glm.fit: glm.fit: "fitted probabilities numerically 0 or 1 occurred"

这应该给你一个提示,表明有些地方不对。基本上,你会发现有无限个平面可以分开你的点(可以说,你所有的0都在左边,所有的1都在右边)。我在链接中提到的讨论中对此有很好的解释。你的自开发GD返回的值取决于你的起始值(试试看!),因为有几个值是可以接受的…以

theta <-  c(20,20)

开始会得到

> theta
[1] -18.6533438   0.3883605

在图中你可以看到我用你的方法在不同起始条件下得到的三条线,如你所见,它们都能很好地分开你的点…

enter image description here

希望这对你有帮助。祝好,Umberto

编辑:查看过你的数据后,我认为你的数据不是线性可分的(与你最初的数据所暗示的相反)。glm给出的模型实际上并不工作。用summary(mod)检查

Coefficients:            Estimate Std. Error z value Pr(>|z|)  (Intercept) -4.11494    2.32945  -1.766   0.0773 .X[, 2]       0.06759    0.03527   1.916   0.0553 .

检查错误和z值… 所以我个人不会太重视你从glm得到的结果… 而你的代码给出的结果(如预期)取决于初始值… 顺便说一下,为了用你的代码和超参数得到稳定的结果,你需要更多的迭代… 还在继续检查,找到更多信息后会更新答案。

编辑2:有了些进展。如果你使用以下参数

theta <-  c(-4,0.05)
iterations <- 1000000
alpha <- 0.001

从你的方法中你会得到

> theta
[1] -4.11500250  0.06758884

而从glm中你会得到

> coef(mod)
(Intercept)      X[, 2] 
-4.11493568  0.06758787 

所以是相同的值(好吧,非常非常接近)。现在请注意,如果你使用初始参数c(0,0),你仍然会得到相同的结果… 所以这是学习率的问题(如果你选择的学习率太大,你的参数就不会收敛)。我检查了theta值的行为,发现参数在两个值之间振荡,这是学习率过大的明显迹象。此外,你需要更多的迭代才能收敛…

在图中展示了截距相对于迭代次数的行为,以给你一个概念…

enter image description here

希望这对你有帮助,Umberto

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注