Skip to content

Commit cfca5e8

Browse files
committed
update docs
1 parent f027a45 commit cfca5e8

File tree

6 files changed

+140
-54
lines changed

6 files changed

+140
-54
lines changed

Examples/Delay_Discounting/Run_Delay_Discounting.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ include("Delay_Discounting.jl")
1212
#######################################################################################
1313
# Define Model
1414
#######################################################################################
15-
Random.seed!(1204)
15+
Random.seed!(12034)
1616
prior = [Uniform(-5, 5), Uniform(-5, 50)]
1717

1818
model = Model(;prior, loglike)

Examples/Monetary_Gambles/Run_Monetary_Gamble.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ using Pkg
99
Pkg.activate("../../")
1010
using AdaptiveDesignOptimization, Random, UtilityModels, Distributions
1111
include("TAX_Model.jl")
12+
Random.seed!(25974)
1213
#######################################################################################
13-
# Define Model
14+
# Define Parameters
1415
#######################################################################################
15-
Random.seed!(25974)
1616

1717
# model with default uniform prior
1818
model = Model(;loglike)
@@ -34,7 +34,7 @@ design_list = (design_names,design_vals[1:100])
3434

3535
data_list = (choice=[true, false],)
3636
#######################################################################################
37-
# Simulate Experiment
37+
# Optimize Experiment
3838
#######################################################################################
3939
using DataFrames
4040
true_parms ==-1.0, β=1.0, γ=.7, θ=1.5)

Examples/Monetary_Gambles/TAX_Model.jl

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1+
"""
2+
*loglike*
3+
4+
Computes the log likelihood for the TAX model.
5+
* `δ`: transfer of attention parameter
6+
* `γ`: probability weighting parameter
7+
* `β`: utility curvature parameter
8+
* `θ`: decision consistency parameter
9+
* `pa`: outcome probabilities for gamble a
10+
* `va`: outcome values for gamble a
11+
* `pb`: outcome probabilities for gamble b
12+
* `vb`: outcome values for gamble b
13+
14+
Function Signature
15+
```julia
16+
loglike(δ, β, γ, θ, pa, va, pb, vb, data)
17+
```
18+
"""
119
function loglike(δ, β, γ, θ, pa, va, pb, vb, data)
220
eua,eub = expected_utilities(δ, β, γ, θ, pa, va, pb, vb)
321
p = choice_prob(eua, eub, θ)
4-
p = p == 1 ? 1 - eps() : p
5-
p = p == 0 ? eps() : p
6-
LL = data ? log(p) : log(1 - p)
7-
return LL
22+
p = max(p, eps())
23+
return logpdf(Bernoulli(p), data)
824
end
925

1026
function choice_prob(eua, eub, θ)

README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,84 @@
11
# AdaptiveDesignOptimization
2+
3+
This package is a grid-based approach for performing Bayesian adaptive design optimization. After each observation, the optimizer chooses an experimental design that maximizes mutual information between model parameters and design parameters. In so doing, the optimizer selects designs that minimize the variance in the posterior distribution of model parameters.
4+
# Example
5+
6+
In this example, we will optimize a decision making experiment for the model called Transfer of Attention Exchange (TAX; Birnbaum, 2008). Additional examples can be found in the folder titled Examples. sds
7+
8+
```julia
9+
using AdaptiveDesignOptimization, Random, UtilityModels, Distributions
10+
include("TAX_Model.jl")
11+
Random.seed!(25974)
12+
```
13+
14+
## Define Model
15+
16+
The model object contains a log likelihood function and optional prior distributions. Unless an array of distribution objects is passed as `prior`, uniform distributions will be used by default. Arguments in the log likelihood function must be ordered as follows:
17+
18+
- loglike(model_parameters..., design_parameters..., data..., args...; kwargs...)
19+
20+
`args...` and `kwargs...` are optional arguments that may be preloaded through the `Model` constructor. Enter
21+
22+
```julia
23+
? Model
24+
```
25+
for additional details. The likelihood function for the TAX model (see `TAX_Model.jl`) is defined as:
26+
27+
```julia
28+
function loglike(δ, β, γ, θ, pa, va, pb, vb, data)
29+
eua,eub = expected_utilities(δ, β, γ, θ, pa, va, pb, vb)
30+
p = choice_prob(eua, eub, θ)
31+
p = max(p, eps())
32+
return logpdf(Bernoulli(p), data)
33+
end
34+
```
35+
36+
The model object is contructed with default uniform prior distributions.
37+
38+
```julia
39+
# model with default uniform prior
40+
model = Model(;loglike)
41+
```
42+
## Define Parameters
43+
44+
Define a `NamedTuple` of parameter value ranges. Note that the parameters listed in the same order that they appear in `loglike`.
45+
46+
```julia
47+
parm_list = (
48+
δ = range(-2, 2, length=10),
49+
β = range(.5, 1.5, length=10),
50+
γ = range(.5, 1.2, length=10),
51+
θ = range(.5, 3, length=10)
52+
)
53+
```
54+
55+
The experiment will consist of two gambles with three outcomes each. The number of dimensions in the design space is large (2X2X3X3 = 36). In this case, we will sample random gambles and select a subset of 100 with high distributional overlap. In this case, the `design_list` will be a `Tuple` of design names and design values.
56+
57+
```julia
58+
# outcome distribution
59+
dist = Normal(0,10)
60+
n_vals = 3
61+
n_choices = 2
62+
design_vals = map(x->random_design(dist, n_vals, n_choices), 1:1000)
63+
# select gambles with overlapping distributions
64+
filter!(x->abs_zscore(x) .4, design_vals)
65+
design_names = (:p1,:v1,:p2,:v2)
66+
design_list = (design_names,design_vals[1:100])
67+
```
68+
69+
Lastly, we will define a list for the data. The value true indicates gamble A was choosen and false indicates gamble B was chosen.
70+
71+
```julia
72+
data_list = (choice=[true, false],)
73+
```
74+
## Optimize Exeriment
75+
76+
77+
# References
78+
79+
* Birnbaum, M. H., & Chavez, A. (1997). Tests of theories of decision making: Violations of branch independence and distribution independence. Organizational Behavior and human decision Processes, 71(2), 161-194. Birnbaum, M. H. (2008). New paradoxes of risky decision making. Psychological review, 115(2), 463.
80+
81+
* Myung, J. I., Cavagnaro, D. R., and Pitt, M. A. (2013). A tutorial on adaptive design optimization. Journal of Mathematical Psychology, 57, 53–67.
82+
83+
* Yang, J., Pitt, M. A., Ahn, W., & Myung, J. I. (2020). ADOpy: A Python Package for Adaptive Design Optimization. Behavior Research Methods, 1--24. https://doi.org/10.3758/s13428-020-01386-4
84+

src/functions.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ function loglikelihood!(loglike, log_like, design_grid, parm_grid, data_grid, mo
5656
for (k,design) in enumerate(design_grid)
5757
for (p,parms) in enumerate(parm_grid)
5858
i += 1
59-
log_like[p,k,d] = loglike(parms..., design..., data..., model_state[i])
59+
state = deepcopy(model_state[i])
60+
log_like[p,k,d] = loglike(parms..., design..., data..., state)
6061
end
6162
end
6263
end
@@ -168,6 +169,14 @@ function update!(optimizer::Optimizer{A,MT}, data, args...; kwargs...) where {A,
168169
return best_design
169170
end
170171

172+
function update!(optimizer::Optimizer{A,MT}, data, args...; kwargs...) where {A<:Rand,MT<:Dyn}
173+
update_posterior!(optimizer, data)
174+
update_states!(optimizer, data, args...; kwargs...)
175+
loglikelihood!(optimizer)
176+
best_design = find_best_design!(optimizer)
177+
return best_design
178+
end
179+
171180
function update!(optimizer::Optimizer{A}, data) where {A<:Rand}
172181
update_posterior!(optimizer, data)
173182
best_design = find_best_design!(optimizer)
@@ -176,10 +185,12 @@ end
176185

177186
function update_states!(optimizer, obs_data, args...; kwargs...)
178187
@unpack model_state, data_grid, design_grid, parm_grid, update_state! = optimizer
179-
for (d, data) in enumerate(data_grid)
180-
for (k,design) in enumerate(design_grid)
181-
for (p,parms) in enumerate(parm_grid)
182-
update_state!(model_state, parms, design, data, obs_data, args...; kwargs...)
188+
i = 0
189+
for data in data_grid
190+
for design in design_grid
191+
for parms in parm_grid
192+
i += 1
193+
update_state!(model_state[i], parms, design, data, obs_data, args...; kwargs...)
183194
end
184195
end
185196
end
@@ -238,6 +249,4 @@ end
238249

239250
function create_state(model_type::Stat, T, dims, args...; kwargs...)
240251
return nothing
241-
end
242-
243-
252+
end

src/structs.jl

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ Constructor
3434
````julia
3535
Model(args...; prior=nothing, loglike, kwargs...)
3636
````
37+
*Examples*
38+
39+
```julia
40+
# Default uninform prior
41+
loglike(θ, design, data) = ...
42+
43+
model = Model(;loglike)
44+
```
45+
46+
```julia
47+
# Custom priors
48+
prior = [Beta(5,5),...]
49+
loglike(θ, design, data) = ...
50+
51+
model = Model(;loglike, prior)
52+
```
3753
"""
3854
mutable struct Model{F<:Function,P}
3955
prior::P
@@ -66,44 +82,6 @@ Constructor
6682
Optimizer(;task, model, grid_design, grid_parms, grid_response)
6783
````
6884
# """
69-
# mutable struct Optimizer{A,M<:Model,T1,T2,T3,T4,T5,T6,T7,T8,T9}
70-
# approach::A
71-
# model::M
72-
# design_grid::T1
73-
# parm_grid::T2
74-
# data_grid::T3
75-
# log_like::Array{Float64,3}
76-
# marg_log_like::T4
77-
# priors::T5
78-
# log_post::Vector{Float64}
79-
# entropy::T6
80-
# marg_entropy::Vector{Float64}
81-
# cond_entropy::Vector{Float64}
82-
# mutual_info::Vector{Float64}
83-
# best_design::T7
84-
# parm_names::T8
85-
# design_names::T9
86-
# end
87-
88-
# function Optimizer(; model, design_list, parm_list, data_list, approach=Optimize)
89-
# design_names,design_grid = to_grid(design_list)
90-
# parm_names,parm_grid = to_grid(parm_list)
91-
# _,data_grid = to_grid(data_list)
92-
# log_like = loglikelihood(model, design_grid, parm_grid, data_grid)
93-
# priors = prior_probs(model, parm_grid)
94-
# post = priors[:]
95-
# log_post = log.(post)
96-
# entropy = compute_entropy(log_like)
97-
# marg_log_like = marginal_log_like(log_post, log_like)
98-
# marg_entropy = marginal_entropy(marg_log_like)
99-
# cond_entropy = conditional_entropy(entropy, post)
100-
# mutual_info = mutual_information(marg_entropy, cond_entropy)
101-
# best_design = find_best_design(mutual_info, design_grid, design_names)
102-
# return Optimizer(approach, model, design_grid, parm_grid, data_grid, log_like,
103-
# marg_log_like, priors, log_post, entropy, marg_entropy, cond_entropy,
104-
# mutual_info, best_design, parm_names, design_names)
105-
# end
106-
10785
mutable struct Optimizer{A,MT,M<:Model,T1,T2,T3,T4,T5,T6,T7,T8,T9,
10886
T10,T11}
10987
design_type::A

0 commit comments

Comments
 (0)