Comments (14)
Maybe we should just create a new German word or something.
from soss.jl.
For reference, here are some not-very-thorough-and-potentially-wrong mappings to other packages:
arguments
- Stan: some
data
- PyMC3: some
named_vars
- ArviZ:
constant_data
variables
- Stan: some
assigned
for LHS ofAssign
(=) statements- Stan:
transformed data
andtransformed parameters
- PyMC3:
deterministics
- ArviZ:
posterior
/prior
variables
- Stan:
sampled
for LHS ofSample
(~) statements- Stan:
parameters
and somedata
- PyMC3:
free_RVs
andobserved_RVs
- ArviZ:
posterior
/prior
/-predictive
/observed_data
variables
- Stan:
parameters(m) = union(assigned(m), sampled(m))
- Stan: some
data
,transformed data
,transformed parameters
,parameters
- PyMC3: some
named_vars
- Stan: some
variables(m) = union(arguments(m), parameters(m))
- Stan:
data
,transformed data
,transformed parameters
,parameters
- PyMC3:
named_vars
- Stan:
That's a mess. I'm fine with the variable subsets you've given. I see arguments
and parameters
probably being the most used.
from soss.jl.
Great idea, thank you Seth!
I think we're done with the "better named subsets" issue, so I'll close this
from soss.jl.
My first reaction is that I like all of these except maybe the last 2. The Soss perspective is still new for me.
What is the intuition behind all LHS being "parameters"? And in what sense are the arguments variable? As I understand it, they're variable in the sense that different arguments can be passed, but you're using the word "arguments" for that, not "variable". In the context of that specific model, they're fixed, not variable. My intuition is that "parameters" and "variable" make more sense swapped, because (nearly) everything on the LHS will follow a distribution, and the term "parameters" is so generic and hence could describe anything in the model.
One more category of interest might be "observations" or "fixed", something that would normally be dependent on other random variables but due to conditioning is fixed. e.g. observations. But I don't know if observations in Soss are ever handled differently from any other parameter.
from soss.jl.
"variables" is always a weird term, because mathematically it's often used to mean "a value bound to a name" more than "a thing that changes". Haskell and SSA languages still talk about variables ;)
In statistical analysis, its really common to talk about estimation or inference on parameters, or sampling from the posterior distribution over the parameters.
Observations in the usual sense aren't really a thing in Soss, or maybe more accurately some values might be observed, but we don't know ahead of time which those might be.
Yeah, naming things is hard
from soss.jl.
julia> m = @model σ2 begin
σ = sqrt(σ2)
x ~ Normal(0,σ)
end;
julia> truth = rand(m(σ2 = 100))
(σ2 = 100, σ = 10.0, x = 9.972715385552725)
julia> arguments(m,truth)
(σ2 = 100,)
julia> assigned(m,truth)
(σ = 10.0,)
julia> sampled(m,truth)
(x = 9.972715385552725,)
julia> parameters(m,truth)
(σ = 10.0, x = 9.972715385552725)
julia> variables(m,truth)
(σ2 = 100, σ = 10.0, x = 9.972715385552725)
from soss.jl.
Awesome! There seems to be some issue showing a model in the REPL once arguments are passed to it.
This motivates some nice convenience functions:
using Soss, NamedTupleTools
function sample_posterior_predictive(
m::Soss.JointDistribution,
observations::NamedTuple,
posterior::AbstractVector{<:NamedTuple}
)
arg_keys = arguments(m.model)
obs_keys = keys(observations)
var_keys = (setdiff(parameters(m.model), obs_keys)...,)
nonobs_keys = (var_keys..., arg_keys...)
pred = predictive(m.model, var_keys...)
post_pred = map(posterior) do draw
delete(rand(pred(merge(draw, m.args))), nonobs_keys)
end
return particles(post_pred)
end
function sample_prior_with_predictive(
m::Soss.JointDistribution,
observations::NamedTuple,
N::Int
)
obs_keys = keys(observations)
var_keys = (setdiff(parameters(m.model), obs_keys)...,)
prior_with_pred = parameters(m.model, particles(m, N))
prior = select(prior_with_pred, var_keys)
prior_pred = delete(prior_with_pred, var_keys)
return prior, prior_pred
end
This makes it really easy to get ArviZ groups. e.g.
julia> using Random; Random.seed!(42);
julia> model = Soss.@model (J, σ) begin
μ ~ Normal(0, 5)
τ ~ HalfCauchy(5)
θ ~ Normal(μ, τ) |> iid(J)
y ~ For(1:J) do j
Normal(θ[j], σ[j])
end
end;
julia> nsamples = 1000
julia> obs = (y = [28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0],);
julia> args = (J = 8, σ = [15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]);
julia> post = dynamicHMC(param_model, obs, logpdf, nsamples);
julia> prior, prior_pred = sample_prior_with_predictive(param_model, obs, length(post));
julia> post_pred = sample_posterior_predictive(param_model, obs, post);
julia> (posterior = particles(post), posterior_predictive = post_pred, prior = prior, prior_predictive = prior_pred, observed_data = obs, constant_data = args)
(posterior = (τ = 3.7 ± 3.2, μ = 4.15 ± 3.1, θ = Particles{Float64,1000}[6.08 ± 5.6, 4.62 ± 4.5, 3.67 ± 5.3, 4.52 ± 5.0, 3.39 ± 4.3, 3.91 ± 5.0, 5.93 ± 4.9, 4.82 ± 5.0]), posterior_predictive = (y = Particles{Float64,1000}[6.37 ± 16.0, 4.59 ± 11.0, 4.01 ± 17.0, 4.57 ± 12.0, 3.17 ± 10.0, 4.02 ± 12.0, 6.25 ± 12.0, 4.78 ± 19.0],), prior = (μ = 3.36e-16 ± 5.0, τ = 26.8 ± 220.0, θ = Particles{Float64,1000}[2.33 ± 170.0, -9.06 ± 240.0, -7.05 ± 220.0, -6.44 ± 170.0, -9.12 ± 280.0, -0.988 ± 100.0, 6.06 ± 160.0, -0.128 ± 190.0]), prior_predictive = (y = Particles{Float64,1000}[2.33 ± 170.0, -9.06 ± 240.0, -7.05 ± 220.0, -6.44 ± 170.0, -9.12 ± 280.0, -0.988 ± 100.0, 6.06 ± 160.0, -0.128 ± 190.0],), observed_data = (y = [28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0],), constant_data = (J = 8, σ = [15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]))
Would it be useful to have convenience functions like these in Soss? Do you think this will be a common workflow, or should we make these more general?
from soss.jl.
I really like the idea of having some helper functions for this sort of thing, but it feels awkward to me to pass in the observations. After inference, we'll have values for the sampled parameters. What do you think of adding methods like
predictive(::JointDistribution, posterior::Vector{NamedTuple})
predictive(::JointDistribution, posterior::NamedTuple) # for particles-based approach
from soss.jl.
So something like
function predict(d::Soss.JointDistribution, post::Vector{NamedTuple{N,T}}) where {N,T}
args = d.args
m = d.model
pred = predictive(m, keys(post[1])...)
map(nt -> rand(pred(merge(args,nt))), post)
end
julia> particles(param_model) |> pairs
pairs(::NamedTuple) with 6 entries:
:J => 8
:σ => [15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]
:τ => 26.8 ± 220.0
:μ => 4.43e-16 ± 5.0
:θ => Particles{Float64,1000}[9.4 ± 250.0, -5.75 ± 150.0, -1.61 ± 57.0, -9.3 ± 2…
:y => Particles{Float64,1000}[9.4 ± 250.0, -5.75 ± 150.0, -1.61 ± 59.0, -9.3 ± 2…
julia> predict(param_model, post) |> particles |> pairs
pairs(::NamedTuple) with 4 entries:
:J => 8.0 ± 0.0
:σ => Particles{Float64,1000}[15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]
:θ => Particles{Float64,1000}[5.98 ± 5.9, 4.33 ± 4.9, 3.18 ± 5.0, 4.4 ± 5.1, 2.7…
:y => Particles{Float64,1000}[6.86 ± 16.0, 4.35 ± 11.0, 2.78 ± 17.0, 4.49 ± 12.0…
from soss.jl.
I like this implementation of predict
. It's weird that the arguments would end up as particles, but I guess the version that takes in particles could avoid that. What would that version look like?
And since this is so general, the variable doesn't need to be post
and could be draws
or sample
or something.
from soss.jl.
Good point, I think we could just merge back with the original arguments to avoid constant particles
from soss.jl.
Oh wait, maybe that's not right. The particles
is outside the function
from soss.jl.
Oh I see, you mean the one that takes particles as an argument. This is in dev
, but particles version isn't yet working correctly
from soss.jl.
Oh you know what, it would be good for these to be implemented with the first argument as an AbstractRNG
and that have these versions forward. So
function predict(rng::AbstractRNG, d::JointDistribution, post::Vector{NamedTuple{N,T}}) where {N,T}
args = d.args
m = d.model
pred = predictive(m, keys(post[1])...)
map(nt -> rand(rng, pred(merge(args,nt))), post)
end
function predict(rng::AbstractRNG, m::Model, post::Vector{NamedTuple{N,T}}) where {N,T}
pred = predictive(m, keys(post[1])...)
map(nt -> rand(rng, pred(nt)), post)
end
predict(args...; kwargs...) = predict(Random.GLOBAL_RNG, args...; kwargs...)
I'm planning to look through and see how we can better support user-provided RNGs. Looks complicated but will make testing a lot easier.
from soss.jl.
Related Issues (20)
- What am I doing wrong? HOT 3
- Examples page in documentation does not exist HOT 1
- sample(...) does not work HOT 9
- No more Soss.predict() methods for densities from Distributions.jl HOT 3
- Implemention of Gaussian mixture model fails when sampling the posterior HOT 4
- Collision of filenames on OS X HOT 3
- Int argument for predict function HOT 2
- Follow Traditional Style Guide? (At least in public API)
- Help fitting a simple t distribution HOT 4
- For(...) do i ... broken using Soss with [email protected] or later HOT 4
- Empty model in predict HOT 6
- Modeling discrete variables
- CSV interference HOT 1
- dynamicHMC UndefVarError
- Can't use M as variable name HOT 4
- Precompilation warning HOT 2
- Example in Readme fails HOT 7
- README example fails HOT 32
- Empty transform with (new) Soss.as HOT 4
- Unable to sample posterior of the MC example from JuliaCon 2021 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from soss.jl.