The code below is an emulation of the Sleeping Beauty Problem that supports the thirder interpretation.
I had originally set out to prove the halfer position (the code for that can be found even further down in this notebook) but found an error in my experiment after seeing Silvia Milano's paper Bayesian Beauty. So I'm a thirder now. Anyway, here's the code:
###
# This runs the experiment [repititions] times, checking to see
# how well a given bet (either heads or tails) performs in
# the Sleeping Beauty Problem.
###
function sleeping_beauty_experiment(repititions, bet)
# Number of times Sleeping Beauty's bet is correct
correct_bets = 0
# To see how well SB does, we need to see how often
# she's right compared to the number of times she's woken up.
# This is different than the number of times we run the experiment
# because on tails, she gets woken up and interviewed *twice*
wakeups = 0
for i = 1:repititions
coin_result = rand(["heads", "tails"])
# On Monday, sleeping beauty makes a bet
# (she is awoken Monday whether the coin
# is heads or tails)
correct_bets += coin_result == bet
wakeups += 1
# However, if the coin is tails we will
# wake her up *again* on Teusday and
# she will make another bet
if coin_result == "tails"
# If the coin was tails, we
# interview SB a second time
correct_bets += coin_result == bet
wakeups += 1
end
# Note that on tails, she makes two bets.
# One on Monday, and another on Teusday.
# Thus out of 100 experiments, she should
# be awoken (and therefore interviewed) ~150 times
end
# Our result is the number of correct bets
# SB made out of the total number of times
# she is awoken.
correct_bets / wakeups
end
heads_result = sleeping_beauty_experiment(100_000, "heads")
tails_result = sleeping_beauty_experiment(100_000, "tails")
## Approximate decimals to two decimal places for friendlier presentation
rounded_heads_pct = round(heads_result * 100, digits=2)
rounded_tails_pct = round(tails_result * 100, digits=2)
println("When Sleeping Beauty guesses heads she is right $(rounded_heads_pct)% of the time")
println("When Sleeping Beauty guesses tails she is right $(rounded_tails_pct)% of the time")
In the original simulation, I hadn't accounted for SB being woken up twice every tails. Instead, I had treated it as though she would be interviewed on either tails(monday) | tails(tuesday). If that were the case, the halfer position would be the correct one.
Here is the original Python code, for those who are curious to see my mistake:
import random
from collections import OrderedDict
def experiment_result(coin, day):
return OrderedDict({
"coin": coin,
"day": day
})
# This runs an emulation of the SB problem and returns
# one of the possible coin/day outcomes (ie, flips a coin
# and wakes up SB on a given day so she can guess which
# day it is).
def emulate_sleeping_beauty():
"""
returns 1 of 3 possible states:
{ "coin": "heads", "day": "monday"}
{ "coin": "tails", "day": "monday"}
{ "coin": "tails", "day": "tuesday"}
"""
coin_toss = random.choice(["heads", "tails"])
if coin_toss == "heads":
# the probability of entering this
# possible world is 50%
return experiment_result("heads", "monday")
# If we make it here, then the coin
# came up false. We enter this possible world
# 50% of the time.
# Sleeping beauty is being woken up on either
# Monday or Tuesday. The odds of either are equal,
# so during each emulation we decide randomly
# which day it is currently
current_day = random.choice(["monday", "tuesday"])
if current_day == "monday":
# The odds between monday and teusday
# if the coin is tails are 50:50.
# But recall we only have a 50% chance
# of getting tails.
# 50% (chance of tails) * 50% (chance of monday within tails) = 25%.
# So there's a 25% chance we enter this possible world.
return experiment_result("tails", "monday")
# The only remaining possibility the coin lands on tails
# AND it is not monday, is that the coin landed on tails
# and it is tuesday. Since monday and teusday are equally
# likely within the tails world, this has the same
# likelihood as the previous possible world: 25%
return experiment_result("tails", "tuesday")
# We emulate a sleeping beauty experiment and have her bet
# whether the coin landed on heads or tails
def make_bet(guess):
emulation_result = emulate_sleeping_beauty()
coin, day = emulation_result.values()
return coin == guess
repititions = 100_000
# Now we will run the experiment 100,000 times
# (to reduce statistical noise) and see whether we
# get heads 1/3 or 1/2 of the time, or something
# else entirely!
wins = [make_bet("heads") for i in range(repititions)].count(True)
# This consistently gives a result within 1 percent of 50%
win_pct = wins / repititions * 100
print(f"If sleeping beauty always bets on heads, she is right {win_pct}% of the time")
I would have preferred the halfer position to be right, honestly. That's what I really learned from this: that I have a profound bias in favor of quirky, obscure intellectual positions. I wonder to what extent my worldview is colored by this prejudice.
I also wonder how committed I really want to be towards 'overcoming bias'. Afterall, I experience the world from an intrinsically biased place, that is, as myself. There must be a balance to strike between colorful subjectivity and cold, hard facts. But I don't think I've found it yet.
When I code up an experiment to solve it, I promise I'll share that too <3
Improvements to this notebook are encouraged! This is my first time using Julia so my usage is probably suboptimal and unidiomatic. Go here to contribute: https://github.com/seisvelas/SleepingJulia