Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean MCMCChains, remove type piracy, and do not invalidate methods in Base #175

Merged
merged 15 commits into from
Feb 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
language: julia

# avoid duplicate tests in PRs
branches:
only:
- master

os:
- linux
# - osx

julia:
- 1.0
- 1.3
- nightly

matrix:
Expand All @@ -16,15 +22,8 @@ matrix:
notifications:
email: false

#script:
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
# - julia -e "
# using Pkg;
# Pkg.clone(pwd(), \"MCMCChain\");
# Pkg.build(\"MCMCChain\");
# Pkg.test(\"MCMCChain\"; coverage=true)
# "

after_success:
- julia -e 'using Pkg; cd(Pkg.dir("MCMCChain")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'

- if [[ $TRAVIS_JULIA_VERSION = 1.3 ]] && [[ $TRAVIS_OS_NAME = linux ]]; then
julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())';
julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())';
fi
8 changes: 2 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
KernelDensity = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Expand All @@ -25,18 +23,16 @@ AbstractMCMC = "~0.1, 0.2, 0.3"
AxisArrays = "^0.3, 0.4"
DataFrames = "^0.19, 0.20"
Distributions = "^0.21, 0.22"
KernelDensity = "^0.5"
RecipesBase = "^0.7, 0.8"
Showoff = "^0.3"
SpecialFunctions = "^0.8, 0.9, 0.10"
StatsBase = "^0.32"
Turing = "^0.7"
julia = "^1"

[extras]
KernelDensity = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Turing = "fce5fe82-541a-59a6-adf8-730c64b5f9a0"

[targets]
test = ["StatsPlots", "Test", "Turing"]
test = ["KernelDensity", "StatsPlots", "Test", "Turing"]
67 changes: 37 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,23 @@ The following simple example illustrates how to use Chain to visually summarize
using MCMCChains
using StatsPlots

theme(:ggplot2);
theme(:ggplot2)

# Define the experiment
n_iter = 500;
n_name = 3;
n_chain = 2;
n_iter = 500
n_name = 3
n_chain = 2

# experiment results
val = randn(n_iter, n_name, n_chain) .+ [1, 2, 3]';
val = hcat(val, rand(1:2, n_iter, 1, n_chain));
val = randn(n_iter, n_name, n_chain) .+ [1, 2, 3]'
val = hcat(val, rand(1:2, n_iter, 1, n_chain))

# construct a Chains object
chn = Chains(val);
chn = Chains(val)

# visualize the MCMC simulation results
p1 = plot(chn)
p2 = plot(chn, colordim = :parameter)

```
This code results in the visualizations shown below. Note that the plot function takes the additional arguments described in the [Plots.jl](https://github.com/JuliaPlots/Plots.jl) package.

Expand Down Expand Up @@ -176,27 +175,27 @@ Note that `x.P` is a tuple which has to be indexed by the relevant index, while
Options for method are `[:weiss, :hangartner, :DARBOOT, MCBOOT, :billinsgley, :billingsleyBOOT]`

```julia
discretediag(c::AbstractChains; frac=0.3, method=:weiss, nsim=1000)
discretediag(c::Chains; frac=0.3, method=:weiss, nsim=1000)
```

#### Gelman, Rubin, and Brooks Diagnostics
```julia
gelmandiag(c::AbstractChains; alpha=0.05, mpsrf=false, transform=false)
gelmandiag(c::Chains; alpha=0.05, mpsrf=false, transform=false)
```

#### Geweke Diagnostic
```julia
gewekediag(c::AbstractChains; first=0.1, last=0.5, etype=:imse)
gewekediag(c::Chains; first=0.1, last=0.5, etype=:imse)
```

#### Heidelberger and Welch Diagnostics
```julia
heideldiag(c::AbstractChains; alpha=0.05, eps=0.1, etype=:imse)
heideldiag(c::Chains; alpha=0.05, eps=0.1, etype=:imse)
```

#### Raftery and Lewis Diagnostic
```julia
rafterydiag(c::AbstractChains; q=0.025, r=0.005, s=0.95, eps=0.001)
rafterydiag(c::Chains; q=0.025, r=0.005, s=0.95, eps=0.001)
```

### Model Selection
Expand All @@ -217,30 +216,31 @@ DIC, pD = dic(chn, lpfun)
### Plotting
```julia
# construct a plot
plot(c::AbstractChains, seriestype = (:traceplot, :mixeddensity))
plot(c::Chains, seriestype = (:traceplot, :mixeddensity))

# construct trace plots
plot(c::AbstractChains, seriestype = :traceplot)
plot(c::Chains, seriestype = :traceplot)

# or for all seriestypes use the alternative shorthand syntax
traceplot(c::AbstractChains)
traceplot(c::Chains)

# construct running average plots
meanplot(c::AbstractChains)
meanplot(c::Chains)

# construct density plots
density(c::AbstractChains)
density(c::Chains)

# construct histogram plots
histogram(c::AbstractChains)
histogram(c::Chains)

# construct mixed density plots
mixeddensity(c::AbstractChains)
mixeddensity(c::Chains)

# construct autocorrelation plots
autocorplot(c::AbstractChains)
autocorplot(c::Chains)

# make a cornerplot (requires StatPlots) of parameters in a Chain:
corner(c::AbstractChains, [:A, :B])
corner(c::Chains, [:A, :B])
```

### Saving and Loading Chains
Expand Down Expand Up @@ -277,7 +277,7 @@ Array(chns, append_chains=false)
Array(chns, remove_missing_union=false)

# This will not convert the Array columns from a
`Union{Missing, Real}` to a `Vector{Real}`.
# `Union{Missing, Real}` to a `Vector{Real}`.
```

Similarly, for DataFrames:
Expand All @@ -291,27 +291,34 @@ DataFrame(chns, append_chains=false)
DataFrame(chns, remove_missing_union=false)
```

See also ?MCMCChains.DataFrame and ?MCMCChains.Array for more help.
See also `?DataFrame` and `?Array` for more help.

### Sampling Chains

MCMCChains overloads several `sample()` methods as defined in StatsBase:
MCMCChains overloads several `sample` methods as defined in StatsBase:

```julia
# Sampling `n` samples from the chain `a`. Optionally
# weighting the samples using `wv`.
sample([rng], a, [wv::AbstractWeights], n::Integer)

# E.g. creating 10000 weighted samples:
c = kde(Array(chn[:s]))
chn_weighted_sample = sample(c.x, Weights(c.density), 100000)

# As above, but supports replacing and ordering.
sample([rng], a, [wv::AbstractWeights], n::Integer; replace=true,
ordered=false)
```

See also ?MCMCChains.sample for additional help.
See also `?sample` for additional help. Alternatively, you can construct
and sample from a kernel density estimator using the KernelDensity package:

```julia
using KernelDensity

# Construct a kernel density estimator
c = kde(Array(chn[:s]))

# Generate 10000 weighted samples from the grid points
chn_weighted_sample = sample(c.x, Weights(c.density), 100000)
```

## License Notice
Note that this package heavily uses and adapts code from the Mamba.jl package licensed under MIT License, see License.md.
9 changes: 0 additions & 9 deletions REQUIRE

This file was deleted.

47 changes: 19 additions & 28 deletions src/MCMCChains.jl
Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
module MCMCChains

using AbstractMCMC

import Statistics
import Showoff: showoff
import StatsBase: autocor, autocov, countmap, counts, describe, predict,
quantile, sample, sem, summarystats, sample, AbstractWeights
import LinearAlgebra: diag
import Serialization: serialize, deserialize
import Base: sort, range, names, get, hash, convert, show, display
import Statistics: cor, mean
import Core.Array
import DataFrames: DataFrame, names, eachcol

using RecipesBase
import RecipesBase: plot
using AxisArrays
const axes = Base.axes

using Serialization
using AbstractMCMC
using DataFrames: eachcol
import DataFrames: DataFrame
using Distributions
using KernelDensity
using RecipesBase
using SpecialFunctions
using AxisArrays
const axes = Base.axes
using StatsBase: autocov, counts, sem, AbstractWeights
import StatsBase: autocor, describe, quantile, sample, summarystats

export Chains, getindex, setindex!, chains, setinfo, chainscat
export describe, set_section, get_params, sections, set_names
export sample, AbstractWeights
export Array, DataFrame, sort_sections, convert
export summarize, summarystats, ChainDataFrame
export hpd, ess
using LinearAlgebra: diag
import Serialization: serialize, deserialize
import Random
import Statistics: std, cor, mean

export Chains, chains, chainscat
export set_section, get_params, sections, sort_sections, setinfo, set_names
export mean
export autocor, describe, sample, summarystats, AbstractWeights
export ChainDataFrame, DataFrame
export summarize

# export diagnostics functions
export discretediag, gelmandiag, gewekediag, heideldiag, rafterydiag
export autocor
export hpd, ess

"""
Chains type
Expand All @@ -53,9 +46,7 @@ struct Chains{A, T, K<:NamedTuple, L<:NamedTuple} <: AbstractChains
info::L
end

# imports
include("utils.jl")

include("chains.jl")
include("constructors.jl")
include("summarize.jl")
Expand Down
Loading