Turing.jl icon indicating copy to clipboard operation
Turing.jl copied to clipboard

Coeftable throws error on mle and map estimates

Open manueldeljesus opened this issue 4 years ago • 1 comments

I was just following the examples on the the guide with my own model. I get to the point of obtaining my mle and map estimates. However, when trying to visualize the results with coeftable I get the following error:

Error showing value of type CoefTable:
ERROR: MethodError: Cannot `convert` an object of type Symbol to an object of type String
Closest candidates are:
  convert(::Type{String}, ::CategoricalValue) at /Users/manuel/.julia/packages/CategoricalArrays/0ZAbp/src/value.jl:60
  convert(::Type{T}, ::ProgressLogging.ProgressString) where T<:AbstractString at /Users/manuel/.julia/packages/ProgressLogging/BBN0b/src/ProgressLogging.jl:211
  convert(::Type{T}, ::T) where T<:AbstractString at strings/basic.jl:229
  ...
Stacktrace:
 [1] StatsBase.NoQuote(::Symbol) at /Users/manuel/.julia/packages/StatsBase/EA8Mh/src/statmodels.jl:455
 [2] (::StatsBase.var"#181#184"{CoefTable,Array{AbstractArray{Float64,1},1}})(::Tuple{Int64,Int64}) at ./none:0
 [3] iterate at ./generator.jl:47 [inlined]
 [4] collect(::Base.Generator{Base.Iterators.ProductIterator{Tuple{UnitRange{Int64},UnitRange{Int64}}},StatsBase.var"#181#184"{CoefTable,Array{AbstractArray{Float64,1},1}}}) at ./array.jl:686
 [5] show(::IOContext{REPL.Terminals.TTYTerminal}, ::CoefTable) at /Users/manuel/.julia/packages/StatsBase/EA8Mh/src/statmodels.jl:467
 [6] show(::IOContext{REPL.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::CoefTable) at ./multimedia.jl:47
 [7] display(::REPL.REPLDisplay, ::MIME{Symbol("text/plain")}, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:214
 [8] display(::REPL.REPLDisplay, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:218
 [9] display(::Any) at ./multimedia.jl:328
 [10] #invokelatest#1 at ./essentials.jl:710 [inlined]
 [11] invokelatest at ./essentials.jl:709 [inlined]
 [12] print_response(::IO, ::Any, ::Bool, ::Bool, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:238
 [13] print_response(::REPL.AbstractREPL, ::Any, ::Bool, ::Bool) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:223
 [14] (::REPL.var"#do_respond#54"{Bool,Bool,REPL.var"#64#73"{REPL.LineEditREPL,REPL.REPLHistoryProvider},REPL.LineEditREPL,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:822
 [15] #invokelatest#1 at ./essentials.jl:710 [inlined]
 [16] invokelatest at ./essentials.jl:709 [inlined]
 [17] run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/LineEdit.jl:2355
 [18] run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:1144
 [19] (::REPL.var"#38#42"{REPL.LineEditREPL,REPL.REPLBackendRef})() at ./task.jl:356

I include my code just in case it may be useful:

using Distributions
using Turing
using Optim
using StatsPlots
using StatsBase

x = rand(GeneralizedExtremeValue(5, 2, .1), 1000)

@model function extremos(y)
        μ ~ Normal(0, 3)
        σ ~ TruncatedNormal(2, 2, 1e-2, Inf)
        #σ ~ Normal(0, 1)
        ξ ~ Uniform(-.5, 0.5)
        for n in eachindex(y)
                y[n] ~ GeneralizedExtremeValue(μ, σ, ξ)
        end
end

# Settings of the Hamiltonian Monte Carlo (HMC) sampler.
iterations = 1000

# Start sampling.
#chain = sample(extremos(x), HMC(ϵ, τ), iterations)
chain = sample(extremos(x), NUTS(), iterations);

map_estimate = optimize(extremos(x), MAP(), SimulatedAnnealing(), Optim.Options(iterations=iterations, allow_f_increases=true))
mle_estimate = optimize(extremos(x), MLE(), SimulatedAnnealing(), Optim.Options(iterations=iterations, allow_f_increases=true))
coeftable(map_estimate)

manueldeljesus avatar Oct 28 '20 08:10 manueldeljesus

It seems the problem is https://github.com/JuliaStats/StatsBase.jl/blob/1c3f3d7ae4fd8afae126443d15ddaf8029316618/src/statmodels.jl#L468. I assume it should be changed to

    mat = [j == 1 ? rownms[i] isa AbstractString ? NoQuote(rownms[i]) : rownms[i] :

BTW this code is really difficult to read... If this NoQuote hack is needed, it seems also more natural to just dispatch on the type of its field in the definition of show(io::IO, ::NoQuote).

devmotion avatar Oct 28 '20 15:10 devmotion

Seems not an issue with Turing.

yebai avatar Nov 12 '22 20:11 yebai

But then, shouldn't this be removed from the guide? I was following the guide, literally copying code, and it fails with the same error. I find it disconcerting that procedures mentioned in the guide cannot be run. I suggest removing just the code where we try to get the coeftable. I can open a PR if deemed appropriate.

using Optim
@model function gdemo(x)
    s² ~ InverseGamma(2, 3)
    m ~ Normal(0, sqrt(s²))

    for i in eachindex(x)
        x[i] ~ Normal(m, sqrt(s²))
    end
end
# Create some data to pass to the model.
data = [1.5, 2.0]

# Instantiate the gdemo model with our data.
model = gdemo(data)

# Generate a MLE estimate.
mle_estimate = optimize(model, MLE())

using StatsBase
coeftable(mle_estimate)
julia> coeftable(map_estimate)
Error showing value of type CoefTable:
ERROR: MethodError: Cannot `convert` an object of type Symbol to an object of type String
Closest candidates are:
...

rdiaz02 avatar Dec 31 '22 18:12 rdiaz02

thanks @rdiaz02, for looking into this. We should probably fix the coeftable interface, if possible, or remove these convenient functions from StatsBase if they are hard to fix as noticed by @devmotion. Personally, I don't feel these functions should live in Turing although they might be useful for some users.

yebai avatar Jan 03 '23 15:01 yebai

FWIW (not much ;-) ) I found these functions could definitely be useful. Unfortunately, I am just starting with Turing and Julia, so I do not think I can really offer much for fixing these functions.

rdiaz02 avatar Jan 10 '23 17:01 rdiaz02