Data-Science-For-Beginners 第 04 课:概率与统计入门——从概率分布到置信区间与假设检验(MLB 实战)
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
本文基于 Data-Science-For-Beginners 课程第 04 课(1-Introduction/04-stats-and-probability,本仓库以法语版translations/fr/1-Introduction/04-stats-and-probability/README.md为指定文档)撰写,系统讲解概率与随机变量、概率分布、均值/方差/标准差、分位数与箱线图、正态分布、置信区间、假设检验、大数定律与中心极限定理、协方差与相关性等核心概念,并结合课程配套的 notebook.ipynb 与 data/SOCR_MLB.tsv 真实数据集,演示如何用 NumPy、Pandas 和 SciPy 把这些概念落地为可运行的代码。读完本文,你将能够独立完成描述性统计、置信区间计算和两样本 t 检验,并理解机器学习建模前“数据服从某概率分布”这一假设的来源。
说明:法语文档本身是由自动翻译服务生成的译文(原文为英文课程),本文在其技术内容基础上结合仓库源码与数据文件做了核对与扩充。课程在本节前后各设置了课前/课后测验(pre/post quiz),可配合学习。
1. 为什么数据科学离不开概率与统计
统计学与概率论是两个紧密关联的数学领域,对数据科学高度相关。即使不深入研究数学也能操作数据,但至少掌握一些基本概念仍然更有利。原文档给出的定位是:这是一篇“帮助你起步”的简短入门,覆盖概念定义 + 真实数据演练两条主线。
本仓库将这一课放在1-Introduction(第 1 阶段:介绍)中的第 04 节,前接“定义数据”,后接“关系数据库”,是课程中唯一一节系统性引入数学工具的课程,后续的数据准备、数据可视化与数据科学生命周期各阶段都会反复使用这里建立的概念。
2. 概率与随机变量
2.1 概率的定义
概率(Probability)是介于 0 和 1 之间的一个数,用来表达某个**事件(event)**发生的可能性大小。在假定所有结果等可能的前提下,其定义为:
概率 = 有利结果数(导致该事件的结果) / 结果总数
原文档的经典例子:掷一枚骰子,得到偶数的概率是 3/6 = 0.5(结果为 2、4、6 共 3 种,总结果 6 种)。
2.2 随机变量与样本空间
描述事件时,数学上用随机变量(random variable)来表达。例如,表示掷骰子所得点数的随机变量取值 1 到 6,集合 {1, 2, 3, 4, 5, 6} 称为样本空间(sample space)。进而可以谈论随机变量取某个值的概率,例如 P(X=3) = 1/6。
随机变量分为两类:
- 离散(discrete):样本空间可数,即存在可以逐一列举的离散取值(如掷骰子的 1–6);
- 连续(continuous):样本空间是某个实数区间,甚至是整个实数集 ℝ。原文档给出的好例子是“公交车到达的时间”。
3. 概率分布
3.1 离散分布与均匀分布
对离散随机变量,可以用函数 P(X) 直接描述每个事件的概率:对样本空间S中的每个取值s,P(X=s) 给出 0 到 1 之间的一个数,且所有事件概率之和等于 1。
最著名的离散分布是均匀分布(uniform distribution):样本空间含 N 个元素,每个元素概率均为 1/N。掷骰子正是 6 元均匀分布。
3.2 连续分布与概率密度函数
连续变量的概率分布描述起来更微妙。以公交车到达时间为例:对任意一个精确的到达时刻t,公交车恰好在这一瞬间到达的概率其实是0!
原文档的幽默注释:现在你知道了——概率为 0 的事件不仅会发生,而且非常频繁,至少每次公交车到站时都在发生。
因此对连续变量,只能谈论它落在某个区间内的概率,例如 P(t₁ ≤ X < t₂)。此时分布由概率密度函数(probability density function)p(x)描述,满足:
P(t₁ ≤ X < t₂) = ∫ᵗ¹ᐟᵗ² p(x) dx(即密度函数在区间上的积分)
连续版均匀分布称为连续均匀分布,定义在有限区间上:X 落入某个长度为 l 的区间的概率与 l 成正比,最大为 1。另一个重要的分布是正态分布,在第 7 节详述。
4. 均值、方差与标准差
设我们从随机变量 X 中抽取 n 个样本:x₁, x₂, ..., xₙ。
均值(mean / arithmetic average,均值或算术平均)按传统方式定义为 (x₁ + x₂ + ... + xₙ)/n。当样本量增大(即取 n→∞ 的极限)时,就得到分布的均值,也叫期望(expectation),记作E(x)。
原文档补充:可以证明,对任意离散分布,取值 {x₁, ..., xₙ} 对应概率 p₁, ..., pₙ,其期望为 E(X) = x₁p₁ + x₂p₂ + ... + xₙpₙ。
要衡量取值离散的程度,可以计算方差:σ² = Σ(xᵢ − μ)²/n,其中 μ 是序列均值。σ 称为标准差(standard deviation),σ² 称为方差(variance)。
在课程 notebook 中,这两者直接由 NumPy 给出:
import numpy as np import pandas as pd df = pd.read_csv("../../data/SOCR_MLB.tsv", sep='\t', header=None, names=['Name', 'Team', 'Role', 'Weight', 'Height', 'Age']) mean = df['Height'].mean() var = df['Height'].var() std = df['Height'].std()这段加载与统计代码见 notebook.ipynb 的“Analyzing Real Data”部分。
5. 众数、中位数与四分位数
有时均值不能很好地代表数据的“典型值”——例如存在少数完全超出范围的极端值时,均值会被明显拉偏。此时**中位数(median)**是更好的指示:一半数据点小于它,另一半大于它。
为了理解数据分布,还要谈论四分位数(quartiles):
- 第一四分位数 Q1:25% 的数据小于该值;
- 第三四分位数 Q3:75% 的数据小于该值。
中位数与四分位数的关系可以用**箱线图(box plot)**图形化表示:
在箱线图中还要计算四分位距 IQR = Q3 − Q1,以及离群值(outliers)——落在 [Q1 − 1.5×IQR, Q3 + 1.5×IQR] 边界之外的取值。
对于取值种类有限的分布,一个好的“典型值”是出现频率最高的取值,即众数(mode)。它常用于分类数据(如颜色)。原文档的例子:假设一群人强烈偏好红色、另一群人偏好蓝色,若把颜色编码为数字,均值会落在橙绿光谱之间的某个无意义位置,无法反映任何一群人的真实偏好;而众数会是其中一种颜色,若两色票数相等则样本是**多峰(multimodal)**的。
6. 用真实数据应用统计概念:MLB 数据集
6.1 数据集与加载
分析现实数据时,数据往往不是严格意义上的随机变量(我们没有在做结果未知的实验)。原文档的例子是一支棒球队的身体数据:身高、体重、年龄。这些数字不完全是随机的,但依然可以套用同样的数学概念——例如把一系列体重视为从某个随机变量中抽取的样本序列。
课程使用的数据集取自 SOCR MLB Height/Weight 数据集,在仓库中为 data/SOCR_MLB.tsv(共 1033 名球员记录,制表符分隔)。从数据文件可见,其前三列依次为球员姓名、球队、场上位置(Role),随后是身高(英寸,约 71–75)、体重(磅,约 160–230)、年龄三个数值列;notebook.ipynb 通过names参数把后三列映射为Weight、Height、Age(header=None表示文件无表头)。复现文档中的数值前,建议先按数值量级核对各列含义,确认列对应关系正确。
原文档给出了前 20 个体重的示例序列(已核对与 TSV 文件前 20 行一致):
[180.0, 215.0, 210.0, 210.0, 188.0, 176.0, 209.0, 200.0, 231.0, 180.0, 188.0, 180.0, 185.0, 160.0, 180.0, 185.0, 197.0, 189.0, 185.0, 219.0]提示(继承原文档):要查看使用本数据集的完整示例,请打开配套的 notebook.ipynb。本课中散布着若干挑战任务,可通过往该 notebook 里添加代码来完成。若不确定如何操作数据,不必担心——课程后续会用 Python 系统讲解数据处理。
6.2 总体箱线图与按角色的箱线图
对体重画箱线图,可以同时展示均值、中位数和四分位数。由于数据包含不同的球员角色(role),还可以按角色分别绘制身高箱线图,直观比较各位置的参数差异:
notebook 中对应代码为df.boxplot(column='Height', by='Role', ...)与水平方向的总体箱线图plt.boxplot(df['Height'].ffill(), orientation='horizontal', showmeans=True)。
从该图可以看出:一垒手(First Baseman)的平均身高高于二垒手(Second Baseman)。原文档明确指出:这只是一个观察,稍后我们会学习如何更形式化地检验这个假设,并证明数据具有统计显著性。
原文档强调的核心假设:处理现实数据时,我们假定所有数据点都来自某个概率分布的抽样。正是这一假设让我们能应用机器学习技术、构建可用的预测模型。
6.3 直方图与“分布形状”的警示
要看数据到底是什么分布,可以画直方图(histogram):X 轴是一系列体重区间(称为bins),纵轴是样本落入各区间的次数。原文档的结论是:数值集中在某个平均体重附近,离得越远取值越少——棒球员体重显著偏离均值的概率很低;体重的方差则刻画了偏离均值的幅度。
原文档的重要警示(务必继承):如果换成非棒球联赛人群(例如大学生)的体重,分布很可能不同,但分布形状相同,只是均值和方差改变。因此,如果在棒球运动员上训练模型,直接应用到大学生身上很可能给出错误结果,因为底层分布不同。
7. 正态分布
上面看到的体重分布非常有代表性:现实中大量测量值都服从同类型的分布,只是均值与方差不同。这种分布就是正态分布(normal distribution),在统计学中地位极其重要。
用正态分布来生成“潜在棒球员”的随机体重是正确做法。已知平均体重mean和标准差std后,生成 1000 个样本:
samples = np.random.normal(mean, std, 1000)对生成的样本画直方图,会得到与真实体重分布非常相似的画面;进一步增大样本数与 bins 数量,可以逼近理想的正态分布(原文档配有 mean=0、std=1 的标准正态直方图,见1-Introduction/04-stats-and-probability/images/normal-histogram.png)。
notebook 还补充了一个“反例”演示:若错误地用均匀随机数生成器(np.random.rand)去模拟体重,得到的分布形状会完全不对:
wrong_sample = np.random.rand(1000) * 2 * std + mean - std结论(notebook 原文):因为现实中大多数量近似正态分布,生成模拟样本数据时不应使用均匀随机数生成器。
8. 置信区间
8.1 总体、样本与置信区间的定义
谈棒球员体重时,我们假定存在某个随机变量 W,对应全体棒球员(称为总体 population)体重的理想概率分布;而手头的一串体重是总体中的一个子集,称为样本 sample。有意思的问题是:能否知道 W 的分布参数,即总体的均值和方差?
最朴素的答案是计算样本的均值和方差,但随机样本未必精确代表总体,因此需要谈论置信区间(confidence interval):
置信区间是基于给定样本对总体真实均值的估计,它在一定概率(即置信水平 confidence level)下是准确的。
设样本为 X₁, ..., Xₙ。每次从分布中抽样都会得到不同的均值 μ,因此 μ 本身也可视为随机变量。置信水平为 p 的置信区间是一对值 (Lₚ, Rₚ),满足P(Lₚ ≤ μ ≤ Rₚ) = p,即测得均值落入该区间内的概率为 p。
8.2 计算方式:Student 分布
原文档说明(并诚实标注“这超出了本入门范围”):计算置信区间时,我们定义“样本均值相对于总体真实均值”的分布,称为Student 分布(学生分布)。
有趣的事实:Student 分布以数学家 William Sealy Gosset 命名,他以笔名 “Student” 发表论文。他曾在 Guinness 酿酒厂工作,据一种说法,雇主不希望公众知道他们在用统计检验评估原料质量。
若要以置信水平 p 估计总体均值 μ,需取 Student 分布的(1−p)/2 分位数A(可查表,也可用统计软件内置函数计算,如 Python、R)。于是 μ 的区间为:
μ ∈ X̄ ± A·D/√n
其中 X̄ 是样本均值,D 是标准差,n 是样本量。
注:原文档同时声明省略了一个重要概念——自由度(degrees of freedom),它与 Student 分布密切相关,建议查阅更完整的统计书籍深入理解。
8.3 notebook 中的实现与结果
notebook.ipynb 给出了完整实现(基于 SciPy 的 t 分布分位数函数):
import scipy.stats def mean_confidence_interval(data, confidence=0.95): a = 1.0 * np.array(data) n = len(a) m, se = np.mean(a), scipy.stats.sem(a) h = se * scipy.stats.t.ppf((1 + confidence) / 2., n - 1) return m, h for p in [0.85, 0.9, 0.95]: m, h = mean_confidence_interval(df['Weight'].ffill(), p) print(f"p={p:.2f}, mean = {m:.2f} ± {h:.2f}")其中scipy.stats.sem是标准误,scipy.stats.t.ppf((1 + confidence) / 2., n - 1)即为 Student 分布的对应分位数 A(双尾,自由度 n−1)。原文档给出的体重均值置信区间结果为:
| p | 体重均值 |
|---|---|
| 0.85 | 201.73 ± 0.94 |
| 0.90 | 201.73 ± 1.08 |
| 0.95 | 201.73 ± 1.28 |
注意:置信概率越高,置信区间越宽。
9. 假设检验
9.1 从数据观察提出假设
MLB 数据集中球员有不同角色,各角色的汇总统计(可由 notebook 的df.groupby('Role').agg({'Weight': 'mean', 'Height': 'mean', 'Age': 'count'})计算,本文已对照 data/SOCR_MLB.tsv 复核)如下:
| 角色 | 身高(均值) | 体重(均值) | 人数 |
|---|---|---|---|
| Catcher(捕手) | 72.723684 | 204.328947 | 76 |
| Designated_Hitter(指定击球手) | 74.222222 | 220.888889 | 18 |
| First_Baseman(一垒手) | 74.000000 | 213.109091 | 55 |
| Outfielder(外野手) | 73.010309 | 199.113402 | 194 |
| Relief_Pitcher(救援投手) | 74.374603 | 203.517460 | 315 |
| Second_Baseman(二垒手) | 71.362069 | 184.344828 | 58 |
| Shortstop(游击手) | 71.903846 | 182.923077 | 52 |
| Starting_Pitcher(先发投手) | 74.719457 | 205.163636 | 221 |
| Third_Baseman(三垒手) | 73.044444 | 200.955556 | 45 |
可以注意到一垒手平均身高高于二垒手,于是容易得出“一垒手比二垒手更高”的结论。
这种陈述称为假设(hypothesis),因为我们并不知道它是否真的成立。
但每个均值都带有置信区间,观察到的差异可能只是统计误差,需要更形式化的检验方法。
9.2 方法一:比较置信区间
分别计算一垒手与二垒手身高的置信区间(原文档数值,法语版以逗号作小数点,此处统一为英文小数点):
| 置信水平 | 一垒手身高 | 二垒手身高 |
|---|---|---|
| 0.85 | 73.62..74.38 | 71.04..71.69 |
| 0.90 | 73.56..74.44 | 70.99..71.73 |
| 0.95 | 73.47..74.53 | 70.92..71.81 |
在任何置信水平下两组区间都不重叠,从而支持“一垒手比二垒手更高”这一假设。
9.3 方法二:Student t 检验
更形式化地说,我们要解决的是两个概率分布是否相同(至少参数是否相同)的问题。根据分布类型,检验方法不同;若已知分布为正态,可应用Student t 检验(Student t-test)。
t 检验的步骤:计算所谓的t 值(t-value)——在考虑方差的前提下衡量两组均值的差异;可以证明 t 值服从Student 分布,由此得到给定置信水平 p 的阈值(可计算或查表);最后比较 t 值与阈值,以接受或拒绝假设。
在 Python 中,SciPy提供了ttest_ind函数(该库还有大量其他有用的统计函数):它替我们计算 t 值,并做置信度 p 值的反查,因此直接查看 p 值即可下结论。原文档给出的示例代码(比较一垒手与指定击球手身高):
from scipy.stats import ttest_ind tval, pval = ttest_ind(df.loc[df['Role']=='First_Baseman', ['Height']], df.loc[df['Role']=='Designated_Hitter', ['Height']], equal_var=False) print(f"T-value = {tval[0]:.2f}\nP-value: {pval[0]}")T-value = 7.65 P-value: 9.137321189738925e-12p 值极低,意味着有充分证据支持“一垒手更高”的结论。参数equal_var=False表示采用 Welch 修正,不假定两组方差相等。notebook 中的对照版本比较的是 First_Baseman 与 Second_Baseman(见 notebook.ipynb),并对两个返回值的含义作了说明:
- p 值可视为“两个分布具有相同均值”的概率;本例中它非常低,说明有强证据支持一垒手更高;
- t 值是 t 检验中归一化均值差的中间量,需要与给定置信水平下的阈值比较。
原文档还列出其他常见的待检验假设类型:
- 证明某个样本服从特定分布(我们一直假设身高正态分布,但这需要形式化的统计验证);
- 证明样本均值等于某个预定义值;
- 比较多组样本的均值(例如不同年龄组的幸福水平差异)。
10. 大数定律与中心极限定理
正态分布之所以重要,原因之一是中心极限定理(central limit theorem):设有一个大样本,包含 N 个独立取值 X₁, ..., Xₙ,来自任意一个均值为 μ、方差为 σ² 的分布。则当 N 足够大(即 N→∞)时,均值 ΣᵢXᵢ 近似服从正态分布,均值为 μ,方差为 σ²/N。
换一种理解方式:无论原始分布如何,对一组随机变量取值求和再取均值,结果都是正态分布。
由中心极限定理还可推出:当 N→∞ 时,样本均值等于 μ 的概率趋于 1,这就是大数定律(law of large numbers)。
notebook 用中心极限定理现场“造”了一个正态随机数生成器(见 notebook.ipynb):Python 的伪随机生成器默认给均匀分布,而对一批均匀随机数求均值,即可得到近似正态分布的值:
def normal_random(sample_size=100): sample = [random.uniform(0, 1) for _ in range(sample_size)] return sum(sample) / sample_size sample = [normal_random() for _ in range(100)] plt.figure(figsize=(10, 6)) plt.hist(sample) plt.tight_layout() plt.show()11. 协方差与相关性
11.1 概念与公式
数据科学的任务之一是发现数据间的关系。当两条序列在相同时刻表现出相似行为时,我们说它们相关(correlate):要么同升同降,要么一升一降。换句话说,两条序列之间似乎存在某种关系。
原文档的告诫:相关不一定意味着因果;有时两个变量共同依赖于某个外部原因,也可能是纯粹的巧合。但强的数学相关是两变量以某种方式相连的良好信号。
数学上刻画两个随机变量关系的核心概念是协方差(covariance):
Cov(X, Y) = E[(X − E(X)) · (Y − E(Y))]
即先计算两个变量各自相对均值的偏差,再取偏差的乘积并求期望。若两个变量同向偏离,乘积恒为正,协方差为正;若反向偏离(一个低于均值时另一个高于均值),乘积恒为负,协方差为负;若偏差相互独立,则大致相消为零。
协方差的绝对值本身说明不了相关强度有多大,因为它取决于实际取值的量级。为做归一化,用协方差除以两个变量的标准差,得到相关系数(correlation)。其好处是取值恒在 [−1, 1] 区间:1 表示强正相关,−1 表示强负相关,0 表示完全不相关(变量相互独立)。
11.2 实战:身高与体重的相关矩阵
用 NumPy 计算 MLB 球员体重与身高的相关性:
print(np.corrcoef(weights, heights))结果是相关矩阵(correlation matrix):
array([[1. , 0.52959196], [0.52959196, 1. ]])相关矩阵 C 可对任意数量的输入序列 S₁, ..., Sₙ 计算。Cᵢⱼ 是 Sᵢ 与 Sⱼ 的相关系数,对角线元素恒为 1(即 Sᵢ 与自身的相关)。
0.53 说明人的体重与身高之间存在一定相关。用散点图可以直观看到这种关系:
11.3 notebook 补充:数据清洗与非线性陷阱
notebook 还给出了几个值得借鉴的细节(“Correlation and Evil Baseball Corp”部分):
- 人工构造的线性关系:假设一家“邪恶棒球公司”按身高发薪(底薪 1000 美元 + 按身高线性加成 0–100 美元),此时
np.cov/np.corrcoef显示相关系数为 1,散点图呈完全线性; - 加入非线性:把加成公式改成
sin函数后,相关系数下降但仍较高——相关系数主要刻画线性关系; - 叠加噪声:再给工资加一个 ±10 的随机扰动,相关系数进一步下降;
- 真实变量的 nan 陷阱:直接对原始列计算
np.corrcoef(df['Height'].ffill(), df['Weight'])会得到nan,因为序列中存在缺失值;必须先用ffill()/fillna处理缺失值,相关系数(0.53)才得以计算出来。
这一节的 takeaway(notebook 原文):它展示了数据准备与清洗的重要性——没有合适的数据,什么都算不出来。
12. 挑战任务
使用 notebook 中的示例代码,检验以下其他假设(继承原文档 Challenge 一节):
- 一垒手的年龄大于二垒手;
- 一垒手的身高大于三垒手;
- 游击手的身高大于二垒手。
可直接复用第 9 节的mean_confidence_interval与ttest_ind代码,只需替换Role过滤条件和比较列即可。
13. 延伸阅读与课后作业
原文档说明:概率与统计范围极广,值得单独开一门课。若想深入理论,原文档推荐了三份材料(此处仅列书名与作者,不含外链):
- 纽约大学 Carlos Fernandez-Granda 的讲义Probability and Statistics for Data Science;
- Peter Bruce 与 Andrew Bruce 的Practical Statistics for Data Scientists(附 R 示例代码);
- James D. Miller 的Statistics for Data Science(附 R 示例代码)。
课后作业:Small Diabetes Study。作业使用仓库内的 data/diabetes.tsv(442 名糖尿病患者的记录,列包括 AGE、SEX、BMI、BP、六项血液指标 S1–S6,以及一年后病情进展指标 Y,样例数据见 assignment.md 中的表格),配套 assignment.ipynb 中列出 5 个任务:
- 计算所有数值的均值与方差;
- 按性别绘制 BMI、BP 与 Y 的箱线图;
- 判断 Age、Sex、BMI、Y 各变量的分布类型;
- 检验各变量与病情进展(Y)的相关性(提示:相关矩阵最有信息量);
- 检验“男性与女性的糖尿病进展程度不同”这一假设。
仓库中同时提供了参考解答 solution/assignment.ipynb,可对照自查。
14. 小结
继承原文档 Conclusion,本节(本文章)覆盖的内容:
- 数据的基本统计性质:均值、方差、众数与四分位数;
- 随机变量的各类分布,包括正态分布;
- 如何寻找不同属性之间的相关性;
- 如何运用数学与统计工具证明(或拒绝)某些假设;
- 如何基于数据样本计算随机变量的置信区间。
这当然不是概率统计全部主题的穷举,但对于进入后续课程(数据准备、可视化、数据科学生命周期)而言,已经是一个足够好的起点。本课程的完整脉络可参考仓库根目录 README.md,第 04 课在其中的位置见 1-Introduction/README.md。
本文基于仓库文档 translations/fr/1-Introduction/04-stats-and-probability/README.md 编写,配套资源:课程 notebook、数据集 SOCR_MLB.tsv、课后作业 与 参考解答。本课作者为 Dmitry Soshnikov(见原文档 Credits)。
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考