<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Lean | Randy Lai</title>
    <link>https://randylai.info/tag/lean/</link>
      <atom:link href="https://randylai.info/tag/lean/index.xml" rel="self" type="application/rss+xml" />
    <description>Lean</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Wed, 21 Oct 2026 00:00:00 +0000</lastBuildDate>
    <image>
      <url>https://randylai.info/media/icon_hucc985415fc2240686c5d2ffac646cd63_12276_512x512_fill_lanczos_center_3.png</url>
      <title>Lean</title>
      <link>https://randylai.info/tag/lean/</link>
    </image>
    
    <item>
      <title>MSE of sample standard deviation (Lean by AI)</title>
      <link>https://randylai.info/post/2026/mse_of_sample_sd_lean/</link>
      <pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://randylai.info/post/2026/mse_of_sample_sd_lean/</guid>
      <description>&lt;p&gt;Back in 2023, I wrote a &lt;a href=&#34;https://randylai.info/post/2023/mse_of_sample_sd_cont/&#34;&gt;post&lt;/a&gt; using SymPy to compute the second order expansion of the mean squared error (MSE) of the sample standard deviation up to $O(n^{-2})$. Earlier this year, I revisited the problem in &lt;a href=&#34;https://randylai.info/post/2026/mse_of_sample_sd_gen_ai/&#34;&gt;MSE of sample standard deviation (Gen AI)&lt;/a&gt; and showed that a modern LLM can derive the entire second order expansion directly from a prompt.&lt;/p&gt;
&lt;p&gt;When an AI produces a long asymptotic derivation with dozens of polynomial moment terms, how can we trust that every coefficient is right and that no terms of order $n^{-2}$ were dropped? To check the derivation rigorously, I formalized and verified the entire proof in &lt;a href=&#34;https://lean-lang.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Lean 4&lt;/a&gt; with &lt;a href=&#34;https://github.com/leanprover-community/mathlib4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mathlib&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The complete Lean 4 formalization is a single file, &lt;a href=&#34;https://github.com/randy3k/randylai.info/blob/master/content/post/2026/SampleSdMse.lean&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;SampleSdMse.lean&lt;/code&gt;&lt;/a&gt;. It builds with Lean &lt;code&gt;v4.35.0&lt;/code&gt; and Mathlib &lt;code&gt;v4.35.0&lt;/code&gt; (commit &lt;code&gt;56a0058&lt;/code&gt;). A &lt;a href=&#34;https://randylai.info/post/2026/mse_of_sample_sd_lean_proof/&#34;&gt;complete human readable proof&lt;/a&gt; follows the Lean formalization step by step.&lt;/p&gt;
&lt;h3 id=&#34;summary-of-results&#34;&gt;Summary of Results&lt;/h3&gt;
&lt;p&gt;Let $X_1, X_2, \ldots$ be i.i.d. with mean $\mu$, variance $\sigma^2 &amp;gt; 0$, and finite moments. We compare two estimators of the population standard deviation $\sigma$:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$S_n = \sqrt{\frac{1}{n-1}\sum _ {i=1}^n (X_i - \bar X)^2}$ (Bessel corrected, using $n - 1$ in the denominator)&lt;/li&gt;
&lt;li&gt;$\hat \sigma_n = \sqrt{\frac{1}{n}\sum _ {i=1}^n (X_i - \bar X)^2} = \sqrt{\frac{n-1}{n}} S_n$ (unadjusted, using $n$ in the denominator)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let $\lambda_k = \frac{E[(X - \mu)^k]}{\sigma^k}$ denote the standardized central moments, with $\lambda_3$ the skewness, $\lambda_4$ the kurtosis, and $\lambda_6$ the sixth moment. The general second order expansions are:&lt;/p&gt;
&lt;p&gt;$$
E(S_n) = \sigma - \frac{\sigma}{8n} (\lambda_4 - 1) + \frac{\sigma}{128n^2} \left(8 \lambda_6 - 15 \lambda_4^2 + 6 \lambda_4 - 48 \lambda_3^2 - 31\right) + o(n^{-2})
$$&lt;/p&gt;
&lt;p&gt;$$
E(\hat \sigma_n) = \sigma - \frac{\sigma}{8n} (\lambda_4 + 3) + \frac{\sigma}{128n^2} \left(8 \lambda_6 - 15 \lambda_4^2 + 14 \lambda_4 - 48 \lambda_3^2 - 55\right) + o(n^{-2})
$$&lt;/p&gt;
&lt;p&gt;$$
MSE(S_n) = \frac{\sigma^2}{4n} (\lambda_4 - 1) + \frac{\sigma^2}{64n^2} \left(48 \lambda_3^2 + 15 \lambda_4^2 - 6 \lambda_4 - 8 \lambda_6 + 31\right) + o(n^{-2})
$$&lt;/p&gt;
&lt;p&gt;$$
MSE(\hat \sigma_n) = \frac{\sigma^2}{4n} (\lambda_4 - 1) + \frac{\sigma^2}{64n^2} \left(48 \lambda_3^2 + 15 \lambda_4^2 - 14 \lambda_4 - 8 \lambda_6 + 55\right) + o(n^{-2})
$$&lt;/p&gt;
&lt;p&gt;Taking the difference gives:&lt;/p&gt;
&lt;p&gt;$$
MSE(S_n) - MSE(\hat \sigma_n) = \frac{\sigma^2 (\lambda_4 - 3)}{8n^2} + o(n^{-2})
$$&lt;/p&gt;
&lt;p&gt;This leads to three conclusions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Threshold at $\lambda_4 = 3$:&lt;/strong&gt; When the kurtosis is $\lambda_4 = 3$, the $1/n^2$ leading difference term vanishes:
$$
MSE(S_n) - MSE(\hat \sigma_n) = o(n^{-2})
$$
For heavier tails ($\lambda_4 &amp;gt; 3$), $\hat \sigma_n$ has smaller MSE. For lighter tails ($\lambda_4 &amp;lt; 3$), $S_n$ has smaller MSE.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shared expansion at $\lambda_4 = 3$:&lt;/strong&gt;
$$
MSE(S_n) = MSE(\hat \sigma_n) + o(n^{-2}) = \frac{\sigma^2}{2n} + \frac{\sigma^2}{16n^2}\left(12\lambda_3^2 - 2\lambda_6 + 37\right) + o(n^{-2})
$$
with expected value:
$$
E(S_n) = \sigma - \frac{\sigma}{4n} + \frac{\sigma}{32n^2}\left(2\lambda_6 - 12\lambda_3^2 - 37\right) + o(n^{-2})
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Normal distribution special case ($\lambda_3 = 0, \lambda_4 = 3, \lambda_6 = 15$):&lt;/strong&gt;
$$
E(S_n) = \sigma - \frac{\sigma}{4n} - \frac{7\sigma}{32n^2} + o(n^{-2})
$$
$$
MSE(S_n) = MSE(\hat \sigma_n) + o(n^{-2}) = \frac{\sigma^2}{2n} + \frac{7\sigma^2}{16n^2} + o(n^{-2})
$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;formalization-in-lean-4-with-mathlib&#34;&gt;Formalization in Lean 4 with Mathlib&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Assumptions.&lt;/strong&gt; The only assumptions are the textbook i.i.d. model, stated with Mathlib&amp;rsquo;s standard notions of independence (&lt;code&gt;iIndepFun&lt;/code&gt;), identical distribution (&lt;code&gt;IdentDistrib&lt;/code&gt;), and variance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;class SampleModel (Ω : outParam Type*) [MeasurableSpace Ω]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    (μ : outParam (Measure Ω)) [IsProbabilityMeasure μ] where
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  X : ℕ → Ω → ℝ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  measurable : ∀ i, Measurable (X i)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  indep : ProbabilityTheory.iIndepFun X μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ident : ∀ i, ProbabilityTheory.IdentDistrib (X i) (X 0) μ μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  moments : ∀ k : ℕ, Integrable (fun ω =&amp;gt; X 0 ω ^ k) μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  var_pos : 0 &amp;lt; ProbabilityTheory.variance (X 0) μ
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In words: on a probability space $(\Omega, \mu)$, the observations $X_0, X_1, \ldots$ are measurable, mutually independent, identically distributed, have all moments finite, and have positive variance. The proof only uses moments up to order 16; assuming all moments are finite keeps the formalization simple.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Definitions.&lt;/strong&gt; Everything in the main theorem is a plain textbook definition. Expectation is Mathlib&amp;rsquo;s Bochner integral:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def mean : ℝ := ∫ ω, SampleModel.X 0 ω ∂μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def σ : ℝ := Real.sqrt (ProbabilityTheory.variance (SampleModel.X 0) μ)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def lam (k : ℕ) : ℝ := ∫ ω, ((SampleModel.X 0 ω - mean (μ := μ)) / σ (μ := μ)) ^ k ∂μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def Xbar (n : ℕ) (ω : Ω) : ℝ := (1 / (n : ℝ)) * ∑ i : Fin n, SampleModel.X i ω
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def sampleSD (n : ℕ) (ω : Ω) : ℝ :=
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Real.sqrt ((1 / (n : ℝ)) * ∑ i : Fin n, (SampleModel.X i ω - Xbar (μ := μ) n ω) ^ 2)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def besselSD (n : ℕ) (ω : Ω) : ℝ :=
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Real.sqrt ((1 / ((n : ℝ) - 1)) * ∑ i : Fin n, (SampleModel.X i ω - Xbar (μ := μ) n ω) ^ 2)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def expect [SampleModel Ω μ] (T : Ω → ℝ) : ℝ := ∫ ω, T ω ∂μ
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def mse [SampleModel Ω μ] (T : Ω → ℝ) (θ : ℝ) : ℝ := ∫ ω, (T ω - θ) ^ 2 ∂μ
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here &lt;code&gt;lam k&lt;/code&gt; is $\lambda_k$, &lt;code&gt;sampleSD&lt;/code&gt; is $\hat \sigma_n$, and &lt;code&gt;besselSD&lt;/code&gt; is $S_n$. Asymptotic statements use Mathlib&amp;rsquo;s standard little $o$ notation along &lt;code&gt;atTop&lt;/code&gt; for integer sample sizes. For example, the MSE difference is the following part of the main theorem &lt;code&gt;textbook_certificate&lt;/code&gt;, which assumes nothing beyond &lt;code&gt;SampleModel&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(fun n : ℕ =&amp;gt; (mse (besselSD n) σ - mse (sampleSD n) σ) -
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    σ ^ 2 * (lam4 - 3) / (8 * (n : ℝ) ^ 2))
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  =o[atTop] (fun n : ℕ =&amp;gt; 1 / (n : ℝ) ^ 2)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Proof outline.&lt;/strong&gt; Lean checks every step of the following argument:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Standardize $Z_i = (X_i - \mu)/\sigma$ and write $\hat \sigma_n = \sigma \sqrt{1 + D_n}$ and $S_n = \sigma \sqrt{1 + \Delta_n}$, where $D_n = U_n - V_n^2$ with $U_n = \frac{1}{n}\sum (Z_i^2 - 1)$ and $V_n = \bar Z$, and $1 + \Delta_n = \frac{n}{n-1}(1 + D_n)$.&lt;/li&gt;
&lt;li&gt;Compute the exact finite sample moments of $U_n$ and $V_n$ from independence, including the exact $1/n^3$ correction in the fourth moments.&lt;/li&gt;
&lt;li&gt;Expand $\sqrt{1 + x}$ to fourth order with an exact remainder, and bound the expected remainder using $|\sqrt{1 + x} - 1| \le |x|$ and the Cauchy Schwarz inequality.&lt;/li&gt;
&lt;li&gt;Prove the moment growth bound $E[T_n^m] = O(n^{m/2})$ for partial sums $T_n = \sum _ {i=1}^n W_i$ of i.i.d. mean zero $W_i$, from the recursion $E[T_{n+1}^m] = \sum_j \binom{m}{j} E[T_n^j] E[W^{m-j}]$, which holds because $T_n$ is independent of $W_{n+1}$. This gives every higher order remainder as $o(n^{-2})$ without any extra rate assumption.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;kernel-axiom-audit&#34;&gt;Kernel Axiom Audit&lt;/h3&gt;
&lt;p&gt;Running &lt;code&gt;lake build SdMseLean&lt;/code&gt; compiles the library with no &lt;code&gt;sorry&lt;/code&gt;, and &lt;code&gt;#print axioms&lt;/code&gt; shows that every theorem depends only on the standard Lean 4 axioms:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2511:0: &amp;#39;SdMseLean.SampleModel.textbook_certificate&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2512:0: &amp;#39;SdMseLean.SampleModel.remainder_order&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2514:0: &amp;#39;SdMseLean.SampleModel.taylorSqrt4&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2518:0: &amp;#39;SdMseLean.sampleAvg_moment1&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2519:0: &amp;#39;SdMseLean.sampleAvg_moment2&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2520:0: &amp;#39;SdMseLean.sampleAvg_moment3&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;info: SdMseLean/SampleSdMse.lean:2521:0: &amp;#39;SdMseLean.sampleAvg_moment4&amp;#39; depends on axioms: [propext, Classical.choice, Quot.sound]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Build completed successfully (3047 jobs).
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lean&amp;rsquo;s kernel checks every coefficient in the expansions above, under exactly the assumptions listed in &lt;code&gt;SampleModel&lt;/code&gt;. What remains a human judgment is whether those Lean statements say what we mean, which is why the assumptions and definitions are kept as close to the textbook as possible.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
