数据科学入门课程第 4 课:用 Python 掌握概率、统计推断与假设检验基础
2026/9/10 15:03:18 网站建设 项目流程

数据科学入门课程第 4 课:用 Python 掌握概率、统计推断与假设检验基础

【免费下载链接】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 课程的第 4 课《统计与概率入门》,配套孟加拉语翻译位于 translations/bn/1-Introduction/04-stats-and-probability/README.md,英文原版位于 1-Introduction/04-stats-and-probability/README.md)以棒球运动员的真实数据为案例,带你从随机变量出发,一路走到用 SciPy 完成 t 检验与相关性分析,最终有能力独立完成"小型糖尿病研究"实战作业。

概率与随机变量:一切推断的起点

概率(Probability)是介于 0 到 1 之间的数字,用来表示某个**事件(event)**发生的可能性大小。它的定义是"导致该事件的有利结果数除以总结果数",前提是所有结果等可能发生。例如掷一枚骰子,得到偶数的概率是 3/6 = 0.5。

讨论事件时我们会使用随机变量(random variable)。例如"掷骰子得到的点数"这个随机变量取值从 1 到 6,这组取值构成的集合称为样本空间(sample space)。我们可以谈论随机变量取某个具体值的概率,比如 P(X=3)=1/6。

随机变量分为两类:

  • 离散随机变量:样本空间可数,即存在可枚举的独立取值。掷骰子结果就是典型例子。
  • 连续随机变量:样本空间是一段实数区间甚至整个实数集 ℝ。公交车到达时间就是很好的例子——对任何一个精确的时刻 t,公交车"恰好在该时刻到达"的概率都是 0!

现在你知道了:概率为 0 的事件不但存在,而且经常发生——至少每次公交车到站时都发生了一次!

概率分布:描述随机变量取值的规律

对于离散随机变量,可以用函数 P(X) 描述每个事件的概率:对样本空间S中的每个值s,它给出一个 0 到 1 之间的数,且所有 P(X=s) 之和为 1。最著名的离散分布是均匀分布(uniform distribution):样本空间含 N 个元素,每个元素概率相等,均为 1/N。

连续变量的概率分布更难描述。我们只能谈论变量落入某个取值区间的概率,例如 P(t₁≤X<t₂)。此时概率分布由概率密度函数(probability density function)p(x) 描述:

均匀分布的连续版本称为连续均匀分布,定义在有限区间上:X 落入长度为 l 的区间的概率与 l 成正比,最高可达 1。另一个极为重要的分布是正态分布(normal distribution),下文将详细展开。

均值、方差与标准差:刻画数据中心与离散程度

假设我们从随机变量 X 中抽取 n 个样本:x₁, x₂, ..., xₙ。序列的均值(mean,又称算术平均)传统上定义为 (x₁+x₂+...+xₙ)/n。当样本量趋于无穷(n→∞)时,我们得到分布的均值,也称期望(expectation),记为E(x)。

可以证明:对于任意离散分布,若取值为 {x₁, x₂, ..., xₙ}、对应概率为 p₁, p₂, ..., pₙ,则期望 E(X) = x₁p₁ + x₂p₂ + ... + xₙpₙ。

为刻画数值的离散程度,可以计算方差(variance)σ² = ∑(xᵢ - μ)²/n,其中 μ 是序列均值。σ 称为标准差(standard deviation),σ² 称为方差

在配套的 教学 Notebook 中,这些概念被直接落地为代码:先用random.randint生成 30 个均匀随机样本,再用np.meannp.var计算均值和方差;随后加载真实棒球数据SOCR_MLB.tsv,对身高列计算均值、方差与标准差:

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() print(f"Mean = {mean}\nVariance = {var}\nStandard Deviation = {std}")

注意这里的数据文件位于仓库根目录下的 data/SOCR_MLB.tsv,字段依次为球员姓名、球队、场上角色、体重(英寸)、身高(磅)与年龄,与names参数一一对应。

众数、中位数与四分位数:抗离群值的"典型值"

有时均值并不能很好地代表数据的"典型"水平。比如存在少数完全超出范围的极端值时,它们会拉偏均值。更好的指标是中位数(median):一半数据点低于它,另一半高于它。

为了理解数据分布,引入四分位数(quartile)

  • 第一四分位数 Q1:25% 的数据低于它;
  • 第三四分位数 Q3:75% 的数据低于它。

中位数与四分位数之间的关系可以用**箱线图(box plot)**直观呈现:

箱线图还定义了两个衍生量:四分位距(inter-quartile range)IQR = Q3 - Q1,以及所谓的离群值(outliers)——落在边界 [Q1-1.5×IQR, Q3+1.5×IQR] 之外的值。

当有限分布的可能取值很少时,出现频率最高的值称为众数(mode),常用于颜色等类别型数据。设想两组人——一组强烈偏爱红色,另一组偏爱蓝色。若把颜色编码为数字,偏好颜色的均值会落在橙绿光谱的某个中间位置,完全无法反映任何一组的真实偏好;而众数则要么是红色要么是蓝色——如果两方人数相同,众数会同时是两个颜色,此时称样本为多模态(multimodal)

Notebook 中同样给出了实操代码:用plt.boxplot绘制身高的水平箱线图(showmeans=True会同时标出均值),再用df.boxplot(column='Height', by='Role')按场上角色分组绘制,直观对比不同位置球员的身高分布。

真实世界数据:把棒球运动员当作随机样本

分析真实数据时,它们严格来说并不是随机变量——我们并没有做结果未知的实验。以棒球队球员的身体数据(身高、体重、年龄)为例,这些数字并非完全随机,但我们仍可套用同样的数学工具:把一组人的体重视为从某个随机变量中抽取的样本序列。下面这组数据来自美国职棒大联盟(MLB),取自 SOCR 的 MLB 身高体重数据集(为方便展示,仅列出前 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,课程中还有若干挑战,你可以在其中补充代码完成。若还不熟悉在 Jupyter Notebook 中运行代码,可以稍后随课程第 7 课(07-python)系统学习。

这份数据的均值、中位数与四分位数可以用箱线图呈现:

由于数据包含不同球员**角色(role)**信息,我们还可以按角色绘制箱线图——这能直观看出参数取值如何随角色变化。这次我们考察身高:

这幅图提示:平均而言,一垒手的身高高出二垒手。本课稍后我们将学习如何用更正式的方式检验这一假设,并证明数据在统计上显著。

处理真实数据时,我们假定所有数据点都是从某个概率分布中抽取的样本。这一假设使我们能够应用机器学习技术、构建可用的预测模型。

为观察数据分布,可以绘制直方图(histogram):X 轴是若干体重区间(称为箱/bins),纵轴表示随机变量样本落入该区间的次数:

从直方图可以看出,所有值都围绕某个平均体重居中分布,离均值越远,出现该体重的人越少。也就是说,棒球球员的体重极不可能与平均体重相差悬殊;方差的大小则表明体重偏离均值的可能程度。

如果取棒球联盟之外人群的体重,分布很可能不同——但形状保持不变,只是均值和方差会改变。因此,若用棒球球员训练模型再套用到大学生身上,结果很可能是错的,因为底层分布不同。

正态分布:用 NumPy 生成符合现实的样本

上面体重数据的分布非常典型,现实中大量测量值遵循同类型分布,只是均值与方差不同,这就是正态分布——统计学中举足轻重的角色。

利用正态分布,我们可以正确生成潜在棒球球员的随机体重:只要知道平均体重mean和标准差std,就能这样生成 1000 个体重样本:

samples = np.random.normal(mean, std, 1000)

绘制生成样本的直方图,会得到与上图几乎相同的形态;若继续增大样本数与箱数,得到的直方图将越来越接近理想的正态分布钟形曲线:

均值为 0、标准差为 1 的正态分布

Notebook 还演示了一个经典反例:真实世界大部分数据服从正态分布,因此不应使用均匀随机数生成器生成样本数据——np.random.rand生成的均匀分布样本(如np.random.rand(1000)*2*std+mean-std)画出的直方图形态与真实体重分布明显不符。

置信区间:用样本估计总体均值

讨论棒球球员体重时,我们假定存在某个随机变量 W,对应全体棒球球员体重的理想概率分布(即总体/population);我们手上的体重序列是全体球员的一个子集,称为样本(sample)。一个有意思的问题是:能否知道 W 的分布参数——即总体的均值与方差?

最直接的回答是计算样本的均值和方差。但随机样本未必能准确代表完整总体,因此引入**置信区间(confidence interval)**的概念。

置信区间是依据样本对总体真实均值做出的估计,它以某个概率(即置信水平/level of confidence)成立。

假设从分布中抽取样本 X₁, ..., Xₙ。每次抽样得到的均值 μ 都不同,因此 μ 本身可视为随机变量。置信水平为 p 的置信区间是一对值 (Lₚ, Rₚ),满足P(Lₚ ≤ μ ≤ Rₚ) = p,即测得的均值落入该区间的概率等于 p。

置信区间如何计算超出了本入门课的范围,简言之:我们定义"样本均值相对于总体真实均值"的分布,称为学生分布(Student distribution)

有趣的事实:学生分布以数学家威廉·西利·戈塞特(William Sealy Gosset)命名,他以笔名"Student"发表论文。他在吉尼斯啤酒厂工作,据其中一种说法,他的雇主不希望公众知道他们在用统计检验判断原材料质量。

若要以置信度 p 估计总体均值 μ,需要取学生分布的(1-p)/2 分位数A——可以从统计表中查,或用统计软件(Python、R 等)内置函数计算。则 μ 的区间为 X ± A·D/√n,其中 X 是样本均值,D 是标准差。

:这里略过了与**自由度(degrees of freedom)**相关的重要概念,更深入的理解可参考完整统计学教材。

配套 Notebook 中封装了一个计算均值置信区间的函数,内部使用scipy.stats.sem计算标准误、用scipy.stats.t.ppf查学生分布分位数:

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体重均值
0.85201.73±0.94
0.90201.73±1.08
0.95201.73±1.28

注意到:置信概率越高,置信区间越宽。

假设检验:用 t 检验证明"一垒手比二垒手高"

棒球球员数据集中包含不同场上角色,汇总如下表(如何计算这张表见 配套 Notebook):

角色身高体重人数
Catcher72.723684204.32894776
Designated_Hitter74.222222220.88888918
First_Baseman74.000000213.10909155
Outfielder73.010309199.113402194
Relief_Pitcher74.374603203.517460315
Second_Baseman71.362069184.34482858
Shortstop71.903846182.92307752
Starting_Pitcher74.719457205.163636221
Third_Baseman73.044444200.95555645

可以看到一垒手的平均身高高于二垒手,于是我们可能忍不住得出结论:一垒手比二垒手高

这句话之所以叫假设(hypothesis),是因为我们并不知道它是否真的成立。

然而下这个结论并不总是显而易见的:每个均值都关联一个置信区间,二者差异可能只是统计误差,因此需要更正式的方法来检验假设。先分别计算一垒手与二垒手身高的置信区间:

置信水平一垒手二垒手
0.8573.62..74.3871.04..71.69
0.9073.56..74.4470.99..71.73
0.9573.47..74.5370.92..71.81

可以看到,任何置信水平下两个区间都不重叠,这证明了一垒手高于二垒手的假设。

更形式化地看,我们实际要解决的是两个概率分布是否相同(或至少参数相同)的问题。分布不同需要选用不同检验;若已知分布为正态,可以应用学生 t 检验(Student t-test)

在学生 t 检验中,我们计算所谓的t 值(t-value),它在考虑方差的前提下反映均值之间的差异。可以证明 t 值服从学生分布,这使我们能为给定置信水平 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-12

在本例中 p 值极低,意味着一垒手更高的证据非常强。(ttest_ind返回的两个值中:p 值可视为两个分布均值相同的概率;t 值是归一化均值差的中间量,需要与给定置信水平的阈值比较。)

除均值比较外,假设检验还能回答更多问题,例如:

  • 证明某个样本服从某种分布(本例中我们假设身高正态分布,但这需要正式统计检验);
  • 证明样本均值等于某个预设值;
  • 比较多组样本的均值(例如不同年龄段的幸福水平差异)。

大数定律与中心极限定理

正态分布如此重要的原因之一是中心极限定理(central limit theorem):假设我们有 N 个独立值 X₁, ..., Xₙ 的大样本,取自均值 μ、方差 σ² 的任意分布。那么当 N 足够大(即 N→∞)时,ΣᵢXᵢ 的均值将服从正态分布,均值 μ、方差 σ²/N。

中心极限定理的另一种解读是:无论分布如何,当你计算任意随机变量值之和的均值时,最终都会得到正态分布。

由中心极限定理还可推出:当 N→∞ 时,样本均值等于 μ 的概率趋近于 1,这就是大数定律(law of large numbers)

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()

协方差与相关性:寻找变量间的关系

数据科学的一项重要工作是在数据中寻找关系。当两个序列在相同时刻表现出相似行为——同时上升/下降,或一个上升而另一个下降——我们就说它们相关(correlate),即两个序列之间似乎存在某种联系。

相关性并不必然意味着两个序列之间存在因果关系:有时两个变量都取决于某个外部原因,有时两个序列相关纯属巧合。但强的数学相关性仍是两个变量存在某种关联的良好信号。

从数学上看,刻画两个随机变量关系的主要概念是协方差(covariance):Cov(X,Y) =E[(X-E(X))(Y-E(Y))]。我们计算两个变量相对于各自均值的偏差,再求这些偏差的乘积:若两个变量同步偏离,乘积恒为正,累加得到正协方差;若两者偏离不同步(一个低于均值时另一个高于均值),乘积恒为负,累加得到负协方差;若偏差相互独立,则大致累加为零。

协方差的绝对值并不能说明相关性强弱,因为它取决于实际数值的量级。为将其归一化,可以把协方差除以两个变量的标准差,得到相关性(correlation)。它的优点是始终落在 [-1, 1]:1 表示强正相关,-1 表示强负相关,0 表示完全无关(变量独立)。

示例:用上面的数据集计算棒球球员体重与身高之间的相关性:

print(np.corrcoef(weights, heights))

结果得到一个相关矩阵(correlation matrix)

array([[1. , 0.52959196], [0.52959196, 1. ]])

相关矩阵 C 可对任意数量的输入序列 S₁, ..., Sₙ 计算:Cᵢⱼ 是 Sᵢ 与 Sⱼ 的相关性,对角线元素恒为 1(即 Sᵢ 的自相关)。

本例中 0.53 表明人的体重与身高之间存在一定相关性。还可以绘制散点图直观查看:

Notebook 还通过一个"邪恶棒球公司"的玩具示例深化理解:该公司按身高发薪——底薪 1000 美元,再按身高加 0~100 美元。线性公式下np.corrcoef接近 1;把公式换成np.sin引入非线性后相关性略降但依然较高;再叠加 ±10 的随机噪声后相关性进一步下降。最后演示了真实的体重-身高相关性:由于序列中存在nan缺失值,直接计算会得到nan,必须先调用ffill()/fillna补齐数据——这直观说明了数据准备与清洗的重要性。关于数据清洗与准备的完整方法论,可进一步学习课程第 8 课(08-data-preparation)。

实战挑战:验证更多假设

利用 Notebook 中的示例代码,尝试检验以下假设:

  1. 一垒手比二垒手年龄更大;
  2. 一垒手比三垒手更高;
  3. 游击手比二垒手更高。

检验思路与课程完全一致:先按角色分组查看各列的均值,再分别计算两组的置信区间看是否重叠,最后用scipy.stats.ttest_ind计算 t 值与 p 值作出统计推断。

课程作业:小型糖尿病研究

本课作业(assignment.md,孟加拉语版见 translations/bn/1-Introduction/04-stats-and-probability/assignment.md)要求你独立完成一次完整的数据统计实践:使用 data/diabetes.tsv 中的糖尿病病人小数据集(取自 NCSU 公开数据集),并在 assignment.ipynb 中完成任务。数据列说明:

  • AGE:年龄;SEX:性别;
  • BMI:身体质量指数;BP:平均血压;
  • S1~S6:六项血液生化指标;
  • Y:一年内疾病进展的定量度量(目标变量)。

具体任务清单:

  • 计算所有变量的均值与方差;
  • 按性别分组,为 BMI、BP 和 Y 绘制箱线图;
  • 分析 AGE、SEX、BMI 和 Y 的分布形态;
  • 检验各变量与疾病进展 Y 之间的相关性(提示:相关矩阵能给出最有用的依赖关系信息);
  • 检验"糖尿病进展程度在男性和女性之间存在差异"这一假设。

Notebook 骨架已给出数据加载代码pd.read_csv("data/diabetes.tsv", sep='\t')与各任务标题占位,评分标准(Rubric)要求所有任务完成、绘图并给出结论性解释:全部完成且图文并茂为"优秀",仅完成均值/方差与基础绘图而未得出结论则评为"需改进"。

小结

本课为你建立了统计与概率的完整入门框架,内容包括:

  • 数据的基本统计量:均值、方差、众数与四分位数;
  • 随机变量的各类分布,尤其是正态分布;
  • 如何发现不同属性之间的相关性;
  • 如何用严谨的数学与统计工具证明假设;
  • 如何基于数据样本计算随机变量的置信区间。

虽然这远非概率与统计的全部主题,但足以支撑你在这门课程后续(数据可视化、数据生命周期、机器学习)中顺利前行。若想深入理论,可继续阅读 NYU Carlos Fernandez-Granda 的《Probability and Statistics for Data Science》讲义、Peter 与 Andrew Bruce 的《Practical Statistics for Data Scientists》、James D. Miller 的《Statistics for Data Science》等经典资料,本课还提供了课前/课后测验与配套 Notebook 用于自测。

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询