news 2026/10/31 7:12:26

鸢尾花数据集实战:马氏距离、GMM、PCA、LDA与刀切法全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸢尾花数据集实战:马氏距离、GMM、PCA、LDA与刀切法全解析

简介:这份数理统计大作业文档面向高校统计学、机器学习课程的学习者,围绕经典鸢尾花数据集展开完整分析,帮助读者理解多重变量数据的建模流程。内容涵盖马氏距离度量样本相似度、混合高斯模型聚类、主成分分析降维去噪、线性判别分析兼顾类间与类内离差,以及刀切法评估降维方法与模型泛化能力,并附有数据预处理、符号说明与算法比对等章节,可作为课程作业参考或统计方法复习材料。资源包共1个docx文件,约511KB,结构完整、条理清晰,便于按章节查阅。目前已有1429人学习下载,适合需要对照案例理解降维、聚类与模型选择思路的读者参考借鉴。

1. 四维鸢尾花为什么能撑起一整套数理统计方法论

150 个样本、4 个数值属性、3 个类别,鸢尾花数据集小到用一张纸就能抄完,却从 1936 年一直活到今天,成了数理统计和机器学习里被反复拿来做基准的经典数据。很多人第一次见它,直觉是“这么干净的数据,随便分分就对了”,但真正动手把主成分分析、线性判别分析、高斯混合模型和刀切法串成一条流水线,才会发现每一步都在做取舍:降维降多少维、用不用标签、距离怎么度量、泛化能力怎么估。这份数理统计大作业的价值不在于跑出一个多高的准确率,而在于它把“降维—建模—评估”这条链路的底层机制完整摊开了一遍。搞懂这条链路,你再看任何高维数值型数据的预处理和聚类,心里都会有一张清晰的图。

2. 马氏距离:为什么欧氏距离在相关变量上会翻车

2.1 从“尺度无关”这个性质说起

欧氏距离的问题在于它把每个维度当成同等重要、彼此独立的坐标轴。鸢尾花的四个属性里,花萼长度和花瓣长度明显正相关,花瓣长度和花瓣宽度也高度耦合,这时候直接算欧氏距离,等于把重叠的信息重复计了好几次,距离就被相关结构带偏了。马氏距离的定义是 $d(x,\mu)=\sqrt{(x-\mu)^T\Sigma^{-1}(x-\mu)}$,核心就在那个协方差矩阵的逆 $\Sigma^{-1}$。它做了两件事:一是用 $\Sigma$ 把各维度的方差归一化,消除量纲影响;二是用 $\Sigma^{-1}$ 把相关方向“拉直”,让距离沿着数据实际分布的形状去度量。

这份作业里明确列了马氏距离的三条性质:当 $\Sigma=I$ 时退化为欧氏距离;本质上是标准化后的欧氏距离;不受量纲变化影响。这三条不是背下来的结论,而是理解后续所有步骤的钥匙。因为高斯混合模型里每个成分的密度函数,指数部分恰好就是马氏距离的平方,也就是说,用马氏距离判断样本属于哪个高斯均值,和用高斯密度做最大似然判别,在数学上是同一件事的两种写法。

2.2 协方差矩阵求逆的隐患

马氏距离好看,但 $\Sigma^{-1}$ 是有代价的。四维数据还好,一旦维度接近甚至超过样本量,协方差矩阵会接近奇异,求逆数值上极不稳定。常见的实现思路是在 $\Sigma$ 的对角线上加一个很小的正则项,或者先做降维再算距离——这恰好解释了为什么整条流水线要先 PCA/LDA 降维再进 GMM。降维不只是为了算得快,也是在给协方差估计“减负”,让 $\Sigma^{-1}$ 有意义。作业里把降维称为“去噪的过程”,从数值稳定性角度看,这个说法是站得住的。

import numpy as np def mahalanobis(x, mu, cov, reg=1e-6): # reg 是正则项,防止协方差矩阵奇异导致求逆失败 cov_reg = cov + reg * np.eye(cov.shape[0]) diff = x - mu # 马氏距离平方 = 偏差向量左乘协方差逆再右乘偏差向量 return np.sqrt(diff.T @ np.linalg.inv(cov_reg) @ diff)

这段代码里reg参数就是血泪经验:不加它,遇到某类样本在某个维度上方差接近零时,np.linalg.inv会直接抛奇异矩阵错误。mu是该类的均值向量,cov是该类的协方差矩阵,两者都必须来自训练样本的估计,而不是全体数据——用全体数据的协方差去算单类距离,等于把类间差异也混进了度量里,判别会失真。

3. 高斯混合模型:极大似然为什么不能直接解

3.1 混合分布的对数似然困境

单个高斯成分的参数估计有闭式解:均值就是样本均值,协方差就是样本协方差。但高斯混合模型是 $p(x)=\sum_{k=1}^{K}\pi_k \mathcal{N}(x|\mu_k,\Sigma_k)$,对数似然 $\ln L=\sum_{i}\ln\sum_{k}\pi_k\mathcal{N}(x_i|\mu_k,\Sigma_k)$ 里,对数套着求和,求导之后参数之间互相耦合,没有解析解。这是 GMM 最本质的难点,也是它必须用迭代法求解的原因。作业里写“在极大似然估计意义下求模型参数”,落到实现上就是 EM 算法:E 步算每个样本属于每个成分的后验概率(责任度),M 步用这些概率加权更新 $\pi_k$、$\mu_k$、$\Sigma_k$,反复直到似然收敛。

这里有个容易被忽略的设计动机:GMM 相比 k-均值,多出来的正是协方差矩阵 $\Sigma_k$。k-均值隐含假设每个簇是各向同性的球,GMM 允许每个簇有自己的形状和朝向,所以作业里说它“考虑了不同方向上方差的不同,而且考虑了不同维度之间的相关性”。鸢尾花里 Versicolour 和 Virginica 两类在花瓣维度上是有重叠的,球形簇假设会把边界切得很生硬,椭圆簇就能贴合得更好。

3.2 责任度与参数更新的代码骨架

def e_step(X, pis, mus, covs): # 计算每个样本对每个高斯成分的责任度(后验概率) n, k = X.shape[0], len(pis) resp = np.zeros((n, k)) for j in range(k): diff = X - mus[j] inv = np.linalg.inv(covs[j]) # 高斯密度:指数部分是马氏距离平方的负一半 maha = np.einsum('ni,ij,nj->n', diff, inv, diff) resp[:, j] = pis[j] * np.exp(-0.5 * maha) / np.sqrt(np.linalg.det(covs[j])) return resp / resp.sum(axis=1, keepdims=True) # 按行归一化成概率 def m_step(X, resp): # 用责任度加权,更新混合系数、均值、协方差 nk = resp.sum(axis=0) pis = nk / X.shape[0] mus = (resp.T @ X) / nk[:, None] covs = [] for j in range(resp.shape[1]): diff = X - mus[j] covs.append((resp[:, j, None] * diff).T @ diff / nk[j]) return pis, mus, covs

e_step里resp按行归一化是关键,否则各成分密度量级不同,责任度不构成概率分布,M 步的加权就失去意义。m_step中nk是每个成分的“有效样本数”,协方差更新用的是责任度加权的二阶矩,这正是极大似然在隐变量模型下的标准形式。实际跑的时候还要注意初始化:均值随机选样本点、协方差初始化为全体协方差,否则 EM 容易收敛到退化解——某个成分只抓住一个点,协方差趋近零,似然反而“变大”,这是 GMM 最经典的翻车点。

4. 主成分分析与线性判别分析:一个不看标签,一个看标签

4.1 PCA 的方差最大化等价于特征分解

PCA 的目标是找线性变换 $u$,让投影后的方差最大。作业里写得很直接:信息量与方差成正比,所以目标就是最大化投影方差。数学上可以证明,协方差矩阵最大特征值对应的单位特征向量就是第一主成分方向,第二大特征值对应第二主成分,依此类推。实现上就是“标准化—求相关矩阵—特征分解—按特征值排序取前 k 个”。作业特别提到用相关矩阵代替协方差矩阵来消除量纲影响,这一步在鸢尾花上其实影响不大(四个属性都是厘米),但对量纲混杂的数据是必须的。

PCA 的局限也在这里:它完全无视标签,只按方差大小挑方向。如果某个方差很大的方向恰好是类间差异很小的方向,PCA 会把它当宝贝留下来,反而把真正有判别力的方向丢掉。这就是为什么作业里说 LDA“在有标签的情况下能够得到比 PCA 好很多的效果”。

4.2 LDA 的类间散度与类内散度之比

LDA 的目标函数是最大化类间散度与类内散度之比。投影后,希望同类样本挤在一起(类内散度 $S_w$ 小),异类样本离得远(类间散度 $S_b$ 大),于是优化目标写成 $\max_u \frac{u^T S_b u}{u^T S_w u}$。这个比值问题的解是 $S_w^{-1}S_b$ 的特征向量,取最大特征值对应的方向。作业里给出的目标函数和解的形式,本质上是广义瑞利商,和 PCA 的特征分解是同一套线性代数工具,区别只在于矩阵换成了 $S_w^{-1}S_b$。

def lda_fit(X, y): classes = np.unique(y) mu_all = X.mean(axis=0) Sw = np.zeros((X.shape[1], X.shape[1])) Sb = np.zeros_like(Sw) for c in classes: Xc = X[y == c] mu_c = Xc.mean(axis=0) diff = Xc - mu_c Sw += diff.T @ diff # 类内散度累加 n_c = Xc.shape[0] mean_diff = (mu_c - mu_all).reshape(-1, 1) Sb += n_c * (mean_diff @ mean_diff.T) # 类间散度按类样本数加权 # 求解广义特征值问题 Sw^{-1} Sb eigvals, eigvecs = np.linalg.eig(np.linalg.inv(Sw) @ Sb) idx = np.argsort(eigvals)[::-1] return eigvecs[:, idx]

Sb按类样本数n_c加权这一步不能省,否则样本多的类在类间散度里被低估。Sw是所有类内散度之和,反映“同类有多散”。注意 LDA 降维后的维度上限是“类别数减一”,三分类最多降到二维,这是它和 PCA 在维度选择上的硬约束,也是作业里比对两种降维方法时绕不开的前提。

5. 刀切法:留一法为什么比简单划分更可信

5.1 每次只留一个样本的评估逻辑

刀切法(留一法)的流程作业里写得很清楚:从某类 n 个样本里剔除一个,用剩下 n-1 个建判别规则,再判被剔除的那个,循环到每个样本都被判过一次,统计判错个数,最后算判错率。它的好处是每个样本都当过一次测试集,评估结果几乎不依赖某一次随机划分的运气。相比把数据一刀切成训练/测试两部分,留一法在小样本上尤其稳——150 个样本,任何一次 7:3 划分都可能让某一类在测试集里只剩几个样本,判错率波动极大,玄学感很重。

代价是运算量:每个样本都要重新训练一次模型。对鸢尾花这种规模无所谓,但对大模型就是灾难。所以作业里也承认“运算量相对很大,但是在计算机辅助下还是比较容易实现的”。这句话背后的取舍是:小样本、低维、模型简单时,留一法的评估偏差最小,值得多花算力;样本量大时就得退回 k 折交叉验证。

5.2 降维程度怎么影响判错率

作业最后用刀切法比对不同降维程度和两种降维方法的差异,这个设计很关键。PCA 降到一维、二维、三维,LDA 降到一维、二维,分别接 GMM 或马氏距离判别,看判错率怎么变。常见的现象是:维度太低,类间信息被压掉,判错率上升;维度太高,噪声和冗余又回来了,判错率同样不降反升,中间存在一个拐点。这个拐点不是拍脑袋定的,而是刀切法一次一次留一跑出来的。换句话说,刀切法在这里承担的不只是“评估模型”,更是“选降维超参数”的角色,这也是它比单次划分更值得信任的地方。

提示:留一法在类别不平衡时,判错率会被多数类主导,最好同时看每一类的判错个数,而不是只看总判错率。

6. 避坑与排查:这条流水线上最容易踩的五个坑

6.1 现象:GMM 似然越迭代越大,但聚类结果全乱

原因:某个高斯成分的协方差在迭代中趋近奇异,密度函数在单点上趋于无穷,似然被“虚假”抬高。解决:给协方差加正则项(对角线加小量),或限制协方差矩阵的最小特征值,同时检查初始化是否让两个成分均值重合。

6.2 现象:PCA 降维后分类效果反而比不降维差

原因:PCA 按方差挑方向,可能把判别力强但方差小的方向丢掉,尤其在类别边界附近。解决:有标签时优先用 LDA,或把 PCA 和 LDA 串联(先 PCA 去噪再 LDA 判别),并借助刀切法验证降维维度。

6.3 现象:马氏距离算出来是 NaN 或异常大

原因:协方差矩阵接近奇异,求逆后数值爆炸。解决:加正则项、先降维、或改用伪逆np.linalg.pinv,同时确认传入的协方差是用对应类别的样本估的,而不是全体数据。

6.4 现象:留一法判错率每次跑都不一样

原因:如果流程里混入了随机初始化(比如 GMM 的初始均值),留一法本身不随机,但模型训练随机,结果就会抖。解决:固定随机种子,或对每个留一折做多次初始化取最优似然,再统计判错。

6.5 现象:LDA 降维后维度对不上,报矩阵维度错误

原因:LDA 最多降到“类别数减一”维,三分类硬要降到三维就会拿到零特征值方向。解决:把目标维度限制在min(n_classes-1, n_features)以内,取特征值时过滤掉接近零的项。

7. 设计取舍:为什么这条流水线的顺序不能随便换

把这份作业的流程拆开看,顺序是“降维 → 建模 → 评估”,但每一步的选择都牵动后面。先降维再 GMM,是因为高维下协方差估计不可靠,马氏距离和 GMM 的密度计算都会失稳;用 LDA 而不是 PCA 做降维,是因为有标签时类间信息比方差更值钱;用刀切法而不是单次划分做评估,是因为样本量小,任何一次划分的偶然性都太大。这三个取舍指向同一个原则:在小样本、有标签、数值型的场景下,优先保住“估计的稳定性”和“信息的判别力”,而不是追求计算速度或实现简单。

我一般会这么理解这套方法论的边界:如果样本量涨到几万,留一法的算力开销就不划算了,得换 k 折;如果维度涨到几百,PCA 的特征分解也要考虑用随机化 SVD;如果类别严重不平衡,GMM 的成分数就不能简单设成类别数。这些延伸都不在这份作业的范围内,但顺着它的机制往下推,方向是清楚的。

从那以后我每次做降维加聚类的流水线,都会强制先跑一遍留一法把降维维度扫一遍,再定模型参数——这个习惯帮我躲过了好几次“看起来准确率很高、换一批数据就崩”的坑。这份大作业把马氏距离、GMM、PCA、LDA、刀切法串成一条可复现的链路,源码和推导都在文档里,想深挖每一步的实现细节,直接拿这份资源对着跑一遍,比看十篇零散教程都管用。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 7:11:49

Spark本地与HDFS文件路径规范及常见URISyntaxException解决方案

简介:本资源是《大数据技术原理与应用》课程配套的Spark初级编程实践实验报告,面向高校大数据初学者及Hadoop/Spark入门学习者,聚焦分布式计算框架的核心操作与排错能力培养。压缩包为1个1.9MB的DOCX文档,完整涵盖实验环境配置&am…

作者头像 李华
网站建设 2026/10/31 7:11:21

CATIA汽车线束三维布线实战:从Geometric Bundle到Floating Junction

简介:这份PPT面向CATIA V5初学者与汽车电气设计入门者,围绕电气线束安装工作台讲解如何在数字样机中构建线束并连接电气组件,帮助读者理解线束组、线束段等核心概念与基本操作流程。内容涵盖线束安装界面与术语、几何线束与线束段定义、线束分…

作者头像 李华
网站建设 2026/10/31 7:10:41

SAP CDS视图Eclipse ADT安装创建与激活实战

简介:一份面向SAP HANA数据建模初学者与ABAP开发人员的CDS视图入门文档,聚焦在Eclipse环境中完成SAP CDS视图创建所需的环境准备与插件配置。内容围绕客户端与Eclipse版本核查、SAP ABAP Development Tools插件安装、SAP项目关联,以及在指定包…

作者头像 李华
网站建设 2026/10/31 7:10:10

CATIA汽车线束三维布线核心知识与易错点梳理

简介:这份PPT面向CATIA V5初学者与汽车电气设计入门者,聚焦电气线束安装工作台的实际操作,帮助读者在数字样机中完成线束建模与装配。内容覆盖线束安装环境介绍、几何线束与线束段定义、线束分段、电气对象联结与局部松弛度调整、支撑路由与取…

作者头像 李华
网站建设 2026/10/31 7:10:10

SAP现金销售订单BV流程:单据流与科目确定配置

简介:SAP现金销售订单从建单到清账的完整操作与配置手册,面向SD顾问、财务与仓库录单人员,帮助解决现金销售流程中订单类型选错、发货与开票脱节、清账环节繁琐等实务问题。内容按目的、适用范围、业务操作、配置实现逐层展开:业务…

作者头像 李华
网站建设 2026/10/31 7:09:59

Kettle PDI 9.2 核心原理与工程实践:从执行断层到生产级同步

简介:本资源是一份面向1–3年经验研发人员的Kettle(Pentaho Data Integration)入门级教学PPT,聚焦ETL核心流程与工具实操,帮助开发者快速掌握数据同步、转换与加载的基础能力。内容覆盖ETL概念解析、Kettle 9.2安装部署…

作者头像 李华