/
beta.jl
119 lines (84 loc) · 2.81 KB
/
beta.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
doc"""
Beta(α,β)
The *Beta distribution* has probability density function
$f(x; \alpha, \beta) = \frac{1}{B(\alpha, \beta)}
x^{\alpha - 1} (1 - x)^{\beta - 1}, \quad x \in [0, 1]$
The Beta distribution is related to the [`Gamma`](:func:`Gamma`) distribution via the
property that if $X \sim \operatorname{Gamma}(\alpha)$ and $Y \sim \operatorname{Gamma}
(\beta)$ independently, then $X / (X + Y) \sim \operatorname{Beta}(\alpha, \beta)$.
```julia
Beta() # equivalent to Beta(1.0, 1.0)
Beta(a) # equivalent to Beta(a, a)
Beta(a, b) # Beta distribution with shape parameters a and b
params(d) # Get the parameters, i.e. (a, b)
```
External links
* [Beta distribution on Wikipedia](http://en.wikipedia.org/wiki/Beta_distribution)
"""
immutable Beta <: ContinuousUnivariateDistribution
α::Float64
β::Float64
function Beta(α::Real, β::Real)
@check_args(Beta, α > zero(α) && β > zero(β))
new(α, β)
end
Beta(α::Real) = Beta(α, α)
Beta() = new(1.0, 1.0)
end
@distr_support Beta 0.0 1.0
#### Parameters
params(d::Beta) = (d.α, d.β)
#### Statistics
mean(d::Beta) = ((α, β) = params(d); α / (α + β))
function mode(d::Beta)
(α, β) = params(d)
(α > 1.0 && β > 1.0) || error("mode is defined only when α > 1 and β > 1.")
return (α - 1.0) / (α + β - 2.0)
end
modes(d::Beta) = [mode(d)]
function var(d::Beta)
(α, β) = params(d)
s = α + β
return (α * β) / (abs2(s) * (s + 1.0))
end
meanlogx(d::Beta) = ((α, β) = params(d); digamma(α) - digamma(α + β))
varlogx(d::Beta) = ((α, β) = params(d); trigamma(α) - trigamma(α + β))
stdlogx(d::Beta) = sqrt(varlogx(d))
function skewness(d::Beta)
(α, β) = params(d)
if α == β
return 0.0
else
s = α + β
(2.0 * (β - α) * sqrt(s + 1.0)) / ((s + 2.0) * sqrt(α * β))
end
end
function kurtosis(d::Beta)
α, β = params(d)
s = α + β
p = α * β
6.0 * (abs2(α - β) * (s + 1.0) - p * (s + 2.0)) / (p * (s + 2.0) * (s + 3.0))
end
function entropy(d::Beta)
α, β = params(d)
s = α + β
lbeta(α, β) - (α - 1.0) * digamma(α) - (β - 1.0) * digamma(β) +
(s - 2.0) * digamma(s)
end
#### Evaluation
@_delegate_statsfuns Beta beta α β
gradlogpdf(d::Beta, x::Float64) =
((α, β) = params(d); 0.0 <= x <= 1.0 ? (α - 1.0) / x - (β - 1.0) / (1 - x) : 0.0)
#### Sampling
rand(d::Beta) = StatsFuns.RFunctions.betarand(d.α, d.β)
#### Fit model
# TODO: add MLE method (should be similar to Dirichlet)
# This is a moment-matching method (not MLE)
#
function fit{T<:Real}(::Type{Beta}, x::AbstractArray{T})
x_bar = mean(x)
v_bar = varm(x, x_bar)
α = x_bar * (((x_bar * (1.0 - x_bar)) / v_bar) - 1.0)
β = (1.0 - x_bar) * (((x_bar * (1.0 - x_bar)) / v_bar) - 1.0)
Beta(α, β)
end