使用 Flux.jl 的逻辑回归
Logistic regression using Flux.jl
我有一个数据集,其中包含 2 个科目的学生成绩以及学生是否被大学录取的结果。我需要对数据执行逻辑回归并找到最佳参数 θ 以最小化损失并预测测试数据的结果。我不是要在这里构建任何复杂的非线性网络。
数据是这样的
我像这样为逻辑回归定义了损失函数,效果很好
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
end
end
for i = 1:400
back!(L)
update!((θ, b))
@show L
end
您可以使用 GLM.jl(更简单)或 Flux.jl(更复杂但通常更强大)。
在代码中,我生成了数据,以便您可以检查结果是否正确。另外我有一个二进制响应变量——如果你有目标变量的其他编码,你可能需要稍微改变一下代码。
这是 运行 的代码(您可以调整参数以提高收敛速度 - 我选择了安全的参数):
using GLM, DataFrames, Flux.Tracker
srand(1)
n = 10000
df = 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
end
end
i = 1
while true
back!(loss(x,y))
max(maximum(abs.(W.grad)), abs(b.grad[1])) > 0.001 || break
update!((W, b))
i += 1
end
结果如下:
julia> model # GLM result
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}}
Formula: y ~ 1 + s1 + s2
Coefficients:
Estimate Std.Error z value Pr(>|z|)
(Intercept) 0.910347 0.0789283 11.5338 <1e-30
s1 2.18707 0.123487 17.7109 <1e-69
s2 0.556293 0.115052 4.83513 <1e-5
julia> (b, W, i) # Flux result with number of iterations needed to converge
(param([0.910362]), param([2.18705; 0.556278]), 1946)
感谢这个有用的例子。但是,我的设置(Julia 1.1,Flux 0.7.1.)似乎没有 运行,因为预测和损失函数中的 1+ 和 1- 操作不会在 TrackedArray 对象上广播。幸运的是修复很简单(注意点!):
predict(x) = 1.0 ./ (1.0 .+ exp.(-x*W .- b))
loss(x,y) = -sum(log.(predict(x[y,:]))) - sum(log.(1 .- predict(x[.!y,:])))
我有一个数据集,其中包含 2 个科目的学生成绩以及学生是否被大学录取的结果。我需要对数据执行逻辑回归并找到最佳参数 θ 以最小化损失并预测测试数据的结果。我不是要在这里构建任何复杂的非线性网络。
数据是这样的
我像这样为逻辑回归定义了损失函数,效果很好
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
end
end
for i = 1:400
back!(L)
update!((θ, b))
@show L
end
您可以使用 GLM.jl(更简单)或 Flux.jl(更复杂但通常更强大)。 在代码中,我生成了数据,以便您可以检查结果是否正确。另外我有一个二进制响应变量——如果你有目标变量的其他编码,你可能需要稍微改变一下代码。
这是 运行 的代码(您可以调整参数以提高收敛速度 - 我选择了安全的参数):
using GLM, DataFrames, Flux.Tracker
srand(1)
n = 10000
df = 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
end
end
i = 1
while true
back!(loss(x,y))
max(maximum(abs.(W.grad)), abs(b.grad[1])) > 0.001 || break
update!((W, b))
i += 1
end
结果如下:
julia> model # GLM result
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}}
Formula: y ~ 1 + s1 + s2
Coefficients:
Estimate Std.Error z value Pr(>|z|)
(Intercept) 0.910347 0.0789283 11.5338 <1e-30
s1 2.18707 0.123487 17.7109 <1e-69
s2 0.556293 0.115052 4.83513 <1e-5
julia> (b, W, i) # Flux result with number of iterations needed to converge
(param([0.910362]), param([2.18705; 0.556278]), 1946)
感谢这个有用的例子。但是,我的设置(Julia 1.1,Flux 0.7.1.)似乎没有 运行,因为预测和损失函数中的 1+ 和 1- 操作不会在 TrackedArray 对象上广播。幸运的是修复很简单(注意点!):
predict(x) = 1.0 ./ (1.0 .+ exp.(-x*W .- b))
loss(x,y) = -sum(log.(predict(x[y,:]))) - sum(log.(1 .- predict(x[.!y,:])))