我有一组数据,包含学生在两个科目中的成绩以及学生是否被大学录取的结果。我需要对这些数据进行逻辑回归,找到最优参数θ来最小化损失,并预测测试数据的结果。我并不是要构建任何复杂的非线性网络。
我已经定义了逻辑回归的损失函数,运行良好
predict(X) = sigmoid(X*θ)loss(X,y) = (1 / length(y)) * sum(-y .* log.(predict(X)) .- (1 - y) .* log.(1 - predict(X)))
我需要最小化这个损失函数并找到最优的θ。我想使用Flux.jl或任何其他能使其更简单的库来完成。我在阅读了示例后尝试使用Flux.jl,但无法最小化成本。
我的代码片段如下:
function update!(ps, η = .1) for w in ps w.data .-= w.grad .* η print(w.data) w.grad .= 0 endendfor i = 1:400 back!(L) update!((θ, b)) @show Lend
回答:
你可以使用GLM.jl(更简单)或Flux.jl(更复杂但总体上更强大)。在代码中,我生成了数据,以便你可以检查结果是否正确。此外,我有一个二元响应变量——如果你有其他目标变量的编码方式,你可能需要稍微修改代码。
以下是可运行的代码(你可以调整参数以提高收敛速度——我选择了安全的参数):
using GLM, DataFrames, Flux.Trackersrand(1)n = 10000df = DataFrame(s1=rand(n), s2=rand(n))df[:y] = rand(n) .< 1 ./ (1 .+ exp.(-(1 .+ 2 .* df[1] .+ 0.5 .* df[2])))model = glm(@formula(y~s1+s2), df, Binomial(), LogitLink())x = Matrix(df[1:2])y = df[3]W = param(rand(2,1))b = param(rand(1))predict(x) = 1.0 ./ (1.0+exp.(-x*W .- b))loss(x,y) = -sum(log.(predict(x[y,:]))) - sum(log.(1 - predict(x[.!y,:])))function update!(ps, η = .0001) for w in ps w.data .-= w.grad .* η w.grad .= 0 endendi = 1while true back!(loss(x,y)) max(maximum(abs.(W.grad)), abs(b.grad[1])) > 0.001 || break update!((W, b)) i += 1end
结果如下:
julia> model # GLM结果StatsModels.DataFrameRegressionModel{GLM.GeneralizedLinearModel{GLM.GlmResp{Array{Float64,1},Distributions.Binomial{Float64},GLM.LogitLink},GLM.DensePredChol{Float64,Base.LinAlg.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}公式: y ~ 1 + s1 + s2系数: 估计值 标准误 z值 Pr(>|z|)(截距) 0.910347 0.0789283 11.5338 <1e-30s1 2.18707 0.123487 17.7109 <1e-69s2 0.556293 0.115052 4.83513 <1e-5julia> (b, W, i) # Flux结果及收敛所需的迭代次数(param([0.910362]), param([2.18705; 0.556278]), 1946)