Data-Science-For-Beginners 概率与统计导论:从随机变量、分布到假设检验与相关分析
【免费下载链接】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 的第四课「概率与统计导论」,系统梳理概率论与数理统计在数据科学中的核心概念与实操方法:从随机变量、概率分布出发,到均值、方差、分位数等描述统计量,再通过真实的 MLB 棒球球员数据集演示正态分布、置信区间、Student t 检验、大数定律与中心极限定理,最后用协方差与相关系数完成特征间的关联分析。读者学完本篇后,将能使用 NumPy、Pandas、SciPy 与 Matplotlib 独立完成一套「描述数据 → 估计分布 → 检验假设 → 度量相关」的完整统计分析流程,并在配套 Notebook 与作业中亲手实践。
一、概率与随机变量
概率是介于 0 与 1 之间的一个数,用来表示某个事件发生的可能性大小。在"所有结果等可能"的假设下,它定义为导致该事件的有利结果数除以总结果数。例如掷一枚骰子,得到偶数点的概率是 3/6 = 0.5。
讨论事件时我们引入随机变量的概念。例如,表示"掷一次骰子所得点数"的随机变量 X 可以取 1 到 6 之间的值,这组数(1~6)称为该随机变量的样本空间。我们可以讨论随机变量取某个特定值的概率,例如 P(X=3)=1/6。
上述例子中的随机变量称为离散随机变量,因为它的样本空间是可数的、可以被逐一列举。当样本空间是实数区间或整个实数集时,这样的变量称为连续随机变量,一个典型的例子是公交车的到达时间。
二、概率分布
对于离散随机变量,可以用函数 P(X) 直接描述每个事件的概率:对样本空间 S 中的每个值 s,P(X=s) 给出一个 0 到 1 之间的数,并且所有 P(X=s) 之和恒等于 1。
最著名的离散分布是均匀分布:样本空间有 N 个元素,每个元素概率均为 1/N。
描述连续变量的概率分布则要复杂得多。仍以公交车到达时间为例子:对任意精确的到达时刻 t,公交车恰好在该时刻到达的概率其实是 0!
现在你知道了:概率为 0 的事件确实会发生,而且经常发生——至少每次公交车到站时都是如此!
因此我们只能讨论变量落在某个区间内的概率,例如 P(t₁ ≤ X < t₂)。此时概率分布由概率密度函数p(x) 描述,满足积分关系:
均匀分布的连续版本称为连续均匀分布,定义在有限区间上:X 落入长度为 l 的区间的概率与 l 成正比,最高可达 1。
另一个重要的分布是正态分布,我们将在后面详细讨论。
三、均值、方差与标准差
假设我们从随机变量 X 中抽取了 n 个样本:x₁, x₂, …, xₙ。序列的均值(算术平均)定义为 (x₁+x₂+…+xₙ)/n。当样本量增大(n→∞)时,均值趋近于分布的期望,记作 E(x)。
可以证明,对取值为 {x₁, x₂, …, x_N}、对应概率为 p₁, p₂, …, p_N 的任意离散分布,期望等于 E(X)=x₁p₁+x₂p₂+…+x_N·p_N。
为了衡量取值相对均值的离散程度,可以计算方差σ² = Σ(xᵢ − μ)²/n,其中 μ 是序列均值。σ 称为标准差,σ² 称为方差。
在配套的 notebook.ipynb 中,可以用 NumPy 直接计算:
sample = [ random.randint(0,10) for _ in range(30) ] print(f"Sample: {sample}") print(f"Mean = {np.mean(sample)}") print(f"Variance = {np.var(sample)}")四、众数、中位数与分位数
有时均值并不能很好地代表数据的"典型值"——当存在少数极端值时,均值会被明显拉偏。此时更好的指标是中位数:一半数据点低于它、另一半高于它。
为了进一步理解数据分布,我们使用分位数:
- 第一四分位数 Q1:25% 的数据落在它之下;
- 第三四分位数 Q3:75% 的数据落在它之下。
中位数与四分位数的关系可以用箱线图(box plot)直观表示(见本文开头第一张图)。同时我们还计算四分位距IQR=Q3−Q1,以及所谓的离群值——落在区间 [Q1−1.5·IQR, Q3+1.5·IQR] 之外的值。
对于取值个数较少的有穷分布,出现频率最高的"典型"值是众数。众数常用于类别型数据,例如颜色。设想两组人分别强烈偏好红色与蓝色:若把颜色编码为数字,平均"最喜欢的颜色"会落在橙色到绿色的某个区间,无法代表任何一组的真实偏好;而众数能正确指出最受欢迎的颜色。如果两种颜色票数相同,则称该样本是**多众数(multimodal)**的。
五、真实世界数据:MLB 球员数据集
在分析真实数据时,数据在严格意义上往往不是随机变量——我们并没有做结果未知的实验。例如一个棒球队球员的身高、体重和年龄:这些数并非严格随机,但我们依然可以套用同样的数学概念,把一组球员的体重看作从某个随机变量中抽取的序列。下面是大联盟(Major League Baseball)球员的真实体重序列(为方便起见仅展示前 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]该数据集的完整副本位于仓库的 data/SOCR_MLB.tsv,每行包含 Name、Team、Role、Weight、Height、Age 六个字段,共 1033 名球员。
在 notebook.ipynb 中,用 Pandas 读取并计算核心统计量:
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() print(f"Mean = {mean}\nVariance = {var}\nStandard Deviation = {std}")下面是数据的箱线图,展示了均值、中位数与四分位数:
由于数据包含球员的**位置(Role)**信息,我们还可以按位置分组绘制箱线图。这次考虑身高:
图中暗示:平均而言,一垒手(First_Baseman)比二垒手(Second_Baseman)更高。在后面的章节中,我们将学习如何更正式地检验这个假设,并证明数据具有统计学显著性。
处理真实世界数据时,我们假设所有数据点都是从某个概率分布中抽取的样本。这一假设使我们能够应用机器学习技术并构建可工作的预测模型。
从直方图(见开头第二张图)可以看出,所有值都围绕某个平均体重聚集,离均值越远,出现次数越少。也就是说,球员体重与均值差异很大的情况非常罕见。方差衡量了体重偏离均值的程度。
如果取另一群人的体重(例如大学生而非棒球联赛球员),分布形状大致相同,但均值和方差会改变。因此,如果在棒球球员上训练的模型被用于大学生,结果很可能不准——因为底层分布不同。
六、正态分布
上面观察到的体重分布非常典型:现实中许多测量值都服从同类型分布,只是均值和方差不同。这个分布就是正态分布,它在统计学中扮演着极其重要的角色。
利用正态分布来生成潜在棒球球员的随机体重是正确做法。一旦知道平均体重mean和标准差std,就可以按如下方式生成 1000 个体重样本:
samples = np.random.normal(mean,std,1000)如果把生成样本的直方图画出来,会得到与真实数据非常相似的图像;当样本数量和分箱数增加时,得到的正态分布图像会更接近理想形态(见开头第三张图,均值为 0、标准差为 1)。
注意:由于真实世界的大部分测量值服从正态分布,我们不应使用均匀随机数生成器来生成样本数据。Notebook 中专门演示了用np.random.rand生成均匀权重样本的反例——结果与真实分布形态明显不符:
wrong_sample = np.random.rand(1000)*2*std+mean-std七、置信区间
当我们讨论棒球球员体重时,我们假设存在某个随机变量 W,它对应所有棒球球员体重的理想概率分布(称为总体)。我们手中的体重序列对应其中一部分球员,称为样本。一个有趣的问题是:我们能知道 W 的分布参数(即总体的均值和方差)吗?
最简单的答案是直接计算样本的均值和方差。但随机样本未必能精确代表完整总体,因此讨论置信区间是有意义的。
置信区间:基于样本对总体真实均值的估计,该估计以一定概率(或置信水平)成立。
假设我们有来自分布的样本 X₁, …, Xₙ。每次抽样得到的均值 μ 都不同,因此 μ 可视为随机变量。置信水平为 p 的置信区间是一对数值 (Lₚ, Rₚ),满足 P(Lₚ ≤ μ ≤ Rₚ) = p,即测得均值落入该区间的概率等于 p。
计算置信区间的细节超出了这篇导论的范畴。简要来说,需要定义样本均值相对总体真实均值的分布,这被称为Student 分布(t 分布)。
趣闻:Student 分布以数学家 William Sealy Gosset 命名,他以笔名 "Student" 发表论文。他曾在健力士啤酒厂工作,据其中一种说法,他的雇主不希望公众知道他们在用统计检验评估原材料质量。
若要以置信水平 p 估计总体均值 μ,需要取 Student 分布的 (1−p)/2 分位数 A(可从表中查得,或用 Python、R 等统计软件的现成函数计算),则 μ 的区间由 X ± A·D/√n 给出,其中 X 是样本均值,D 是标准差。与 t 分布密切相关的自由度概念此处略去,可查阅更完整的统计学教材。
在 notebook.ipynb 中,体重的置信区间按如下方式计算:
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}")运行结果如下表:
| p | Weight mean |
|---|---|
| 0.85 | 201.73±0.94 |
| 0.90 | 201.73±1.08 |
| 0.95 | 201.73±1.28 |
可以看到:置信概率越高,置信区间越宽。
八、假设检验
在我们的棒球球员数据集中存在不同的球员位置,可汇总如下(notebook.ipynb 中展示了如何计算这张表):
| Role | Height | Weight | Count |
|---|---|---|---|
| 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 |
可以看出,一垒手的平均身高高于二垒手。我们可能会得出"一垒手比二垒手高"的结论。
这个陈述被称为假设,因为我们并不知道这个事实是否真的成立。
然而,这个结论并不总是显而易见的。从前面的讨论可知,每个均值都对应一个置信区间,因此上述差异可能只是统计误差。我们需要更正式的方法来检验假设。
先分别计算一垒手和二垒手身高的置信区间:
| Confidence | First Basemen | Second Basemen |
|---|---|---|
| 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 |
可以看到,在任何置信水平下两个区间都不重叠。这支持了"一垒手比二垒手高"的假设。
更正式地说,我们要解决的问题是判断两个概率分布是否相同,或至少是否具有相同参数。不同的分布需要不同的检验;如果我们知道分布是正态的,可以应用Student t 检验。
在 Student t 检验中,我们计算所谓的t 值,它考虑方差因素衡量均值之间的差异。可以证明 t 值服从Student 分布,这使我们能得到给定置信水平 p 的阈值(可计算或查表),然后将 t 值与阈值比较来决定接受或拒绝假设。
在 Python 中,可以使用SciPy包,其中包含ttest_ind函数(此外还有很多有用的统计函数!)。它为我们计算 t 值,并做置信度 p 值的反向查询,因此只需查看置信度即可得出结论。
例如,对一垒手与指定击球员(Designated_Hitter)身高的比较结果如下:
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-12本例中 p 值非常低,说明有很强的证据支持"一垒手更高"。ttest_ind返回的两个值含义如下:p 值可视为两个分布均值相同的概率;t 值是在 t 检验中使用的归一化均值差中间量,需与给定置信水平下的阈值进行比较。
我们可能还想检验其他类型的假设,例如:
- 证明给定样本服从某种分布——本例中我们假设身高是正态分布,但这需要正式的统计验证;
- 证明样本均值等于某个预设值;
- 比较多组样本的均值(例如不同年龄段的幸福水平差异)。
九、大数定律与中心极限定理
正态分布如此重要的原因之一是所谓的中心极限定理。假设我们有从任意分布(均值为 μ、方差为 σ²)中抽样的 N 个独立值 X₁, …, X_N,那么当 N 足够大(即 N→∞)时,均值 ΣᵢXᵢ 将服从正态分布,其均值为 μ、方差为 σ²/N。
中心极限定理的另一种解读是:无论原始分布如何,当你计算任意随机变量之和的均值时,最终得到的都是正态分布。
由中心极限定理还可推出:当 N→∞ 时,样本均值等于 μ 的概率趋近于 1。这被称为大数定律。
Notebook 中还用 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.hist(sample) plt.show()十、协方差与相关
数据科学要做的事情之一就是发现数据间的关系。当两个序列同时表现出相似行为——同升同降,或一个上升时另一个下降——我们说这两个序列相关。换言之,两个序列之间似乎存在某种关系。
相关并不一定意味着两个序列之间存在因果关系:有时两个变量都依赖于某个外部原因,也可能只是偶然相关。但强数学相关是两变量存在某种联系的良好指示。
数学上,两个随机变量之间的关系由协方差度量,其计算公式为 Cov(X,Y) = E[(X−E(X))(Y−E(Y))]。我们计算两个变量相对各自均值的偏差,再取这些偏差的乘积。如果两个变量同步偏离,乘积恒为正,累加得到正协方差;如果它们不同步(一个低于均值时另一个高于均值),乘积恒为负,累加得到负协方差;如果偏差互不依赖,则累加结果约为零。
协方差的绝对值并不能告诉我们相关有多强,因为它依赖数值的实际量级。为将其归一化,我们把协方差除以两个变量的标准差,得到相关系数。相关系数始终落在 [-1,1] 区间内:1 表示强正相关,-1 表示强负相关,0 表示无相关(变量独立)。
示例:计算上述数据集中球员体重与身高的相关:
print(np.corrcoef(weights,heights))结果为相关矩阵:
array([[1. , 0.52959196], [0.52959196, 1. ]])相关矩阵 C 可对任意数量的输入序列 S₁, …, Sₙ 计算。Cᵢⱼ 是 Sᵢ 与 Sⱼ 的相关系数,对角线元素恒为 1(即 Sᵢ 的自相关)。
本例中 0.53 表明人的体重与身高之间存在一定相关。我们还可以绘制散点图直观观察两者关系:
一个有趣的案例:相关 vs 因果
Notebook 中用"邪恶棒球公司"的玩具案例演示相关与因果的区别:假设公司按身高发薪水——底薪 1000 美元,另按身高加 0 到 100 美元奖金。此时身高与"薪水"的相关系数接近 1(强线性关系);当把奖金公式改成包含sin的非线性项并加入随机噪声后,相关性下降,散点图也出现明显的垂直条带。这说明强相关只是线性关系的指示器,而非因果证明。
数据清洗的必要性
在计算真实变量身高与体重的相关时,最初会得到一堆奇怪的nan值——因为序列中存在缺失值(nan),导致运算结果未定义。这直观地展示了数据准备与清洗的重要性:没有干净的数据,什么也计算不了。用fillna/ffill填补缺失值后再计算,就能得到真实的相关系数。
十一、总结
在本节中,我们学习了:
- 数据的基本统计属性:均值、方差、众数和四分位数;
- 随机变量的不同分布,包括正态分布;
- 如何发现不同属性之间的相关关系;
- 如何运用数学和统计工具证明某些假设;
- 如何根据数据样本为随机变量计算置信区间。
虽然这不是概率与统计的全部主题,但它足以让你在这门课程中有一个良好的开端。
十二、实战:配套 Notebook 与糖尿病作业
动手运行 Notebook
本课的核心可运行示例全部集中在 notebook.ipynb 中,涉及随机变量与分布采样、真实数据分析、正态分布模拟、置信区间、假设检验、中心极限定理实现,以及协方差/相关的玩具案例(包括上述"邪恶棒球公司"示例与缺失值清洗演示)。Notebook 中还内置了多处挑战,你可以通过向其中添加代码来完成它们。如果在后续课程中想了解如何用 Jupyter Notebook 执行代码,可以参考仓库内其他课程的说明。
糖尿病小研究(Assignment)
课后作业是 assignment.md 描述的"Small Diabetes Study",基于仓库内的 data/diabetes.tsv 数据集(442 名糖尿病患者的 11 项指标)。其中 AGE 为年龄,SEX 为性别,BMI 为身体质量指数,BP 为平均血压,S1~S6 为不同血液指标,Y 为一年内疾病进展的定性度量。你需要在 assignment.ipynb 中完成以下任务:
- 计算所有变量的均值和方差;
- 按性别(SEX)绘制 BMI、BP 和 Y 的箱线图;
- 分析 Age、Sex、BMI 和 Y 变量的分布形态;
- 检验各变量与疾病进展(Y)之间的相关性;
- 检验"男女糖尿病进展程度不同"的假设。
仓库中的参考答案 solution/assignment.ipynb 给出了每项任务的实现与结论,可作为对照:
- 任务 1:
df.describe()或pd.DataFrame([df.mean(), df.var()], index=['Mean','Variance'])直接给出均值与方差,例如 BMI 均值 26.38、方差 19.52,Y 均值 152.13、方差 5943.33。 - 任务 3:绘制直方图后判断——Age 近似正态、Sex 近似均匀,BMI 与 Y 形态不明显。
- 任务 4:用
df.corr()得到相关矩阵。与 Y 相关最强的变量是 BMI(0.586)、S5 血糖指标(0.566)和 BP(0.441),符合医学直觉;再用散点图可视化 Y 与 BMI、S5、BP 的关系。 - 任务 5:用
ttest_ind检验男女的 Y 是否不同,结果为 T-value = -0.90,P-value ≈ 0.367。p 值接近 0(通常低于 0.05)才表示对假设有较高置信度;本例没有强证据表明性别影响糖尿病进展。
挑战:检验更多假设
使用 Notebook 中的样例代码,检验以下假设:
- 一垒手比二垒手年龄更大;
- 一垒手比三垒手更高;
- 游击手比二垒手更高。
延伸阅读建议
概率与统计是极其广阔的领域,足以开设专门课程。如需深入理论,可阅读以下资源:纽约大学 Carlos Fernandez-Granda 的《Probability and Statistics for Data Science》讲义、Peter 与 Andrew Bruce 合著的《Practical Statistics for Data Scientists》、James D. Miller 的《Statistics for Data Science》。本课由 Dmitry Soshnikov 撰写,配套的全部数据(data/SOCR_MLB.tsv、data/diabetes.tsv)与可运行 Notebook(notebook.ipynb、assignment.ipynb)均已随仓库提供,可直接克隆后按上文步骤实践。
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考