Expected Utility Theory
Expected utility theory is a theory of rational decision making with roots in economics. According to expected utility theory, gambles are evaluated by computing an expected utility, and selecting the gamble with the highest expected utility. The expected utility is computed as a probability weighted sum across all possible outcomes, where the outcomes can undergo a transformation from objective to subjective units called utility. Note that many utility-based models can be conceptualized as a generalization of expected utility theory.
Example
In this example, we will demonstrate how to use expected utility theory with a choice between two gambles.
Load Packages
The first step is to load the required packages.
using Plots
using Random
using UtilityModels
Random.seed!(8741)
Random.TaskLocalRNG()
Create Choice Set
We will consider the following two options in this example: $\mathbf{G}_1 = (58, .20; 56, .20; 2, .60)$ and $\mathbf{G}_2 = (96, .20; 4, .20; 2, .60)$. Note that the package can handle choices between an arbitrary number of options, each with an arbitrary number of outcomes.
gamble1 = Gamble(;
p = [.20, .20, .60],
v = [58, 56, 2]
)
gamble2 = Gamble(;
p = [.20, .20, .60],
v = [96, 4, 2]
)
gambles = [gamble1,gamble2]
2-element Vector{Gamble{Float64}}:
Gamble{Float64}([0.2, 0.2, 0.6], [58.0, 56.0, 2.0])
Gamble{Float64}([0.2, 0.2, 0.6], [96.0, 4.0, 2.0])
Create Model Object
In the code below, we will define parameters for the LBA and create a model object to store the parameter values.
Utility Curvature
The utility curvature parameter $\alpha$ controls whether the utility function is concave, linear, or convex. The utility function is given by:
\[U(x) = \mathrm{sign}(x)|x|^\alpha.\]
The parameter $\alpha$ can be intrepreted in terms of risk profile as follows:
- risk averse: $0 \geq \alpha < 1$
- risk neutral: $\alpha = 1$
- risk seeking: $\alpha > 1$
The utility function $U(x)$ is plotted below for a range of values of $\alpha$.
Show Plotting Code
model = ExpectedUtility()
vals = [-20:.5:20;]
gamble = Gamble(; v = vals)
αs = range(0, 1.5, length = 5)
utilities = [compute_utility(ExpectedUtility(; α) , gamble) for α ∈ αs]
utility_plot = plot(vals, utilities, xlabel = "x", ylabel = "U(x)", labels = αs', legendtitle = "α", grid = false)
utility_plot
Below, we set the $\alpha$ parameter to a value associated with moderate risk aversion.
α = .80
0.8
Decisional Consistency
The parameter $\theta$—sometimes known as decisional consistency or sensitivity—controls how deterministically a model selects the option with the higher expected utility. In the equation below, the probability of selecting $\x_i$ from choice set $\{x_1,\dots, x_n\}$ is computed with the soft max function.
\[\Pr(X = x_i \mid \{x_1, \dots, x_n\}) = \frac{e^{\theta \cdot \mathrm{EU}(x_i)}}{\sum_{j=1}^n e^{\theta \cdot \mathrm{EU}(x_j)}}\]
As shown in the plot below, parameter $\theta$ modulates the choice probability.
Show Plotting Code
vals = [-10:.1:10;]
θs = range(0, 2, length = 5)
probs = [pdf(ExpectedUtility(; α = 1, θ) , [Gamble(; p = [1], v = [0]), Gamble(; p = [1], v=[v])], [1,0]) for v ∈ vals, θ ∈ θs]
prob_plot = plot(reverse!(vals), probs, xlabel = "U(A) - U(B)", ylabel = "Probability A", labels = θs', legendtitle = "θ", grid = false)
prob_plot
We will set $\theta$ to the following value:
θ = 1.0
1.0
Expected Utility Constructor
Now that values have been asigned to the parameters, we will pass them to ExpectedUtility
to generate the model object.
dist = ExpectedUtility(; α, θ)
ExpectedUtility
┌───────────┬───────┐
│ Parameter │ Value │
├───────────┼───────┤
│ α │ 0.80 │
│ θ │ 1.00 │
└───────────┴───────┘
Expected Utility
The expected utilities of each gamble can be computed via mean
as demonstrated below:
mean.(dist, gambles)
2-element Vector{Float64}:
11.20128014604588
9.357266295457723
Standard Deviation Utility
The standard deviation of utilities of each gamble can be computed via std
as demonstrated below:
std.(dist, gambles)
2-element Vector{Float64}:
11.588497959137282
14.595722209785217
The larger standard deviation of the second gamble indicates it is a riskier option.
Simulate Model
Now that the model is defined, we will generate $10$ choices using rand
.
choices = rand(dist, gambles, 10)
2-element Vector{Int64}:
8
2
In the code block above, the output is a sample from a multinomial distribution in which the
Compute Choice Probability
The probability of choosing the first option can be obtained as follows:
pdf(dist, gambles, [1,0])
0.8634227272534111
The relatively high choice probability for the first option makes sense in light of its higher expected value (and lower variance).
Multiple Choice Sets
The logic above can be easily extended to situations involving multiple choice sets by wrapping them in vectors. Consider the following situation involing two repetitions of two choice sets:
choice_sets = [
[
Gamble(; p = [0.20, 0.20, 0.60], v = [58, 56, 2]),
Gamble(; p = [0.20, 0.20, 0.60], v = [96, 4, 2])
],
[
Gamble(; p = [0.45, 0.45, 0.10], v = [58, 56, 2]),
Gamble(; p = [0.45, 0.45, 0.10], v = [96, 4, 2])
]
]
2-element Vector{Vector{Gamble{Float64}}}:
[Gamble{Float64}([0.2, 0.2, 0.6], [58.0, 56.0, 2.0]), Gamble{Float64}([0.2, 0.2, 0.6], [96.0, 4.0, 2.0])]
[Gamble{Float64}([0.45, 0.45, 0.1], [58.0, 56.0, 2.0]), Gamble{Float64}([0.45, 0.45, 0.1], [96.0, 4.0, 2.0])]
Next, we simulate two choices for each choice set:
choices = rand.(dist, choice_sets, [2,2])
2-element Vector{Vector{Int64}}:
[2, 0]
[2, 0]
Finally, we compute the joint choice probabilities for each choice set:
choices = pdf.(dist, choice_sets, choices)
2-element Vector{Float64}:
0.7454988059377182
0.9691721902020233