探索正态分布:交互式实验带你体验统计之美

探索正态分布:交互式实验带你体验统计之美

正态分布,这条优美的钟形曲线,可以说是统计学中最重要、最无处不在的概率分布。从自然现象(如身高、测量误差)到金融市场,再到机器学习,它的身影随处可见。但你是否真正理解它为何如此普遍?仅仅看公式和定义可能有些枯燥,不如动手实践!

最近,我创建了一个简单的 HTML 交互式页面,通过三个经典的实验,让你直观地感受和探索正态分布的奥秘。无需安装任何软件,在浏览器中即可运行。

你可以将下面的完整 HTML 代码保存为一个 .html 文件,然后用浏览器打开它,即可开始交互式实验。

(如果你正在使用支持 Artifact 的界面,可以直接在旁边预览和交互)

下面,我们来详细介绍一下这三个实验以及它们背后的原理。

实验一:中心极限定理 (Central Limit Theorem, CLT)

核心思想: 这是正态分布“王者地位”的关键原因之一。中心极限定理指出,无论原始数据来自什么分布(只要它有明确的均值和方差),只要你从中抽取足够多的样本,并计算这些样本的均值,那么这些样本均值的分布就会趋近于正态分布。样本量越大,这种趋近性越好。

交互实验:

  1. 过程: 实验从一个简单的均匀分布(0到1之间的随机数,每个数值出现的概率相等)开始。我们进行 T 次试验,每次试验都抽取 M 个这样的随机数,然后计算这 M 个数的平均值。最后,我们将这 T 个平均值进行“标准化”处理(减去理论均值,再除以理论标准差),并绘制它们的分布直方图。
  2. 你的操作:
    • 调整 试验次数 (T) 滑块:增加 T 会让直方图看起来更平滑,因为它基于更多的数据点。
    • 调整 每次试验的样本量 (M) 滑块:这是关键!观察当 M 逐渐增大时,直方图的形状如何越来越像标准的正态分布(N(0,1))曲线。即使原始分布(均匀分布)完全不是钟形,它们的均值(经过标准化后)却神奇地呈现出正态性。
  3. 观察: 图表中会同时绘制理论的标准正态分布 PDF(概率密度函数)曲线,方便你对比实验结果与理论的吻合程度。

实验二:高尔顿板 (Galton Board / Bean Machine) 模拟

核心思想: 高尔顿板是一个物理装置,小球从顶部落下,经过多层交错排列的钉子,每次碰到钉子时,小球有同等机会向左或向右落下。最终,小球落在底部的不同槽中,形成近似正态分布的堆积。这本质上是二项分布的一个直观展示,而当层数(试验次数)很多时,二项分布可以很好地用正态分布来近似。

交互实验:

  1. 过程: 我们模拟这个过程。设置钉板的层数 L 和下落的小球数量 B。每个小球独立下落 L 层,每层随机向左(位置-0.5)或向右(位置+0.5)。我们记录每个小球最终的水平位置。
  2. 你的操作:
    • 调整 钉板层数 (L) 滑块:层数越多,相当于二项分布中的试验次数越多,其形状越接近正态分布。
    • 调整 小球数量 (B) 滑块:增加小球数量可以让分布的形状更清晰、更稳定。
  3. 观察: 绘制的是最终落点位置的直方图。你会看到,即使每次决策只是简单的左右二选一,大量重复后,整体结果呈现出中间高、两边低的钟形分布。实验同样会绘制一个理论上的正态分布曲线(均值为0,方差为 L/4)供你对比。

实验三:Box-Muller 变换

核心思想: 前两个实验展示了正态分布是如何“自然产生”或作为极限情况出现的。而 Box-Muller 变换则是一种直接生成符合标准正态分布 (N(0,1)) 随机数的常用算法。它利用两个独立的、来自标准均匀分布 U(0,1) 的随机数,通过一个精巧的数学变换,生成两个独立的、来自标准正态分布 N(0,1) 的随机数。

交互实验:

  1. 过程: 实验直接应用 Box-Muller 算法。你只需要指定想要生成的符合 N(0,1) 分布的样本数量 N
  2. 你的操作:
    • 调整 生成样本数量 (N) 滑块:生成的样本越多,直方图就越能精确地反映标准正态分布的形状。
  3. 观察: 你会看到生成的样本数据绘制的直方图,以及理论上的 N(0,1) 曲线。这个实验展示了如何从最基础的均匀随机数“构造”出正态随机数,这在计算机模拟和统计计算中非常有用。

如何使用?

非常简单:

  1. 将下面的代码复制并保存为一个 .html 文件 (例如 normal_experiments.html)。
  2. 用你的网页浏览器打开这个文件。
  3. 找到你感兴趣的实验。
  4. 拖动滑块来调整参数(如样本量、试验次数等)。滑块旁边的数字会实时显示当前值。
  5. 点击对应实验下方的“运行实验”按钮。
  6. 观察下方图表的变化,看看实验结果的直方图如何与理论的正态曲线进行拟合。

结语

通过这三个交互式实验,希望你能更直观地理解:

  • 中心极限定理的强大威力,解释了为何许多现实世界的变量近似正态分布。
  • 累积效应(如高尔顿板)如何导致正态分布的出现。
  • 如何利用基础的随机数生成正态分布样本(Box-Muller)。

统计学不仅仅是冰冷的公式,动手实验和模拟是理解其深刻内涵的绝佳途径。快去亲自试试看,调整参数,观察变化,感受正态分布的魅力吧!


交互式实验完整 HTML 代码

<!DOCTYPE html>  
<html lang="zh">  
<head>  <meta charset="UTF-8">  <title>交互式正态分布实验</title>  <script src="https://cdn.tailwindcss.com"></script>  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>  <style>  
.chart-container {  position: relative;  height: 300px;  width: 100%;  
}  
label {  display: block;  margin-bottom: 0.25rem;  font-weight: 500;  
}  
input[type="number"], input[type="range"] {  width: 100%;  padding: 0.5rem;  border: 1px solid #d1d5db;  border-radius: 0.375rem;  margin-bottom: 0.5rem;  
}  
button {  background-color: #3b82f6;  color: white;  padding: 0.5rem 1rem;  border-radius: 0.375rem;  cursor: pointer;  transition: background-color 0.2s;  
}  
button:hover {  background-color: #2563eb;  
}  
.description {  font-size: 0.875rem;  color: #4b5563;  margin-bottom: 1rem;  
}  </style>  
</head>  
<body class="bg-gray-100 p-6">  <h1 class="text-3xl font-bold mb-8 text-center">交互式正态分布实验</h1>  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">  <!-- 实验1:中心极限定理 -->  
<div class="bg-white rounded-lg shadow p-6">  <h2 class="text-xl font-semibold mb-3">实验1:中心极限定理</h2>  <p class="description">  从任意分布(这里使用均匀分布)中抽取多个样本,计算这些样本的均值。根据中心极限定理,当样本量足够大时,这些样本均值的分布将趋近于正态分布。  </p>  <div>  <label for="clt-trials">试验次数 (T): <span id="clt-trials-val">5000</span></label>  <input type="range" id="clt-trials" min="100" max="10000" value="5000" step="100" oninput="document.getElementById('clt-trials-val').textContent = this.value;">  </div>  <div>  <label for="clt-sample-size">每次试验的样本量 (M): <span id="clt-sample-size-val">30</span></label>  <input type="range" id="clt-sample-size" min="2" max="100" value="30" step="1" oninput="document.getElementById('clt-sample-size-val').textContent = this.value;">  </div>  <button onclick="runCLTExperiment()">运行实验</button>  <div class="chart-container mt-4">  <canvas id="chart1"></canvas>  </div>  
</div>  <!-- 实验2:高尔顿板 (Galton Board / Bean Machine) -->  
<div class="bg-white rounded-lg shadow p-6">  <h2 class="text-xl font-semibold mb-3">实验2:高尔顿板模拟</h2>  <p class="description">  模拟小球通过钉板下落的过程。小球每次碰到钉子时,随机向左或向右下落。最终小球落入底部的槽中,其分布接近二项分布。当层数足够多时,二项分布近似于正态分布。  </p>  <div>  <label for="galton-levels">钉板层数 (L): <span id="galton-levels-val">20</span></label>  <input type="range" id="galton-levels" min="5" max="50" value="20" step="1" oninput="document.getElementById('galton-levels-val').textContent = this.value;">  </div>  <div>  <label for="galton-balls">小球数量 (B): <span id="galton-balls-val">5000</span></label>  <input type="range" id="galton-balls" min="100" max="10000" value="5000" step="100" oninput="document.getElementById('galton-balls-val').textContent = this.value;">  </div>  <button onclick="runGaltonExperiment()">运行实验</button>  <div class="chart-container mt-4">  <canvas id="chart2"></canvas>  </div>  
</div>  <!-- 实验3:Box-Muller 变换 -->  
<div class="bg-white rounded-lg shadow p-6">  <h2 class="text-xl font-semibold mb-3">实验3:Box-Muller 变换</h2>  <p class="description">  利用均匀分布的随机数生成符合标准正态分布 (N(0,1)) 的随机数。这是生成正态分布样本的常用算法。  </p>  <div>  <label for="boxmuller-samples">生成样本数量 (N): <span id="boxmuller-samples-val">5000</span></label>  <input type="range" id="boxmuller-samples" min="100" max="10000" value="5000" step="100" oninput="document.getElementById('boxmuller-samples-val').textContent = this.value;">  </div>  <button onclick="runBoxMullerExperiment()">运行实验</button>  <div class="chart-container mt-4">  <canvas id="chart3"></canvas>  </div>  
</div>  </div>  <script>  
let chart1, chart2, chart3;  // 标准正态分布 PDF  
function normalPDF(x, mu = 0, sigma = 1) {  return (1 / (sigma * Math.sqrt(2 * Math.PI))) * Math.exp(-0.5 * Math.pow((x - mu) / sigma, 2));  
}  // 数据分箱 (用于直方图)  
function binData(data, binCount = 40) {  if (!data || data.length === 0) return { counts: [], centers: [], binWidth: 0 };  let min = Math.min(...data), max = Math.max(...data);  if (min === max) { // Handle case where all data points are the same  min -= 0.5;  max += 0.5;  }  const binWidth = (max - min) / binCount;  const bins = Array(binCount).fill(0);  const centers = Array(binCount).fill(0).map((_, i) => min + (i + 0.5) * binWidth);  data.forEach(v => {  let idx = Math.floor((v - min) / binWidth);  if (idx >= binCount) idx = binCount - 1; // Handle max value  if (idx < 0) idx = 0; // Handle min value potentially slightly off  bins[idx]++;  });  return { counts: bins, centers, binWidth };  
}  // 绘制直方图  
function drawHistogram(ctx, chartInstance, data, binCount = 40, title, theoreticalPdf = null, pdfParams = {}) {  const { counts, centers, binWidth } = binData(data, binCount);  const N = data.length;  const datasets = [{  label: '实验频数',  data: counts,  backgroundColor: 'rgba(59, 130, 246, 0.5)',  borderColor: 'rgba(59, 130, 246, 1)',  borderWidth: 1,  barPercentage: 1.0,  categoryPercentage: 1.0  }];  if (theoreticalPdf) {  const pdfValues = centers.map(x => theoreticalPdf(x, pdfParams.mu, pdfParams.sigma) * N * binWidth);  datasets.push({  label: '理论分布 (缩放后)',  data: pdfValues,  type: 'line',  borderColor: 'rgba(234, 88, 12, 1)',  borderWidth: 2,  fill: false,  pointRadius: 0,  tension: 0.1  });  }  if (chartInstance) {  chartInstance.destroy();  }  return new Chart(ctx, {  type: 'bar',  data: {  labels: centers.map(c => c.toFixed(2)),  datasets: datasets  },  options: {  responsive: true,  maintainAspectRatio: false,  plugins: {  title: { display: true, text: title },  tooltip: {  mode: 'index',  intersect: false,  }  },  scales: {  x: {  title: { display: true, text: '值' },  ticks: {  maxRotation: 0,  minRotation: 0,  autoSkip: true,  maxTicksLimit: 10 // Limit number of x-axis labels for readability  }  },  y: {  title: { display: true, text: '频数' },  beginAtZero: true  }  }  }  });  
}  // --- 实验 1: 中心极限定理 ---  
function runCLTExperiment() {  const trials = parseInt(document.getElementById('clt-trials').value);  const sampleSize = parseInt(document.getElementById('clt-sample-size').value);  const means = [];  // 均匀分布 U[0, 1] 的均值为 0.5,方差为 1/12  const mu_uniform = 0.5;  const var_uniform = 1 / 12;  // 根据CLT,样本均值的均值为 mu_uniform,方差为 var_uniform / sampleSize  const mu_mean = mu_uniform;  const sigma_mean = Math.sqrt(var_uniform / sampleSize);  // 标准化后的均值 Z = (Mean - mu_mean) / sigma_mean,应服从 N(0,1)  for (let i = 0; i < trials; i++) {  let sum = 0;  for (let j = 0; j < sampleSize; j++) {  sum += Math.random();  }  const mean = sum / sampleSize;  const standardized_mean = (mean - mu_mean) / sigma_mean;  means.push(standardized_mean);  }  chart1 = drawHistogram(  document.getElementById('chart1').getContext('2d'),  chart1,  means,  40, // bins  `样本均值的分布 (T=${trials}, M=${sampleSize})`,  normalPDF, // Theoretical PDF is N(0,1) after standardization  { mu: 0, sigma: 1 }  );  
}  // --- 实验 2: 高尔顿板 ---  
function runGaltonExperiment() {  const levels = parseInt(document.getElementById('galton-levels').value);  const balls = parseInt(document.getElementById('galton-balls').value);  const finalPositions = [];  for (let i = 0; i < balls; i++) {  let position = 0;  for (let j = 0; j < levels; j++) {  position += (Math.random() < 0.5) ? -0.5 : 0.5; // 左 -0.5, 右 +0.5  }  finalPositions.push(position);  }  // 二项分布 B(n, p) 的均值为 np, 方差为 np(1-p)  // 这里 n=levels, p=0.5 (向右的概率)  // 每次移动是 +0.5 或 -0.5。等价于计算向右次数 k,位置 = k*0.5 + (levels-k)*(-0.5) = k - levels/2  // 向右次数 k ~ B(levels, 0.5)。均值 E[k] = levels*0.5。方差 Var(k) = levels*0.5*0.5 = levels/4  // 最终位置 Position = k - levels/2  // 均值 E[Position] = E[k] - levels/2 = levels*0.5 - levels/2 = 0  // 方差 Var(Position) = Var(k) = levels/4  const mu_galton = 0;  const sigma_galton = Math.sqrt(levels / 4);  // 确定分箱数量,最好是层数+1,如果层数不多  const binCount = Math.min(levels + 1, 50);  chart2 = drawHistogram(  document.getElementById('chart2').getContext('2d'),  chart2,  finalPositions,  binCount,  `高尔顿板落点分布 (L=${levels}, B=${balls})`,  normalPDF, // Compare with Normal distribution  { mu: mu_galton, sigma: sigma_galton }  );  
}  // --- 实验 3: Box-Muller ---  
function sampleNormalBoxMuller(n) {  const samples = [];  for (let i = 0; i < Math.ceil(n / 2); i++) {  const u1 = Math.random();  const u2 = Math.random();  const R = Math.sqrt(-2 * Math.log(u1));  const theta = 2 * Math.PI * u2;  samples.push(R * Math.cos(theta));  samples.push(R * Math.sin(theta));  }  return samples.slice(0, n); // Ensure exact number of samples  
}  function runBoxMullerExperiment() {  const numSamples = parseInt(document.getElementById('boxmuller-samples').value);  const samples = sampleNormalBoxMuller(numSamples);  chart3 = drawHistogram(  document.getElementById('chart3').getContext('2d'),  chart3,  samples,  40, // bins  `Box-Muller 生成的 N(0,1) 样本 (N=${numSamples})`,  normalPDF, // Theoretical PDF is N(0,1)  { mu: 0, sigma: 1 }  );  
}  // Initial runs on page load  
window.onload = () => {  runCLTExperiment();  runGaltonExperiment();  runBoxMullerExperiment();  
};  </script>  
</body>  
</html>  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 IDEA + Maven 搭建传统 Spring MVC 项目的详细步骤(非Spring Boot)

搭建Spring MVC项目 第一步&#xff1a;创建Maven项目第二步&#xff1a;配置pom.xml第三步&#xff1a;配置web.xml第四步&#xff1a;创建Spring配置文件第五步&#xff1a;创建控制器第六步&#xff1a;创建JSP视图第七步&#xff1a;配置Tomcat并运行目录结构常见问题解决与…

AI日报 · 2025年5月04日|Hugging Face 启动 MCP 全球创新挑战赛

1、Hugging Face 启动 MCP 全球创新挑战赛 Hugging Face 于 5 月 3 日发布 MCP Global Innovation Challenge&#xff0c;面向全球开发者征集基于模型上下文协议&#xff08;MCP&#xff09;的创新工具与应用&#xff0c;赛事持续至 5 月 31 日&#xff0c;设立多档…

学习spring boot-拦截器Interceptor,过滤器Filter

目录 拦截器Interceptor 过滤器Filter 关于过滤器的前置知识可以参考&#xff1a; 过滤器在springboot项目的应用 一&#xff0c;使用WebfilterServletComponentScan 注解 1 创建过滤器类实现Filter接口 2 在启动类中添加 ServletComponentScan 注解 二&#xff0c;创建…

汇编常用语法

GNU汇编语句&#xff1a; [lable:] instruction [comment] lable 表示标号&#xff0c;表示地址位置&#xff0c;可选. instruction即指令&#xff0c;也就是汇编指令或伪指令。 comment 就是注释内容。 用户使用.section 伪操作来定义一个段&#xff0c;汇编系统预定义了一些…

terraform resource创建了5台阿里云ecs,如要使用terraform删除其中一台主机,如何删除?

在 Terraform 中删除阿里云 5 台 ECS 实例中的某一台&#xff0c;具体操作取决于你创建资源时使用的 多实例管理方式&#xff08;count 或 for_each&#xff09;。以下是详细解决方案&#xff1a; 方法一&#xff1a;使用 for_each&#xff08;推荐&#xff09; 如果创建时使…

pycharm terminal 窗口打不开了

参考添加链接描述powershell.exe改为cmd.exe发现有一个小正方形&#xff0c;最大化可以看见了。

百度「心响」:左手“多智能体”右手“保姆级服务”,C端用户能看懂这技术告白吗?

——当技术名词撞上“傻瓜式”需求&#xff0c;谁是赢家&#xff1f; 「多智能体」是什么&#xff1f;用户&#xff1a;不重要&#xff0c;能一键搞定就行 百度最新推出的多智能体平台“心响”&#xff0c;号称能用自然语言交互一键托管复杂任务。 从旅游攻略到法律咨询&#x…

57认知干货:AI机器人产业

机器人本质上由可移动的方式和可交互万物的机构组成,即适应不同环境下不同场景的情况,机器人能够做到根据需求调整交互机构和移动方式。因此,随着人工智能技术的发展,AI机器人的产业也将在未来逐步从单一任务的执行者,发展为能够完成复杂多样任务的智能体。 在未来的社会…

在两个bean之间进行数据传递的解决方案

简介 在日常开发中&#xff0c;在两个bean之间进行数据传递是常见的操作&#xff0c;例如在日常开发中&#xff0c;将数据从VO类转移到DO类等。在两个bean之间进行数据传递&#xff0c;最常见的解决方案&#xff0c;就是手动复制&#xff0c;但是它比较繁琐&#xff0c;充斥着…

基于开闭原则优化数据库查询语句拼接方法

背景 在开发实践中&#xff0c;曾有同事在实现新功能时&#xff0c;因直接修改一段数据库查询条件拼接方法的代码逻辑&#xff0c;导致生产环境出现故障。 具体来看&#xff0c;该方法通过在函数内部直接编写条件判断语句实现查询拼接&#xff0c;尽管从面向对象设计的开闭原…

QT开发工具对比:Qt Creator、Qt Designer、Qt Design Studio

前端开发工具—Qt Designer Qt Designer是Qt框架的一部分&#xff0c;是一个图形用户界面设计工具。它允许开发者通过可视化方式设计和布局GUI组件&#xff0c;而无需手动编写UI代码。设计完成后&#xff0c;Qt Designer生成UI文件&#xff08;通常以.ui为扩展名&#xff09;&…

0基础 | STM32 | TB6612电机驱动使用

TB6612介绍及使用 单片机通过驱动板连接至电机 原因&#xff1a;单品机I/O口输出电流I小 驱动板&#xff1a;从外部引入高电压&#xff0c;控制电机驱动 电源部分 VM&#xff1a;电机驱动电源输入&#xff0c;输入电压范围建议为3.7&#xff5e;12V GND&#xff1a;逻辑电…

【操作系统】死锁

1. 定义 死锁是指两个或多个进程&#xff08;或线程&#xff09;在执行过程中&#xff0c;因争夺资源而造成的一种僵局&#xff0c;每个进程都无限期地等待其他进程释放它们所持有的资源。在这种情况下&#xff0c;没有任何进程能够继续执行&#xff0c;除非有外部干预。 2. …

C++入门☞关于类的一些特殊知识点

涉及的关于类中的默认成员函数的知识点可以看我的这篇博客哦~ C入门必须知道的知识☞类的默认成员函数&#xff0c;一文讲透运用 目录 初始化列表 类型转换 static成员 友元 内部类 匿名对象 对象拷贝时的一些编译器的优化 初始化列表 我们知道类中的构造函数的任务是完…

只用Prettier进行格式化项目

1.下载Prettier插件&#xff0c;禁用ESlint 2.在项目根目录新建.prettierrc文件 {"singleQuote": true,"jsxSingleQuote": true,"printWidth": 100,"trailingComma": "none","tabWidth": 2,"semi": f…

XXL-TOOL v1.4.0 发布 | Java工具类库

Release Notes 1、【新增】JsonRpc模块&#xff1a;一个轻量级、跨语言远程过程调用实现&#xff0c;基于json、http实现&#xff08;从XXL-JOB底层通讯组件提炼抽象&#xff09;。2、【新增】Concurrent模块&#xff1a;一系列并发编程工具&#xff0c;具备良好的线程安全、高…

基于LVGL的登录界面设计

目录 一、演示 二、前言 三、部件知识 3.1 图片按钮部件 3.1.1 图片按钮部件的组成 3.1.2 图片的来源 3.1.3 添加/清除的状态 3.1.4 图片按钮部件 API 函数 3.2 键盘部件(lv_keyboard) 3.2.1 键盘部件的组成 3.2.2 键盘部件的相关知识 3.2.2.1 键盘部件模式 3.…

S3 跨账户复制:增强云中的灾难恢复计划

您准备好提升您的云和 DevOps 技能了吗&#xff1f; &#x1f425;《云原生devops》专门为您打造&#xff0c;我们精心打造的 30 篇文章库&#xff0c;这些文章涵盖了 Azure、AWS 和 DevOps 方法论的众多重要主题。无论您是希望精进专业知识的资深专业人士&#xff0c;还是渴望…

线程与进程深度解析:从fork行为到生产者-消费者模型

线程与进程深度解析&#xff1a;从fork行为到生产者-消费者模型 一、多线程环境下的fork行为与线程安全 1. 多线程程序中fork的特殊性 核心问题&#xff1a;fork后子进程的线程模型 当多线程程序中的某个线程调用fork时&#xff1a; 子进程仅包含调用fork的线程&#xff1…

Circular Plot系列(五): circle plot展示单细胞互作

这是我们circle系列的最后一节&#xff0c;我想常见的弦图是绕不开的&#xff0c;所以最后从前面介绍的circle plot思路&#xff0c;做一遍弦图。其实前面的内容如果消化了&#xff0c;plot互作弦图也就不成什么问题了。 效果如下&#xff1a; #cellchat提取互作结果&#xff…