Distributions fit_mle of distribution type vs distributions with parameters

I try the following, but it does not work.

using Distributions
p = 0.2
x = rand(Bernoulli(0.2),50)
fit_mle(Bernoulli(p), x)
 MethodError: no method matching fit_mle(::Bernoulli{Float64}, ::Vector{Bool})

I know that

fit_mle(Bernoulli, x)

works.
Adding the following seems to do what I want

function fit_mle(g::Distribution{Univariate,Discrete}, args...)
    fit_mle(typeof(g), args...)
end

function fit_mle(g::Distribution{Univariate,Continuous}, args...)
    fit_mle(typeof(g), args...)
end

However, I don’t understand why fit_mle(Bernoulli(p), x) is not authorized (or coded this way)?
Sure, the parameter p does not matter for the usual function where the MLE is explicit.
In my applications, I write extensions of fit_mle to other distributions where the actual parameter p is useful. It can be an initialization for an optimization algorithm.
Or when the distributions are Products or Mixture, the type is not enough and the whole distribution structure is needed.

I’d be more surprised if that did work - the point of fit_mle(Bernoulli, x) is to find p.

This is the same with any type of optimization scheme I know. Say in Optim if I want to find the x that minimizes a function, I would do:

rosenbrock(x) =  (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2
result = optimize(rosenbrock, zeros(2), BFGS())

and not optimize(rosenbrock([1.5, 2.5]), zeros(2), BFGS()).

1 Like

I get your point, the first p = p_ini is just an initial point here not what you look for.
In optimization, it would not work because rosenbrock([1.5, 2.5]) is a scalar and not a function.
For distribution fitting Bernoulli(p) carries the same info as just the type Bernoulli.
In fact, it carries more info because of the p_ini, in some situation it might be useless I agree (like for Benoulli).
Imagine a Product distribution of an Exponential and Normal distribution.
If one were to write a fit_mle(::Type{<:Product}, x) how do you extract the informations over the component of the Product if you just accept the type ? Whereas fit_mle(g::Product, x) has everything you need.
Same thing for a Mixture distribution.

I am still uncomfortable with the types, so there might be a way to do that I do not understand.

Actually product types are parametrized:

julia> typeof(product_distribution(Gamma(),Normal()))
Distributions.ProductDistribution{1, 0, Tuple{Gamma{Float64}, Normal{Float64}}, Continuous, Float64}

julia> 

I agree with you for mixtures though.

Thanks for the heads-up, I did not notice it got updated with v0.25.65 on July 22.

However, note that

# v0.25.64 and bellow
julia> typeof(product_distribution([Gamma(),Normal()]...))
ERROR: MethodError: no method matching product_distribution(::Gamma{Float64}, ::Normal{Float64})

julia> typeof(product_distribution([Gamma(),Normal()]))
Product{Continuous, Distribution{Univariate, Continuous}, Vector{Distribution{Univariate, Continuous}}}
# v0.25.65 and above
julia> typeof(product_distribution([Gamma(),Normal()]...))
Distributions.ProductDistribution{1, 0, Tuple{Gamma{Float64}, Normal{Float64}}, Continuous, Float64}

julia> typeof(product_distribution([Gamma(),Normal()]))
Product{Continuous, Distribution{Univariate, Continuous}, Vector{Distribution{Univariate, Continuous}}}
# -> still use the old (depreacated) Product interface

Indeed, having a similar update for MixtureModels would answer my concern and unify the interface.

# v0.25.65 and above
julia> typeof(product_distribution([Gamma(),Normal()]...))
Distributions.ProductDistribution{1, 0, Tuple{Gamma{Float64}, Normal{Float64}}, Continuous, Float64}

julia> typeof(product_distribution([Gamma(),Normal()]))
Product{Continuous, Distribution{Univariate, Continuous}, Vector{Distribution{Univariate, Continuous}}}
# -> still use the old (depreacated) Product interface

This looks like a bug and should be reported.

I opened an issue.