Experimentation.Design­Based.Estimators

Entry point for paper-agnostic estimators of finite-population causal estimands and their randomization properties.

Difference­In­Means 6 core · 3 supporting The two-arm difference-in-means estimator is unbiased for the sample average treatment effect under complete randomization. ★ E_diffInMeans_eq_sate

Difference-in-means under complete randomization

The two-arm difference-in-means estimator is unbiased for the sample average treatment effect under complete randomization.

This file defines the finite-population target sateEstimand, the realized arm averages treatedMean and controlMean, and their contrast diffInMeans. The results E_treatedMean and E_controlMean prove that each arm mean estimates its finite-population arm mean, and E_diffInMeans_eq_sate packages the consequence: when 0 < n₁ < N, the expected difference in means equals sateEstimand. The companion theorem unbiased_diffInMeans states the same fact using the generic FiniteDesign.Unbiased predicate. The generic finite-population variance quantities used by downstream variance results are defined in NeymanVariance.

def sateEstimand reviewed
Causalean.Experimentation.DesignBased

For a finite population of units with potential outcomes under treatment and under control, the sample average treatment effect is the population mean of the unit-level difference between those two potential outcomes.

Definition (Lean source)
U :
Type u_1
shared
Y1 Y0 :
U → ℝ
sateEstimand Y1 Y0 :
ℝ
(∑ i, (Y1 i - Y0 i)) / (Fintype.card U : ℝ)
Causalean.Experimentation.DesignBased.sateEstimand · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:47
def treatedMean reviewed
Causalean.Experimentation.DesignBased

For a finite population of units, a number of treated units, the potential outcome under treatment for each unit, and a treated set containing exactly that many units, the treated-arm mean is the average treatment potential outcome among the treated units.

Definition (Lean source)
U :
Type u_1
shared
n₁ :
ℕ
Y1 :
U → ℝ
S :
{S : Finset U // S.card = n₁}
treatedMean n₁ Y1 S :
ℝ
(∑ i, (if i ∈ S.val then Y1 i else 0)) / (n₁ : ℝ)
Causalean.Experimentation.DesignBased.treatedMean · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:53
def controlMean reviewed
Causalean.Experimentation.DesignBased

For a finite population of units, a number of treated units, the potential outcome under control for each unit, and a treated set containing exactly that many units, the control-arm mean is the average control potential outcome among all units outside the treated set.

Definition (Lean source)
U :
Type u_1
shared
n₁ :
ℕ
Y0 :
U → ℝ
S :
{S : Finset U // S.card = n₁}
controlMean n₁ Y0 S :
ℝ
(∑ i, (if i ∈ S.val then 0 else Y0 i)) / ((card U - n₁ : ℕ) : ℝ)
Causalean.Experimentation.DesignBased.controlMean · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:60
def diffInMeans reviewed
Causalean.Experimentation.DesignBased

For a finite population of units, a number of treated units, potential outcomes under treatment and under control, and a treated set containing exactly that many units, the difference-in-means estimator is the treated-arm mean minus the control-arm mean.

Definition (Lean source)
U :
Type u_1
shared
n₁ :
ℕ
Y1 Y0 :
U → ℝ
S :
{S : Finset U // S.card = n₁}
diffInMeans n₁ Y1 Y0 S :
ℝ
treatedMean n₁ Y1 S - controlMean n₁ Y0 S
Causalean.Experimentation.DesignBased.diffInMeans · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:67
theorem E_diffInMeans_eq_sate reviewed
Causalean.Experimentation.DesignBased

Unbiasedness of difference in means. Under complete randomization in which at least one unit is treated and the treated count n₁ is strictly below the population size N, so at least one unit remains a control, the difference-in-means estimator, computed from the potential outcomes Y1 and Y0, has expectation exactly equal to the sample average treatment effect.

Formal statement
U :
Type u_1
shared
n₁ :
ℕ
hn1 :
0 < n₁
hn0 :
n₁ < card U
Y1 Y0 :
U → ℝ
(completeRandomization n₁ (le_of_lt hn0)).E (diffInMeans n₁ Y1 Y0)
= sateEstimand Y1 Y0
Proof (Lean source)
theorem E_diffInMeans_eq_sate (n₁ : ℕ) (hn1 : 0 < n₁) (hn0 : n₁ < card U) (Y1 Y0 : U → ℝ) : (completeRandomization n₁ (le_of_lt hn0)).E (diffInMeans n₁ Y1 Y0) = sateEstimand Y1 Y0 := by have hn : n₁ ≤ card U := le_of_lt hn0 unfold diffInMeans sateEstimand rw [FiniteDesign.E_sub, E_treatedMean n₁ hn hn1, E_controlMean n₁ hn0] rw [← sub_div] congr 1 rw [← Finset.sum_sub_distrib]
def varianceEstimator reviewed
Causalean.Experimentation.DesignBased.DifferenceInMeans

For a population of n units, a treated count, treated and control potential outcomes, and a treated set, the usual conservative variance estimator for difference in means is the transported sum of the two observed arm sample variances divided by their arm sizes.

Definition (Lean source)
n :
ℕ
K :
ℕ
Y1 Y0 :
Fin n → ℝ
S :
{S : Finset (Fin n) // S.card = K}
varianceEstimator K Y1 Y0 S :
ℝ
varHat K Y1 Y0 (fun i => decide (i ∈ S.val))
Causalean.Experimentation.DesignBased.DifferenceInMeans.varianceEstimator · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:215
3 supporting declarations (lemmas, instances)
  • E_treatedMean theorem — The treated-arm mean is unbiased for the treated population mean (1/N) ∑ Y1. Each unit enters the treated arm with probability n₁ / N, so its inverse-n₁ weight averages to 1/N.
    U :
    Type u_1
    shared
    n₁ :
    ℕ
    hn :
    n₁ ≤ Fintype.card U
    hn1 :
    0 < n₁
    Y1 :
    U → ℝ
    (completeRandomization n₁ hn).E (treatedMean n₁ Y1) = (∑ i, Y1 i) / (Fintype.card U : ℝ)
    Proof (Lean source)
    theorem E_treatedMean (n₁ : ℕ) (hn : n₁ ≤ Fintype.card U) (hn1 : 0 < n₁) (Y1 : U → ℝ) : (completeRandomization n₁ hn).E (treatedMean n₁ Y1) = (∑ i, Y1 i) / (Fintype.card U : ℝ) := by let D := completeRandomization n₁ hn have hn1R : (n₁ : ℝ) ≠ 0 := by exact_mod_cast (ne_of_gt hn1) have hNpos : 0 < Fintype.card U := lt_of_lt_of_le hn1 hn have hNR : (Fintype.card U : ℝ) ≠ 0 := by exact_mod_cast (ne_of_gt hNpos) have hterm (i : U) : D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then Y1 i else 0) = Y1 i * ((n₁ : ℝ) / (Fintype.card U : ℝ)) := by calc D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then Y1 i else 0) = D.E (fun S : {S : Finset U // S.card = n₁} => Y1 i * FiniteDesign.ind (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val) S) := by exact D.E_congr (fun S => by unfold FiniteDesign.ind by_cases h : i ∈ S.val <;> simp [h]) _ = Y1 i * D.E (FiniteDesign.ind (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val)) := by rw [FiniteDesign.E_const_mul] _ = Y1 i * D.Pr (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val) := by rw [FiniteDesign.E_ind] _ = Y1 i * ((n₁ : ℝ) / (Fintype.card U : ℝ)) := by rw [completeRandomization_incl] calc D.E (treatedMean n₁ Y1) = D.E (fun S : {S : Finset U // S.card = n₁} => (∑ i, (if i ∈ S.val then Y1 i else 0)) * (1 / (n₁ : ℝ))) := by exact D.E_congr (fun S => by unfold treatedMean rw [div_eq_mul_inv, one_div]) _ = D.E (fun S : {S : Finset U // S.card = n₁} => ∑ i, (if i ∈ S.val then Y1 i else 0)) * (1 / (n₁ : ℝ)) := by rw [FiniteDesign.E_mul_const] _ = (∑ i, D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then Y1 i else 0)) * (1 / (n₁ : ℝ)) := by rw [FiniteDesign.E_sum] _ = (∑ i, Y1 i * ((n₁ : ℝ) / (Fintype.card U : ℝ))) * (1 / (n₁ : ℝ)) := by congr 1 exact Finset.sum_congr rfl (fun i _ => hterm i) _ = (∑ i, Y1 i) / (Fintype.card U : ℝ) := by rw [← Finset.sum_mul] field_simp [hn1R, hNR]
    Causalean.Experimentation.DesignBased.E_treatedMean · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:74
  • E_controlMean theorem — The control-arm mean is unbiased for the control population mean (1/N) ∑ Y0. Each unit enters the control arm with probability n₀ / N.
    U :
    Type u_1
    shared
    n₁ :
    ℕ
    hn0 :
    n₁ < Fintype.card U
    Y0 :
    U → ℝ
    (completeRandomization n₁ (le_of_lt hn0)).E (controlMean n₁ Y0)
    = (∑ i, Y0 i) / (Fintype.card U : ℝ)
    Proof (Lean source)
    theorem E_controlMean (n₁ : ℕ) (hn0 : n₁ < Fintype.card U) (Y0 : U → ℝ) : (completeRandomization n₁ (le_of_lt hn0)).E (controlMean n₁ Y0) = (∑ i, Y0 i) / (Fintype.card U : ℝ) := by have hn : n₁ ≤ Fintype.card U := le_of_lt hn0 let D := completeRandomization n₁ hn have hNpos : 0 < Fintype.card U := lt_of_le_of_lt (zero_le n₁) hn0 have hNR : (Fintype.card U : ℝ) ≠ 0 := by exact_mod_cast (ne_of_gt hNpos) have hdenNat : (Fintype.card U - n₁ : ℕ) ≠ 0 := Nat.sub_ne_zero_of_lt hn0 have hdenR : ((Fintype.card U - n₁ : ℕ) : ℝ) ≠ 0 := by exact_mod_cast hdenNat have hdiffR : (Fintype.card U : ℝ) - (n₁ : ℝ) ≠ 0 := by have hlt : (n₁ : ℝ) < (Fintype.card U : ℝ) := by exact_mod_cast hn0 exact ne_of_gt (sub_pos.mpr hlt) have hterm (i : U) : D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then 0 else Y0 i) = Y0 i * (1 - (n₁ : ℝ) / (Fintype.card U : ℝ)) := by calc D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then 0 else Y0 i) = D.E (fun S : {S : Finset U // S.card = n₁} => Y0 i * (1 - FiniteDesign.ind (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val) S)) := by exact D.E_congr (fun S => by unfold FiniteDesign.ind by_cases h : i ∈ S.val <;> simp [h]) _ = Y0 i * D.E (fun S : {S : Finset U // S.card = n₁} => 1 - FiniteDesign.ind (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val) S) := by rw [FiniteDesign.E_const_mul] _ = Y0 i * (D.E (fun _ : {S : Finset U // S.card = n₁} => 1) - D.E (FiniteDesign.ind (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val))) := by rw [FiniteDesign.E_sub] _ = Y0 i * (1 - D.Pr (fun T : {S : Finset U // S.card = n₁} => i ∈ T.val)) := by rw [FiniteDesign.E_const, FiniteDesign.E_ind] _ = Y0 i * (1 - (n₁ : ℝ) / (Fintype.card U : ℝ)) := by rw [completeRandomization_incl] calc D.E (controlMean n₁ Y0) = D.E (fun S : {S : Finset U // S.card = n₁} => (∑ i, (if i ∈ S.val then 0 else Y0 i)) * (1 / ((Fintype.card U - n₁ : ℕ) : ℝ))) := by exact D.E_congr (fun S => by unfold controlMean rw [div_eq_mul_inv, one_div]) _ = D.E (fun S : {S : Finset U // S.card = n₁} => ∑ i, (if i ∈ S.val then 0 else Y0 i)) * (1 / ((Fintype.card U - n₁ : ℕ) : ℝ)) := by rw [FiniteDesign.E_mul_const] _ = (∑ i, D.E (fun S : {S : Finset U // S.card = n₁} => if i ∈ S.val then 0 else Y0 i)) * (1 / ((Fintype.card U - n₁ : ℕ) : ℝ)) := by rw [FiniteDesign.E_sum] _ = (∑ i, Y0 i * (1 - (n₁ : ℝ) / (Fintype.card U : ℝ))) * (1 / ((Fintype.card U - n₁ : ℕ) : ℝ)) := by congr 1 exact Finset.sum_congr rfl (fun i _ => hterm i) _ = (∑ i, Y0 i) / (Fintype.card U : ℝ) := by rw [← Finset.sum_mul] rw [Nat.cast_sub hn] field_simp [hNR, hdenR, hdiffR]
    Causalean.Experimentation.DesignBased.E_controlMean · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:122
  • unbiased_diffInMeans theorem — The difference in means is unbiased for the SATE, in the Unbiased predicate form.
    U :
    Type u_1
    shared
    n₁ :
    ℕ
    hn1 :
    0 < n₁
    hn0 :
    n₁ < card U
    Y1 Y0 :
    U → ℝ
    Proof (Lean source)
    theorem unbiased_diffInMeans (n₁ : ℕ) (hn1 : 0 < n₁) (hn0 : n₁ < card U) (Y1 Y0 : U → ℝ) : (completeRandomization n₁ (le_of_lt hn0)).Unbiased (diffInMeans n₁ Y1 Y0) (sateEstimand Y1 Y0) := E_diffInMeans_eq_sate n₁ hn1 hn0 Y1 Y0
    Causalean.Experimentation.DesignBased.unbiased_diffInMeans · Causalean/Experimentation/DesignBased/Estimators/DifferenceInMeans.lean:206
Neyman­Variance 10 core · 0 supporting This module contains the paper-independent finite-population arm variances, unit-effect variance, and observed separate-arm variance estimator used by Neyman's complete-randomization formula.

Generic finite-population variance quantities for two-arm designs

This module contains the paper-independent finite-population arm variances, unit-effect variance, and observed separate-arm variance estimator used by Neyman's complete-randomization formula. They live in the design-based layer so interference models can import them without reversing the library's dependency direction.

def T reviewed
Causalean.Experimentation.DesignBased

For a population of n units and a unit, the treatment indicator is one when the Boolean assignment treats that unit and zero otherwise.

Definition (Lean source)
n :
ℕ
shared
j :
Fin n
T j :
(Fin n → Bool) → ℝ
FiniteDesign.ind (fun w => w j = true)
def popMeanV reviewed
Causalean.Experimentation.DesignBased

For a population of n units and a real quantity for every unit, the finite-population mean is the unit sum divided by n.

Definition (Lean source)
n :
ℕ
shared
x :
Fin n → ℝ
popMeanV x :
ℝ
(∑ j, x j) / n
Causalean.Experimentation.DesignBased.popMeanV · Causalean/Experimentation/DesignBased/Estimators/NeymanVariance.lean:37
def S1 reviewed
Causalean.Experimentation.DesignBased

For a population of n units and treated potential outcomes, the treated finite-population sample variance uses denominator n-1.

Definition (Lean source)
n :
ℕ
shared
a :
Fin n → ℝ
S1 a :
ℝ
(∑ j, (a j - popMeanV a) ^ 2) / (n - 1 : ℝ)
def S0 reviewed
Causalean.Experimentation.DesignBased

For a population of n units and control potential outcomes, the control finite-population sample variance uses denominator n-1.

Definition (Lean source)
n :
ℕ
shared
b :
Fin n → ℝ
S0 b :
ℝ
(∑ j, (b j - popMeanV b) ^ 2) / (n - 1 : ℝ)
def Stau reviewed
Causalean.Experimentation.DesignBased

For a population of n units, treated potential outcomes, and control potential outcomes, the finite-population sample variance of unit treatment effects uses denominator n-1.

Definition (Lean source)
n :
ℕ
shared
a b :
Fin n → ℝ
Stau a b :
ℝ
(∑ j, ((a j - b j) - (popMeanV a - popMeanV b)) ^ 2) / (n - 1 : ℝ)
def obsMeanTreated reviewed
Causalean.Experimentation.DesignBased

For a treated count, treated outcomes, and a Boolean assignment, the observed treated-arm mean averages treated outcomes over the treated count.

Definition (Lean source)
n :
ℕ
shared
K :
ℕ
shared
a :
Fin n → ℝ
shared
w :
Fin n → Bool
obsMeanTreated K a w :
ℝ
(∑ j, T j w * a j) / K
Causalean.Experimentation.DesignBased.obsMeanTreated · Causalean/Experimentation/DesignBased/Estimators/NeymanVariance.lean:59
def obsMeanControl reviewed
Causalean.Experimentation.DesignBased

For a treated count, control outcomes, and a Boolean assignment, the observed control-arm mean averages control outcomes over the control count.

Definition (Lean source)
n :
ℕ
shared
K :
ℕ
shared
b :
Fin n → ℝ
shared
w :
Fin n → Bool
obsMeanControl K b w :
ℝ
(∑ j, (1 - T j w) * b j) / (n - K : ℝ)
Causalean.Experimentation.DesignBased.obsMeanControl · Causalean/Experimentation/DesignBased/Estimators/NeymanVariance.lean:64
def ShatTreated reviewed
Causalean.Experimentation.DesignBased

For a treated count, treated outcomes, and a Boolean assignment, the observed treated-arm sample variance uses denominator K-1.

Definition (Lean source)
n :
ℕ
shared
K :
ℕ
shared
a :
Fin n → ℝ
shared
w :
Fin n → Bool
ShatTreated K a w :
ℝ
(∑ j, T j w * (a j - obsMeanTreated K a w) ^ 2) / (K - 1 : ℝ)
Causalean.Experimentation.DesignBased.ShatTreated · Causalean/Experimentation/DesignBased/Estimators/NeymanVariance.lean:69
def ShatControl reviewed
Causalean.Experimentation.DesignBased

For a treated count, control outcomes, and a Boolean assignment, the observed control-arm sample variance uses denominator n-K-1.

Definition (Lean source)
n :
ℕ
shared
K :
ℕ
shared
b :
Fin n → ℝ
shared
w :
Fin n → Bool
ShatControl K b w :
ℝ
(∑ j, (1 - T j w) * (b j - obsMeanControl K b w) ^ 2) / (n - K - 1 : ℝ)
Causalean.Experimentation.DesignBased.ShatControl · Causalean/Experimentation/DesignBased/Estimators/NeymanVariance.lean:74
def varHat reviewed
Causalean.Experimentation.DesignBased

For a treated count, treated and control outcomes, and a Boolean assignment, the usual conservative variance estimator is the sum of the observed arm sample variances divided by their arm sizes.

Definition (Lean source)
n :
ℕ
shared
K :
ℕ
shared
a :
Fin n → ℝ
shared
b :
Fin n → ℝ
shared
w :
Fin n → Bool
varHat K a b w :
ℝ
ShatTreated K a w / K + ShatControl K b w / (n - K : ℝ)