Agent-based modelling, Konstanz, 2024
23 April 2024
Learner’s grammar | String received | Update |
---|---|---|
\(G_1\) | \(s \in L_1\) | increase \(p\) |
\(G_1\) | \(s \in L_2 \setminus L_1\) | decrease \(p\) |
\(G_2\) | \(s \in L_2\) | decrease \(p\) |
\(G_2\) | \(s \in L_1 \setminus L_2\) | increase \(p\) |
How can we increase/decrease \(p\) in practice? What is the update formula?
Answer
One possibility (which we will stick to):
The parameter \(0 < \gamma < 1\) is a learning rate
"S1"
, "S12"
and "S2"
, and to the probabilities as P1
, P12
and P2
:String type | Probability | Explanation |
---|---|---|
"S1" |
P1 |
\(s \in L_1 \setminus L_2\) |
"S12" |
P12 |
\(s \in L_1 \cap L_2\) |
"S2" |
P2 |
\(s \in L_2 \setminus L_1\) |
sample()
which lives in the StatsBase
packageNow to sample a string, you can do the following:
function sample_string(x::LearningEnvironment)
sample(["S1", "S12", "S2"], Weights([x.P1, x.P12, x.P2]))
end
sample_string (generic function with 1 method)
How would you implement point 2, i.e. picking a grammar to try and parse the incoming string?
function learn!(x::VariationalLearner, y::LearningEnvironment)
s = sample_string(y)
g = pick_grammar(x)
end
learn! (generic function with 1 method)
if
block is necessary; elseif
and else
are optional, and there may be more than one elseif
blocknumber
:Important
To compare equality of two values inside a condition, you must use a double equals sign, ==
. This is because the single equals sign, =
, is already reserved for assigning values to variables.
if ... elseif ... else ... end
block to finish off our learn!
function&&
, logical “or” is ||
Learner’s grammar | String received | Update |
---|---|---|
\(G_1\) | \(s \in L_1\) | increase \(p\) |
\(G_1\) | \(s \in L_2 \setminus L_1\) | decrease \(p\) |
\(G_2\) | \(s \in L_2\) | decrease \(p\) |
\(G_2\) | \(s \in L_1 \setminus L_2\) | increase \(p\) |
Answer
Important! The following function, which we originally used, has a bug! It does not update the learner’s state with input strings from \(L_1 \cap L_2\). See below for fixed version.
function learn!(x::VariationalLearner, y::LearningEnvironment)
s = sample_string(y)
g = pick_grammar(x)
if g == "G1" && s == "S1"
x.p = x.p + x.gamma * (1 - x.p)
elseif g == "G1" && s == "S2"
x.p = x.p - x.gamma * x.p
elseif g == "G2" && s == "S2"
x.p = x.p - x.gamma * x.p
elseif g == "G2" && s == "S1"
x.p = x.p + x.gamma * (1 - x.p)
end
return x.p
end
Answer
function learn!(x::VariationalLearner, y::LearningEnvironment)
s = sample_string(y)
g = pick_grammar(x)
if g == "G1" && s != "S2"
x.p = x.p + x.gamma * (1 - x.p)
elseif g == "G1" && s == "S2"
x.p = x.p - x.gamma * x.p
elseif g == "G2" && s != "S1"
x.p = x.p - x.gamma * x.p
elseif g == "G2" && s == "S1"
x.p = x.p + x.gamma * (1 - x.p)
end
return x.p
end
learn! (generic function with 1 method)
1000-element Vector{Float64}:
0.5097500248005
0.514652524552495
0.5195059993069701
0.5143109393139004
0.5191678299207614
0.5239761516215538
0.5287363901053382
0.5334490262042848
0.5381145359422419
0.5327333905828194
0.5374060566769913
0.5420319961102213
0.5466116761491191
⋮
0.8043883364948524
0.7963444531299039
0.7983810085986048
0.7903971985126188
0.7924932265274927
0.7945682942622178
0.7966226113195956
0.7986563852063996
0.7906698213543356
0.7927631231407922
0.7948354919093843
0.7968871369902905