从零开始实现逻辑回归

在数据分析领域,逻辑回归是一种常用的分类算法。但是,许多从业者对于逻辑回归背后的数学原理并不熟悉。本文的目标是揭示如何在不使用内置函数的情况下实现逻辑回归,以帮助读者更好地理解这一算法。

数学术语回顾

逻辑回归是一种估计Logit函数的方法。Logit函数简单地说就是事件发生的赔率的对数。这个函数创建了一个S形曲线,与所需的概率估计非常相似。

接下来,需要定义试图优化的函数,以获得系数的估计值。这个函数类似于线性回归中误差的平方,被称为似然函数。

似然函数

考虑到似然函数复杂的导数,考虑一个单调函数,可以复制似然函数并简化导数。这就是似然函数的对数,也就是Log Likelihood。

Log Likelihood

最后,有Log Likelihood函数的导数。以下是Log Likelihood函数的第一和第二导数。

导数与Hessian矩阵

有了这些导数,将应用牛顿-拉弗森方法来收敛到最优解。以下是牛顿-拉弗森方法的回顾。

牛顿-拉弗森方法

牛顿-拉弗森方法是一种寻找函数根的迭代方法,它利用函数的导数来加速收敛。在逻辑回归中,使用这种方法来找到最优的系数。

# 计算似然函数的第一导数 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))
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485