LeanMachineLearning exposition

2.5. Online.Bandit.Regret🔗

Regret, gap, best arm

Main definitions

  • gap ν a is the gap of an action a, i.e., the difference between the highest mean of the actions and the mean of a.

  • regret ν A t ω is the regret of a sequence of pulls A : ℕ → Ω → 𝓐 at time t for the reward kernel ν : Kernel 𝓐 ℝ and the outcome ω : Ω.

  • bestArm ν is an action with the highest mean.

Module LeanMachineLearning.Online.Bandit.Regret contains 18 exposed declarations.

gap🔗

DefinitionBandits.gap

Gap of an action a: difference between the highest mean of the actions and the mean of a.

🔗def
Bandits.gap.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} (ν : ProbabilityTheory.Kernel 𝓐 ) (a : 𝓐) :
Bandits.gap.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} (ν : ProbabilityTheory.Kernel 𝓐 ) (a : 𝓐) :

Code

noncomputable
def gap (ν : Kernel 𝓐 ℝ) (a : 𝓐) : ℝ := (⨆ i, (ν i)[id]) - (ν a)[id]
Used by (27)

Actions: Source · Open Issue

gap_nonneg🔗

LemmaBandits.gap_nonneg

No docstring.

🔗theorem
Bandits.gap_nonneg.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Finite 𝓐] : 0 gap ν a
Bandits.gap_nonneg.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Finite 𝓐] : 0 gap ν a

Code

lemma gap_nonneg [Finite 𝓐] : 0 ≤ gap ν a
Type uses (1)
Used by (5)

Actions: Source · Open Issue

Proof
by
  rw [gap, sub_nonneg]
  exact le_ciSup (f := fun i ↦ (ν i)[id]) (by simp) a

gap_nonneg_of_le🔗

LemmaBandits.gap_nonneg_of_le

The gap is non-negative if the means are bounded by u : ℝ (even if 𝓐 is not Finite).

🔗theorem
Bandits.gap_nonneg_of_le.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} {u : } (h : (a : 𝓐), (x : ), id x ν a u) : 0 gap ν a
Bandits.gap_nonneg_of_le.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} {u : } (h : (a : 𝓐), (x : ), id x ν a u) : 0 gap ν a

Code

lemma gap_nonneg_of_le {u : ℝ} (h : ∀ a, (ν a)[id] ≤ u) : 0 ≤ gap ν a
Type uses (1)
Used by (1)

Actions: Source · Open Issue

Proof
by
  rw [gap, sub_nonneg]
  exact le_ciSup ⟨u, Set.forall_mem_range.2 h⟩ a

gap_le_of_mem_Icc🔗

LemmaBandits.gap_le_of_mem_Icc

No docstring.

🔗theorem
Bandits.gap_le_of_mem_Icc.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Nonempty 𝓐] {l u : } (h : (a : 𝓐), (x : ), id x ν a Set.Icc l u) : gap ν a u - l
Bandits.gap_le_of_mem_Icc.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Nonempty 𝓐] {l u : } (h : (a : 𝓐), (x : ), id x ν a Set.Icc l u) : gap ν a u - l

Code

lemma gap_le_of_mem_Icc [Nonempty 𝓐] {l u : ℝ} (h : ∀ a, (ν a)[id] ∈ Set.Icc l u) :
    gap ν a ≤ u - l
Type uses (1)
Used by (1)

Actions: Source · Open Issue

Proof
by
  grind [gap, ciSup_le (fun i ↦ (h i).2)]

regret🔗

DefinitionBandits.regret

Regret of a sequence of pulls k : ℕ → 𝓐 at time t for the reward kernel ν ; Kernel 𝓐 ℝ.

🔗def
Bandits.regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} (ν : ProbabilityTheory.Kernel 𝓐 ) (A : Ω 𝓐) (t : ) (ω : Ω) :
Bandits.regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} (ν : ProbabilityTheory.Kernel 𝓐 ) (A : Ω 𝓐) (t : ) (ω : Ω) :

Code

noncomputable
def regret (ν : Kernel 𝓐 ℝ) (A : ℕ → Ω → 𝓐) (t : ℕ) (ω : Ω) : ℝ :=
  t * (⨆ a, (ν a)[id]) - ∑ s ∈ range t, (ν (A s ω))[id]
Used by (11)

Actions: Source · Open Issue

regret_eq_sum_gap🔗

LemmaBandits.regret_eq_sum_gap

No docstring.

🔗theorem
Bandits.regret_eq_sum_gap.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } : regret ν A t ω = s Finset.range t, gap ν (A s ω)
Bandits.regret_eq_sum_gap.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } : regret ν A t ω = s Finset.range t, gap ν (A s ω)

Code

lemma regret_eq_sum_gap : regret ν A t ω = ∑ s ∈ range t, gap ν (A s ω)
Type uses (2)
Used by (3)

Actions: Source · Open Issue

Proof
by
  simp [regret, gap]

regret_nonneg🔗

LemmaBandits.regret_nonneg

No docstring.

🔗theorem
Bandits.regret_nonneg.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Finite 𝓐] : 0 regret ν A t ω
Bandits.regret_nonneg.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Finite 𝓐] : 0 regret ν A t ω

Code

lemma regret_nonneg [Finite 𝓐] : 0 ≤ regret ν A t ω
Type uses (1)
Body uses (3)

Actions: Source · Open Issue

Proof
by
  rw [regret_eq_sum_gap]
  exact sum_nonneg (fun _ _ ↦ gap_nonneg)

gap_eq_zero_of_regret_eq_zero🔗

LemmaBandits.gap_eq_zero_of_regret_eq_zero

No docstring.

🔗theorem
Bandits.gap_eq_zero_of_regret_eq_zero.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Finite 𝓐] (hr : regret ν A t ω = 0) {s : } (hs : s < t) : gap ν (A s ω) = 0
Bandits.gap_eq_zero_of_regret_eq_zero.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Finite 𝓐] (hr : regret ν A t ω = 0) {s : } (hs : s < t) : gap ν (A s ω) = 0

Code

lemma gap_eq_zero_of_regret_eq_zero [Finite 𝓐] (hr : regret ν A t ω = 0) {s : ℕ} (hs : s < t) :
    gap ν (A s ω) = 0
Type uses (2)
Body uses (2)

Actions: Source · Open Issue

Proof
by
  rw [regret_eq_sum_gap] at hr
  exact (sum_eq_zero_iff_of_nonneg fun _ _ ↦ gap_nonneg).1 hr s (mem_range.2 hs)

regret_eq_sum_pullCount_mul_gap🔗

LemmaBandits.regret_eq_sum_pullCount_mul_gap

No docstring.

🔗theorem
Bandits.regret_eq_sum_pullCount_mul_gap.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Fintype 𝓐] : regret ν A t ω = a, (Learning.pullCount A a t ω) * gap ν a
Bandits.regret_eq_sum_pullCount_mul_gap.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {t : } [Fintype 𝓐] : regret ν A t ω = a, (Learning.pullCount A a t ω) * gap ν a

Code

lemma regret_eq_sum_pullCount_mul_gap [Fintype 𝓐] :
    regret ν A t ω = ∑ a, pullCount A a t ω * gap ν a
Type uses (3)
Body uses (2)
Used by (2)

Actions: Source · Open Issue

Proof
by
  simp_rw [regret_eq_sum_gap, sum_pullCount_mul]

integral_regret_eq_sum_gap_mul_integral_pullCount🔗

LemmaBandits.integral_regret_eq_sum_gap_mul_integral_pullCount

No docstring.

🔗theorem
Bandits.integral_regret_eq_sum_gap_mul_integral_pullCount.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} { : MeasurableSpace Ω} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {n : } [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : MeasureTheory.Measure Ω} [MeasureTheory.IsProbabilityMeasure P] (hA : (n : ), Measurable (A n)) : (x : Ω), regret ν A n x P = a, gap ν a * (x : Ω), (fun ω => (Learning.pullCount A a n ω)) x P
Bandits.integral_regret_eq_sum_gap_mul_integral_pullCount.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} { : MeasurableSpace Ω} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {n : } [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : MeasureTheory.Measure Ω} [MeasureTheory.IsProbabilityMeasure P] (hA : (n : ), Measurable (A n)) : (x : Ω), regret ν A n x P = a, gap ν a * (x : Ω), (fun ω => (Learning.pullCount A a n ω)) x P

Code

lemma integral_regret_eq_sum_gap_mul_integral_pullCount
    [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : Measure Ω} [IsProbabilityMeasure P]
    (hA : ∀ n, Measurable (A n)) :
    P[regret ν A n] = ∑ a, gap ν a * P[fun ω ↦ (pullCount A a n ω : ℝ)]
Type uses (3)
Body uses (2)
Used by (1)

Actions: Source · Open Issue

Proof
by
  simp_rw [regret_eq_sum_pullCount_mul_gap]
  rw [integral_finsetSum]
  swap; · exact fun i _ ↦ (integrable_pullCount hA i n).mul_const _
  congr with a
  rw [integral_mul_const, mul_comm]

integral_regret_le_of_forall_integral_pullCount_le🔗

LemmaBandits.integral_regret_le_of_forall_integral_pullCount_le

To bound the expected regret, it suffices to bound the expected number of pulls for each action with positive gap.

🔗theorem
Bandits.integral_regret_le_of_forall_integral_pullCount_le.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} { : MeasurableSpace Ω} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {R : Ω } {n : } [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : MeasureTheory.Measure Ω} [MeasureTheory.IsProbabilityMeasure P] {alg : Learning.Algorithm 𝓐 } {env : Learning.Environment 𝓐 } {B : 𝓐 } (h : Learning.IsAlgEnvSeq A R alg env P) (h_le : (a : 𝓐), gap ν a 0 (ω : Ω), (Learning.pullCount A a n ω) P B a) : (x : Ω), regret ν A n x P a, gap ν a * B a
Bandits.integral_regret_le_of_forall_integral_pullCount_le.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} { : MeasurableSpace Ω} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {R : Ω } {n : } [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : MeasureTheory.Measure Ω} [MeasureTheory.IsProbabilityMeasure P] {alg : Learning.Algorithm 𝓐 } {env : Learning.Environment 𝓐 } {B : 𝓐 } (h : Learning.IsAlgEnvSeq A R alg env P) (h_le : (a : 𝓐), gap ν a 0 (ω : Ω), (Learning.pullCount A a n ω) P B a) : (x : Ω), regret ν A n x P a, gap ν a * B a

Code

lemma integral_regret_le_of_forall_integral_pullCount_le
    [StandardBorelSpace 𝓐] [Fintype 𝓐] {P : Measure Ω} [IsProbabilityMeasure P]
    {alg : Algorithm 𝓐 ℝ} {env : Environment 𝓐 ℝ} {B : 𝓐 → ℝ}
    (h : IsAlgEnvSeq A R alg env P)
    (h_le : ∀ a, gap ν a ≠ 0 → ∫ ω, (pullCount A a n ω : ℝ) ∂P ≤ B a) :
    P[regret ν A n] ≤ ∑ a, gap ν a * B a
Type uses (6)
Body uses (2)
Used by (2)

Actions: Source · Open Issue

Proof
by
  have hA := h.measurable_action
  rw [integral_regret_eq_sum_gap_mul_integral_pullCount hA]
  gcongr 1 with a
  by_cases h_gap : gap ν a = 0
  · simp [h_gap]
  gcongr
  · exact gap_nonneg
  · exact h_le a h_gap

bestArm🔗

DefinitionBandits.bestArm

action with the highest mean.

🔗def
Bandits.bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} [Fintype 𝓐] [Nonempty 𝓐] (ν : ProbabilityTheory.Kernel 𝓐 ) : 𝓐
Bandits.bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} [Fintype 𝓐] [Nonempty 𝓐] (ν : ProbabilityTheory.Kernel 𝓐 ) : 𝓐

Code

noncomputable def bestArm (ν : Kernel 𝓐 ℝ) : 𝓐 :=
  (exists_max_image univ (fun a ↦ (ν a)[id]) (univ_nonempty_iff.mpr inferInstance)).choose
Used by (18)

Actions: Source · Open Issue

le_bestArm🔗

LemmaBandits.le_bestArm

No docstring.

🔗theorem
Bandits.le_bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } [Fintype 𝓐] [Nonempty 𝓐] (a : 𝓐) : (x : ), id x ν a (x : ), id x ν (bestArm ν)
Bandits.le_bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } [Fintype 𝓐] [Nonempty 𝓐] (a : 𝓐) : (x : ), id x ν a (x : ), id x ν (bestArm ν)

Code

lemma le_bestArm (a : 𝓐) : (ν a)[id] ≤ (ν (bestArm ν))[id]
Type uses (1)
Used by (2)

Actions: Source · Open Issue

Proof
(exists_max_image univ (fun a ↦ (ν a)[id])
    (univ_nonempty_iff.mpr inferInstance)).choose_spec.2 _ (mem_univ a)

gap_eq_bestArm_sub🔗

LemmaBandits.gap_eq_bestArm_sub

No docstring.

🔗theorem
Bandits.gap_eq_bestArm_sub.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Fintype 𝓐] [Nonempty 𝓐] : gap ν a = (x : ), id x ν (bestArm ν) - (x : ), id x ν a
Bandits.gap_eq_bestArm_sub.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Fintype 𝓐] [Nonempty 𝓐] : gap ν a = (x : ), id x ν (bestArm ν) - (x : ), id x ν a

Code

lemma gap_eq_bestArm_sub : gap ν a = (ν (bestArm ν))[id] - (ν a)[id]
Type uses (2)
Body uses (1)
Used by (4)

Actions: Source · Open Issue

Proof
by
  rw [gap]
  congr
  refine le_antisymm ?_ (le_ciSup (f := fun a ↦ (ν a)[id]) (by simp) (bestArm ν))
  exact ciSup_le le_bestArm

gap_bestArm🔗

LemmaBandits.gap_bestArm

No docstring.

🔗theorem
Bandits.gap_bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } [Fintype 𝓐] [Nonempty 𝓐] : gap ν (bestArm ν) = 0
Bandits.gap_bestArm.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } [Fintype 𝓐] [Nonempty 𝓐] : gap ν (bestArm ν) = 0

Code

lemma gap_bestArm : gap ν (bestArm ν) = 0
Type uses (2)
Body uses (1)
Used by (1)

Actions: Source · Open Issue

Proof
by
  rw [gap_eq_bestArm_sub, sub_self]

integral_eq_of_gap_eq_zero🔗

LemmaBandits.integral_eq_of_gap_eq_zero

No docstring.

🔗theorem
Bandits.integral_eq_of_gap_eq_zero.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Fintype 𝓐] [Nonempty 𝓐] (hg : gap ν a = 0) : (x : ), id x ν (bestArm ν) = (x : ), id x ν a
Bandits.integral_eq_of_gap_eq_zero.{u_1} {𝓐 : Type u_1} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {a : 𝓐} [Fintype 𝓐] [Nonempty 𝓐] (hg : gap ν a = 0) : (x : ), id x ν (bestArm ν) = (x : ), id x ν a

Code

lemma integral_eq_of_gap_eq_zero (hg : gap ν a = 0) : (ν (bestArm ν))[id] = (ν a)[id]
Type uses (2)
Body uses (1)

Actions: Source · Open Issue

Proof
by
  rwa [← sub_eq_zero, ← gap_eq_bestArm_sub]

avg_mean_reward_tendsto_of_sublinear_regret🔗

LemmaBandits.avg_mean_reward_tendsto_of_sublinear_regret

If the regret is sublinear, the average mean reward tends to the highest mean of the arms.

🔗theorem
Bandits.avg_mean_reward_tendsto_of_sublinear_regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} (hr : (fun x => regret ν A x ω) =o[Filter.atTop] fun t => t) : Filter.Tendsto (fun t => (∑ s Finset.range t, (x : ), id x ν (A s ω)) / t) Filter.atTop (nhds (⨆ a, (x : ), id x ν a))
Bandits.avg_mean_reward_tendsto_of_sublinear_regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} (hr : (fun x => regret ν A x ω) =o[Filter.atTop] fun t => t) : Filter.Tendsto (fun t => (∑ s Finset.range t, (x : ), id x ν (A s ω)) / t) Filter.atTop (nhds (⨆ a, (x : ), id x ν a))

Code

lemma avg_mean_reward_tendsto_of_sublinear_regret
    (hr : (regret ν A · ω) =o[atTop] fun t ↦ (t : ℝ)) :
    Tendsto (fun t ↦ (∑ s ∈ range t, (ν (A s ω))[id]) / (t : ℝ))
      atTop (nhds (⨆ a, (ν a)[id]))
Type uses (1)

Actions: Source · Open Issue

Proof
by
  have ht : Tendsto (fun t ↦ (⨆ a, (ν a)[id]) - regret ν A t ω / t)
      atTop (nhds (⨆ a, (ν a)[id])) := by
    simpa using tendsto_const_nhds.sub hr.tendsto_div_nhds_zero
  apply ht.congr'
  filter_upwards [eventually_ne_atTop 0] with t ht
  rw [regret]
  field_simp
  ring

pullCount_rate_tendsto_of_sublinear_regret🔗

LemmaBandits.pullCount_rate_tendsto_of_sublinear_regret

If the regret is sublinear, the rate of suboptimal arm pulls tends to zero.

🔗theorem
Bandits.pullCount_rate_tendsto_of_sublinear_regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {a : 𝓐} [Finite 𝓐] (hr : (fun x => regret ν A x ω) =o[Filter.atTop] fun t => t) (hg : 0 < gap ν a) : Filter.Tendsto (fun t => (Learning.pullCount A a t ω) / t) Filter.atTop (nhds 0)
Bandits.pullCount_rate_tendsto_of_sublinear_regret.{u_1, u_2} {𝓐 : Type u_1} {Ω : Type u_2} [DecidableEq 𝓐] {m𝓐 : MeasurableSpace 𝓐} {ν : ProbabilityTheory.Kernel 𝓐 } {A : Ω 𝓐} {ω : Ω} {a : 𝓐} [Finite 𝓐] (hr : (fun x => regret ν A x ω) =o[Filter.atTop] fun t => t) (hg : 0 < gap ν a) : Filter.Tendsto (fun t => (Learning.pullCount A a t ω) / t) Filter.atTop (nhds 0)

Code

lemma pullCount_rate_tendsto_of_sublinear_regret [Finite 𝓐]
    (hr : (regret ν A · ω) =o[atTop] fun t ↦ (t : ℝ)) (hg : 0 < gap ν a) :
    Tendsto (fun t ↦ (pullCount A a t ω : ℝ) / t) atTop (nhds 0)
Type uses (3)
Body uses (3)

Actions: Source · Open Issue

Proof
by
  have := Fintype.ofFinite 𝓐
  have hb (t : ℕ) : (pullCount A a t ω : ℝ) * gap ν a ≤ regret ν A t ω := by
    rw [regret_eq_sum_pullCount_mul_gap]
    exact single_le_sum (f := fun a ↦ pullCount A a t ω * gap ν a)
      (fun _ _ ↦ mul_nonneg (Nat.cast_nonneg _) gap_nonneg) (mem_univ a)
  have hb' (t : ℕ) : (pullCount A a t ω : ℝ) / t ≤ regret ν A t ω / t / gap ν a := by
    obtain ht | ht := eq_or_ne t 0
    · simp [ht]
    · calc (pullCount A a t ω : ℝ) / t
          = pullCount A a t ω * gap ν a / gap ν a / t := by field_simp
        _ ≤ regret ν A t ω / gap ν a / t := by gcongr; exact hb t
        _ = regret ν A t ω / t / gap ν a := by ring
  apply squeeze_zero' (Eventually.of_forall fun _ ↦ by positivity) (Eventually.of_forall hb')
  simpa using hr.tendsto_div_nhds_zero.div_const (gap ν a)
  1. Bandits.gap
  2. Bandits.gap_nonneg
  3. Bandits.gap_nonneg_of_le
  4. Bandits.gap_le_of_mem_Icc
  5. Bandits.regret
  6. Bandits.regret_eq_sum_gap
  7. Bandits.regret_nonneg
  8. Bandits.gap_eq_zero_of_regret_eq_zero
  9. Bandits.regret_eq_sum_pullCount_mul_gap
  10. Bandits.integral_regret_eq_sum_gap_mul_integral_pullCount
  11. Bandits.integral_regret_le_of_forall_integral_pullCount_le
  12. Bandits.bestArm
  13. Bandits.le_bestArm
  14. Bandits.gap_eq_bestArm_sub
  15. Bandits.gap_bestArm
  16. Bandits.integral_eq_of_gap_eq_zero
  17. Bandits.avg_mean_reward_tendsto_of_sublinear_regret
  18. Bandits.pullCount_rate_tendsto_of_sublinear_regret