Skip to content

Commit

Permalink
wrapper returns more now
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Agerton committed Sep 15, 2017
1 parent 725cafb commit da9448d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,33 @@
[![Coverage Status](https://coveralls.io/repos/magerton/OrderedResponse.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/magerton/OrderedResponse.jl?branch=master)

[![codecov.io](http://codecov.io/github/magerton/OrderedResponse.jl/coverage.svg?branch=master)](http://codecov.io/github/magerton/OrderedResponse.jl?branch=master)

Estimates ordered logit & probit models. Returns a tuple with the negative log likelihood, gradient, hessian, and the `Optim.MultivariateOptimizationResults` object.

# Example
```julia
using OrderedResponse
using DataFrames
using Optim

# ------- make some data ----------

srand(1234)

n,k = 1000,2
X = randn(n, k)
ϵ = randn(n)

β = [0.2, -1.0]
γ = [-0.4, 0.5]

ystar = X*β + ϵ
y = map((yi) -> searchsortedfirst(γ,yi), ystar)

df = convert(DataFrame, X)
df[:y] = y

# ------- run model ----------
@show orlm(@formula(y ~ 0 + x1 + x2), df, :logit)
@show orlm(@formula(y ~ 0 + x1 + x2), df, :probit)
```
2 changes: 2 additions & 0 deletions src/OrderedResponse.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
__precompile__()

module OrderedResponse

using StatsFuns
Expand Down
16 changes: 8 additions & 8 deletions src/likelihood.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ function LLi!(grad::Vector{T}, hess::Matrix{T}, tmpgrad::Vector, l::Integer, η:
η2 = l == L+1 ? Inf : γ[l] - η

# LL takes a short-cut to improve accuracy if l == 1 or L+1
# if l == 1
# F = cdf(η2, model)
# LL = logcdf(η2, model)
# elseif l == L+1
# F = ccdf(η1, model)
# LL = logccdf(η1, model)
# else
if l == 1
F = cdf(η2, model)
LL = logcdf(η2, model)
elseif l == L+1
F = ccdf(η1, model)
LL = logccdf(η1, model)
else
F = cdf(η2, model) - cdf(η1, model)
LL = log(F)
# end
end

if length(grad) > 0
dlogF1 = pdf(η1, model) / F
Expand Down
17 changes: 15 additions & 2 deletions src/outer-wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ response_vec(y::DataVector{<:Integer}) = Vector(y)
response_vec(mf::ModelFrame) = response_vec(mf.df[:,mf.terms.eterms[1]])

"""
Estimate ordered response of variety `model ∈ (:logit, :probit)` with specification `fm` and `data`. Optim options passed with `kwargs`
orlm(fm::Formula, data::DataFrame, model::Symbol; method=Optim.Newton(), kwargs...)
Estimate ordered response model of variety `model ∈ (:logit, :probit)` with specification
`fm` and `data`. Optim options passed with `kwargs`. Set the optimizer with `method`.
Returns a tuple with negative log likelihood, gradient, hessian, and optimization results
`(LL::Real, grad::Vector, hess::Matrix, opt::Optim.MultivariateOptimizationResults)`
"""
function orlm(fm::Formula, data::DataFrame, model::Symbol; method=Optim.Newton(), kwargs...)

Expand Down Expand Up @@ -38,6 +43,14 @@ function orlm(fm::Formula, data::DataFrame, model::Symbol; method=Optim.Newton()
(hess::Matrix, θ::Vector) -> LL!(zeros(T,KLm1), hess, tmpgrad , η, y, X, θ[1:k], θ[k+1:end], Val{model}, -1.0)
)

return Optim.optimize(td, θ0, method, Optim.Options(;kwargs...))
opt = Optim.optimize(td, θ0, method, Optim.Options(;kwargs...))

# final eval
hess = zeros(T, KLm1, KLm1)
grad = similar(tmpgrad)
θfinal = opt.minimizer
LL = LL!(grad, hess, tmpgrad, η, y, X, θfinal[1:k], θfinal[k+1:end], Val{model}, -1.0)

return (LL, grad, hess, opt)

end

0 comments on commit da9448d

Please sign in to comment.