Skip to content
AI360Xpert
Beta

Expected SARSA

Instead of gambling on a single randomly sampled next action, Expected SARSA takes the exact average value over all next actions, weighted by how likely each one is.

Expected SARSA averages the values 20, 10 and minus 100 with weights 0.8, 0.1 and 0.1 to get a steady target, while SARSA gambles on one sample and Q-learning takes only the max
Expected SARSA averages the values 20, 10 and minus 100 with weights 0.8, 0.1 and 0.1 to get a steady target, while SARSA gambles on one sample and Q-learning takes only the max

Why Does This Exist?

Temporal difference learning bootstraps: it updates a guess from another guess. SARSA builds its target from the exact next action the agent happened to sample:

YtSARSA=Rt+1+γQ(St+1,At+1)Y_t^{\text{SARSA}} = R_{t+1} + \gamma Q(S_{t+1}, A_{t+1})

Because At+1A_{t+1} is one random draw from an exploratory policy, this single sample injects noise into every update. Two identical visits to the same state can give wildly different targets: one step samples the good action, the next samples an exploratory blunder. To survive that noise you must shrink the learning rate, and learning crawls.

Q-learning dodges the noise by taking the greedy maximum, max⁡aQ(St+1,a)\max_a Q(S_{t+1}, a). But that assumes perfect future play. In a risky environment where the agent keeps exploring, Q-learning ignores its own future blunders and can march straight into penalties it should have priced in.

Expected SARSA takes the middle path that keeps the honesty without the noise. Instead of rolling the dice on one sampled action, compute the exact average over every next action, weighted by the policy:

YtExp=Rt+1+γ∑a∈Aπ(a∣St+1)Q(St+1,a)Y_t^{\text{Exp}} = R_{t+1} + \gamma \sum_{a \in \mathcal{A}} \pi(a \mid S_{t+1}) Q(S_{t+1}, a)

One draw becomes an expectation. The sampling noise disappears, but the exploratory risk stays in the price.

The one idea you need first: an ϵ\epsilon-greedy policy. With probability 1−ϵ1 - \epsilon it picks the current best action, and with probability ϵ\epsilon it picks uniformly at random. So the best action gets probability 1−ϵ+ϵ/∣A∣1 - \epsilon + \epsilon / |\mathcal{A}| and every other action gets ϵ/∣A∣\epsilon / |\mathcal{A}|.

Think of It Like This

Three ways to grade a course

A course has safe assignments, dull busywork, and one brutal trap question.

The SARSA examiner rolls a die, picks one question, and awards that single score as your whole grade. Roll the safe one and you shine; roll the trap and you fail. Over infinite retakes the average is fair, but every single grade is a lottery ticket.

The Q-learning examiner assumes you answer only the easiest question, ignoring that the rules force you onto harder ones 10 percent of the time.

The Expected SARSA examiner opens the syllabus, multiplies each question by its exact probability, and assigns the weighted average. No dice. Every grade is smooth and predictable, and the trap question still drags the average down exactly as much as its probability warrants.

Where it stops: a syllabus is fixed, while in RL both the policy π\pi and the values QQ shift as the agent learns, so the expectation must be recomputed at every step.

How It Actually Works

Write StS_t for the state, AtA_t for the action taken, Rt+1R_{t+1} for the reward, and St+1S_{t+1} for where you land. The update is:

Q(St,At)←Q(St,At)+α[Rt+1+γ∑a∈Aπ(a∣St+1)Q(St+1,a)−Q(St,At)]Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha \left[ R_{t+1} + \gamma \sum_{a \in \mathcal{A}} \pi(a \mid S_{t+1}) Q(S_{t+1}, a) - Q(S_t, A_t) \right]

Here α\alpha in (0,1](0, 1] is the step size, γ\gamma in [0,1)[0, 1) discounts the future, and π(a∣St+1)\pi(a \mid S_{t+1}) is the probability of each next action under the target policy. The sum is the expected next value, Eπ[Q(St+1,⋅)]\mathbb{E}_{\pi}[Q(S_{t+1}, \cdot)].

Why the variance vanishes

Condition on the transition (St,At,Rt+1,St+1)(S_t, A_t, R_{t+1}, S_{t+1}). Standard SARSA's target varies with the sampled action, so whenever the policy gives positive probability to actions with different values, its variance is positive:

VarAt+1[Rt+1+γQ(St+1,At+1)∣St+1]=γ2VarAt+1[Q(St+1,At+1)]>0\text{Var}_{A_{t+1}}\left[ R_{t+1} + \gamma Q(S_{t+1}, A_{t+1}) \mid S_{t+1} \right] = \gamma^2 \text{Var}_{A_{t+1}}\left[ Q(S_{t+1}, A_{t+1}) \right] > 0

Expected SARSA replaces the draw with its mean, and a mean has no sampling variance:

Var[∑aπ(a∣St+1)Q(St+1,a)  |  St+1]=0\text{Var}\left[ \sum_{a} \pi(a \mid S_{t+1}) Q(S_{t+1}, a) \;\middle|\; S_{t+1} \right] = 0

Only environment noise remains (random transitions and rewards). Lower variance means you can run a larger α\alpha without blowing up, which is why Expected SARSA converges faster than SARSA on tabular benchmarks.

One rule, two policies

Expected SARSA separates the behavior policy bb (what picks actions in the world) from the target policy π\pi (what the expectation uses). Set π=b\pi = b and you get on-policy control: with ϵ\epsilon-greedy behavior the expectation is (1−ϵ)max⁡aQ+(ϵ/∣A∣)∑aQ(1 - \epsilon) \max_a Q + (\epsilon / |\mathcal{A}|) \sum_a Q. Set π\pi to pure greedy (probability 1 on the best action) and the sum collapses to max⁡aQ\max_a Q: that is exactly Q-learning, with no importance sampling correction needed on the next action.

Worked example: the cliff state

The agent takes action East from S0S_0, lands in S1S_1, and gets reward R=−1.0R = -1.0. Settings: α=0.5\alpha = 0.5, γ=0.9\gamma = 0.9, current Q(S0,East)=2.0Q(S_0, \text{East}) = 2.0. State S1S_1 has three actions:

  • a1a_1 (safe path): Q=20.0Q = 20.0, the greedy action
  • a2a_2 (detour): Q=10.0Q = 10.0
  • a3a_3 (cliff edge): Q=−100.0Q = -100.0

Behavior is ϵ\epsilon-greedy with ϵ=0.3\epsilon = 0.3 and ∣A∣=3|\mathcal{A}| = 3: π(a1)=1−0.3+0.3/3=0.8\pi(a_1) = 1 - 0.3 + 0.3/3 = 0.8, π(a2)=0.1\pi(a_2) = 0.1, π(a3)=0.1\pi(a_3) = 0.1.

Expected SARSA first averages the next values:

Eπ[Q(S1,⋅)]=0.8×20.0+0.1×10.0+0.1×(−100.0)=16.0+1.0−10.0=7.0\mathbb{E}_\pi[Q(S_1, \cdot)] = 0.8 \times 20.0 + 0.1 \times 10.0 + 0.1 \times (-100.0) = 16.0 + 1.0 - 10.0 = 7.0

Then the target, the error, and the update:

YExp=−1.0+0.9×7.0=5.3,δ=5.3−2.0=3.3Y^{\text{Exp}} = -1.0 + 0.9 \times 7.0 = 5.3, \quad \delta = 5.3 - 2.0 = 3.3

Q(S0,East)←2.0+0.5×3.3=3.65Q(S_0, \text{East}) \leftarrow 2.0 + 0.5 \times 3.3 = 3.65

Compare. If SARSA samples the safe action: Y=−1.0+0.9×20.0=17.0Y = -1.0 + 0.9 \times 20.0 = 17.0, so Q←2.0+0.5×15.0=9.5Q \leftarrow 2.0 + 0.5 \times 15.0 = 9.5. If it samples the cliff: Y=−1.0+0.9×(−100.0)=−91.0Y = -1.0 + 0.9 \times (-100.0) = -91.0, so Q←2.0+0.5×(−93.0)=−44.5Q \leftarrow 2.0 + 0.5 \times (-93.0) = -44.5. Q-learning always takes the max: Y=17.0Y = 17.0 and Q←9.5Q \leftarrow 9.5. SARSA swings between 9.59.5 and −44.5-44.5 on pure dice luck, Q-learning prices the cliff at zero despite a 10 percent fall chance, and Expected SARSA lands once, deterministically, at 3.653.65.

Code

A pure-Python transcription of the worked example, with all three updates side by side.

q_next = [20.0, 10.0, -100.0]probs = [0.8, 0.1, 0.1]reward = -1.0gamma = 0.9alpha = 0.5q_current = 2.0
expected = sum(p * q for p, q in zip(probs, q_next))target = reward + gamma * expectedupdated = q_current + alpha * (target - q_current)
sarsa_safe = q_current + alpha * ((reward + gamma * q_next[0]) - q_current)sarsa_cliff = q_current + alpha * ((reward + gamma * q_next[2]) - q_current)qlearn = q_current + alpha * ((reward + gamma * max(q_next)) - q_current)
print(round(expected, 2))  # -> 7.0print(round(target, 2))  # -> 5.3print(round(updated, 2))  # -> 3.65print(round(sarsa_safe, 2))  # -> 9.5print(round(sarsa_cliff, 2))  # -> -44.5print(round(qlearn, 2))  # -> 9.5

Watch Out For

Paying full price for the expectation in huge action spaces

SARSA does one array lookup per step and Q-learning does one max scan, but Expected SARSA evaluates the full dot product ∑aπ(a)Q\sum_a \pi(a) Q over every action on every transition. With 4 to 20 actions that is trivial and the variance win pays immediately. With hundreds of thousands of discrete actions, say a recommender, the dot product becomes the bottleneck. In continuous spaces the integral has no closed form at all.

The fix: under ϵ\epsilon-greedy policies, split the sum into (1−ϵ)max⁡aQ+(ϵ/∣A∣)∑aQ(1 - \epsilon) \max_a Q + (\epsilon / |\mathcal{A}|) \sum_a Q in one vectorized pass instead of building the probability vector. For massive spaces, sample K≪∣A∣K \ll |\mathcal{A}| actions to approximate the mean: most of the variance win at a fraction of the cost.

Writing one policy and pricing another

The expectation follows the target policy you wrote, not the behavior you ran. Plug the greedy distribution into the sum while the agent acts ϵ\epsilon-greedy and you are doing Q-learning wearing an Expected SARSA costume, cliff blindness included. Plug the exploratory distribution in while intending to evaluate the greedy policy and you learn a pessimistic value for a policy you never deploy.

The fix: name both policies at the top of your loop and assert which is which. On-policy means the probabilities in the sum match the policy that picked the actions. Any mismatch is off-policy by definition, and then you should say so and check whether the resulting optimism is safe in your environment.

The Quick Version

  • Expected SARSA replaces the single sampled next action Q(St+1,At+1)Q(S_{t+1}, A_{t+1}) with the policy-weighted mean ∑aπ(a∣St+1)Q(St+1,a)\sum_a \pi(a \mid S_{t+1}) Q(S_{t+1}, a).
  • Killing action-sampling variance lets it train stably with larger step sizes than standard SARSA.
  • The cliff example averages 20, 10 and −100-100 with weights 0.8, 0.1 and 0.1 to get 7.0, and updates 2.02.0 to 3.653.65 in one deterministic step.
  • Setting the target policy to greedy reproduces Q-learning exactly, with no importance sampling correction.
  • The price is a full pass over the action set per step, so huge or continuous action spaces need the split-sum trick or a sampled approximation.