在数据分析领域,逻辑回归是一种常用的分类算法。但是,许多从业者对于逻辑回归背后的数学原理并不熟悉。本文的目标是揭示如何在不使用内置函数的情况下实现逻辑回归,以帮助读者更好地理解这一算法。
逻辑回归是一种估计Logit函数的方法。Logit函数简单地说就是事件发生的赔率的对数。这个函数创建了一个S形曲线,与所需的概率估计非常相似。
接下来,需要定义试图优化的函数,以获得系数的估计值。这个函数类似于线性回归中误差的平方,被称为似然函数。
考虑到似然函数复杂的导数,考虑一个单调函数,可以复制似然函数并简化导数。这就是似然函数的对数,也就是Log Likelihood。
最后,有Log Likelihood函数的导数。以下是Log Likelihood函数的第一和第二导数。
有了这些导数,将应用牛顿-拉弗森方法来收敛到最优解。以下是牛顿-拉弗森方法的回顾。
牛顿-拉弗森方法是一种寻找函数根的迭代方法,它利用函数的导数来加速收敛。在逻辑回归中,使用这种方法来找到最优的系数。
# 计算似然函数的第一导数
calculateder <- function(y,x,pi) {
derv <- y*x - pi*x
derv_sum <- sum(derv)
return(derv_sum)
}
# 计算似然函数
calculatell <- function(y,pi) {
ll <- 1
ll_unit <- 1:length(y)
for (i in 1:length(y)){
ll_unit[i] <- ifelse(y[i] == 1,pi[i],1-pi[i])
ll = ll_unit[i]*ll
}
return(ll)
}
# 计算pi(每个观测的预测值)给定x_new(输入)和估计的beta
findpi <- function(x_new,beta){
pi <- 1:nrow(x_new)
expon <- 1:nrow(x_new)
for (i in 1:nrow(x_new)){
expon[i] <- 0
for (j in 1:ncol(x_new)){
expo <- x_new[i,j] * beta[j]
expon[i] <- expo + expon[i]}
pi[i] <- exp(expon[i])/(1+exp(expon[i]))
}
return(pi)
}
# 计算矩阵W,所有对角线值为pi
findW <- function(pi){
W <- matrix(0,length(pi),length(pi))
for (i in 1:length(pi)){
W[i,i] <- pi[i]*(1-pi[i])
}
return(W)
}
# 制作逻辑函数,给定所需的输入列表
logistic <- function(x,y,vars,obs,learningrate,dif) {
beta <- rep(0, (vars+1))
bias <- rep(1, obs)
x_new <- cbind(bias,x)
derivative <- 1:(vars+1)
diff <- 10000
while(diff > dif) {
pi <- findpi(x_new,beta)
pi <- as.vector(pi)
W <- findW(pi)
derivative <- (solve(t(x_new)%*%W%*%as.matrix(x_new))) %*% (t(x_new)%*%(y - pi))
beta = beta + derivative
diff <- sum(derivative^2)
ll <- calculatell(y,pi)
print(ll)
}
return(beta)
}
# 用文章开头提到的值测试算法
x <- 1:10
y <- c(rep(0, 4),1,0,1,0,1,1)
a <- logistic(x,y,1,10,0.01,0.000000001)
calculatell(y,findpi(x_new,a))