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)
Example block output
utility_plot
Example block output

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)
Example block output
prob_plot
Example block output

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