通过负对数似然最小化在逻辑模型中进行参数估计 - R
Parameter estimation in logistic model by negative log-likelihood minimization - R
我目前正在尝试通过最小化交叉熵在 iris
数据集上“手动”估计逻辑回归模型的参数。请注意,当我说 iris
数据集时,它已被更改为只有两个 类 - Setosa 和其他。它也通过 scale
函数标准化:
library(dplyr)
library(optimx)
iriso <- iris %>%
mutate(Species = ifelse(Species == "setosa", "setosa", "other")) %>%
mutate(Species_n = ifelse(Species == "setosa", 1, 0)) %>%
as.data.frame()
iriso[,1:4] <- scale(iriso[,1:4])
根据我的理解:如果一切正确,优化完成后我们每次都应该获得相同的参数集——无论优化算法的起点如何。但是,优化后的参数估计值出现了反弹:
正在定义一些函数:
X <- model.matrix(~.,data=iriso[,1:4])
Y <- model.matrix(~0+Species_n,data=iriso)
e <- exp(1)
sigmoid <- function(y){
1/(1 + e^-y)
}
#w is an array of weights. x is matrix of observations
logistique <- function(w, x){
sigmoid(
y = w[1]*x[,1] + w[2]*x[,2] + w[3]*x[,3] + w[4]*x[,4] + w[5]*x[,5]
)
}
#y is obsrved values
entropie <- function(w, y, x){
prob_pred <- logistique(w = w, x = x)
-sum(
y*log(prob_pred) + (1-y)*log(1-prob_pred)
)
}
优化步骤:
for(i in 1:5){
w0 <- rnorm(n = 5) #set of initial parameters
optimx(par = w0, fn = entropie,
method = "Nelder-Mead",
y = iriso$Species_n, x = X) %>%
print()
}
我似乎不明白为什么我得不到一致的答案。上面的代码有问题吗?有没有我不知道的概念?我错过了什么?
谢谢。
主要问题是您的数据集中存在“完全分离”。使用这些预测变量,您可以毫无错误地识别 Species_n
。在这种情况下,logistic 模型没有 MLE,随着估计系数在正确方向上变得越来越极端,它会越来越好。
检测此问题的方法是查看预测概率或对数。当我 运行 你的模型一次时,我得到的估计是
[1] -21.208757 -3.827454 4.601657 -5.271226 -25.119453
这些估计给出了 y
个绝对值都大于 13 的值(logits),因此概率基本上为零或一。
其他几个小问题:
计算e^-y
没有意义,你可以直接使用exp(-y)
并且会更快得到相同的结果。
直接计算log(prob_pred)
和log(1-prob_pred)
很可能会很不准确,或者给出上溢或下溢。最好以分析的方式计算出这些表达式,这样您就不会在 prob_pred
的极值处出现舍入误差。例如1-prob_pred = exp(-y)/(1 + exp(-y))
,所以log(1-prob_pred) = -y-log(1 + exp(-y)) = -y-log1p(exp(-y))
.
我目前正在尝试通过最小化交叉熵在 iris
数据集上“手动”估计逻辑回归模型的参数。请注意,当我说 iris
数据集时,它已被更改为只有两个 类 - Setosa 和其他。它也通过 scale
函数标准化:
library(dplyr)
library(optimx)
iriso <- iris %>%
mutate(Species = ifelse(Species == "setosa", "setosa", "other")) %>%
mutate(Species_n = ifelse(Species == "setosa", 1, 0)) %>%
as.data.frame()
iriso[,1:4] <- scale(iriso[,1:4])
根据我的理解:如果一切正确,优化完成后我们每次都应该获得相同的参数集——无论优化算法的起点如何。但是,优化后的参数估计值出现了反弹:
正在定义一些函数:
X <- model.matrix(~.,data=iriso[,1:4])
Y <- model.matrix(~0+Species_n,data=iriso)
e <- exp(1)
sigmoid <- function(y){
1/(1 + e^-y)
}
#w is an array of weights. x is matrix of observations
logistique <- function(w, x){
sigmoid(
y = w[1]*x[,1] + w[2]*x[,2] + w[3]*x[,3] + w[4]*x[,4] + w[5]*x[,5]
)
}
#y is obsrved values
entropie <- function(w, y, x){
prob_pred <- logistique(w = w, x = x)
-sum(
y*log(prob_pred) + (1-y)*log(1-prob_pred)
)
}
优化步骤:
for(i in 1:5){
w0 <- rnorm(n = 5) #set of initial parameters
optimx(par = w0, fn = entropie,
method = "Nelder-Mead",
y = iriso$Species_n, x = X) %>%
print()
}
我似乎不明白为什么我得不到一致的答案。上面的代码有问题吗?有没有我不知道的概念?我错过了什么?
谢谢。
主要问题是您的数据集中存在“完全分离”。使用这些预测变量,您可以毫无错误地识别 Species_n
。在这种情况下,logistic 模型没有 MLE,随着估计系数在正确方向上变得越来越极端,它会越来越好。
检测此问题的方法是查看预测概率或对数。当我 运行 你的模型一次时,我得到的估计是
[1] -21.208757 -3.827454 4.601657 -5.271226 -25.119453
这些估计给出了 y
个绝对值都大于 13 的值(logits),因此概率基本上为零或一。
其他几个小问题:
计算
e^-y
没有意义,你可以直接使用exp(-y)
并且会更快得到相同的结果。直接计算
log(prob_pred)
和log(1-prob_pred)
很可能会很不准确,或者给出上溢或下溢。最好以分析的方式计算出这些表达式,这样您就不会在prob_pred
的极值处出现舍入误差。例如1-prob_pred = exp(-y)/(1 + exp(-y))
,所以log(1-prob_pred) = -y-log(1 + exp(-y)) = -y-log1p(exp(-y))
.