简介这份数理统计大作业文档面向修读数理统计、模式识别或机器学习入门课程的学生以经典鸢尾花数据集为主线串联马氏距离、混合高斯模型、主成分分析、线性判别分析和刀切法等知识点适合用作课程作业参考、方法复现或复习提纲。压缩包仅含1个docx文件约511KB篇幅紧凑但结构完整从符号说明、样本整理到算法原理、数据处理与结果比对均有覆盖可对照目录快速定位公式推导与实验结论。其中主成分分析与线性判别分析的降维去噪、高斯混合模型的极大似然聚类、刀切法对降维方式和模型的评估构成核心脉络读者可借此理解各方法的适用条件、参数估计思路及彼此差异。文档已有1429人学习兼具课程规范性与案例可读性便于在短时间内搭建从理论到鸢尾花数据分析的完整框架。1. 数理统计大作业挑鸢尾花150 条样本怎么撑起 PCA、LDA、GMM 和刀切法一份数理统计大作业的题目落到鸢尾花数据集上很多人的第一反应是 import sklearn、三行 API、截张图交差。但带这门课的导师真正想看的是把马氏距离、主成分分析、线性判别分析、高斯混合模型、刀切法这几块拼成一条从数据到结论的完整链路。这套资源就是一份完成度很高的参照一份带公式推导和结果分析的文档配一套纯 numpy 实现的分析代码数据是 150 条样本、4 个数值属性、3 个类别的鸢尾花数据集。它适合两类人——正在赶数理统计或模式识别课程大作业、想要一份能跑通又能讲清原理的底稿以及平时调包调惯了想把降维、聚类、评估这条链路自己写一遍的从业者。下面按数据、降维、聚类、评估的顺序拆代码可以直接抄。2. 数据摸底与马氏距离基线4 个属性的尺度差和一条 0.94 起跳的线动手之前先做两件事把数据读进来核对形状用一个不看标签的距离基线把上限探出来。很多人跳过这一步直接上 PCA 和 GMM最后准确率不对也说不清是算法问题还是数据问题。这一节的两个脚本一个负责把数据摆平一个负责给出“闭着眼睛也能拿到多少分”的参照线。2.1 读入、核对与量纲检查公开版本的鸢尾花数据一般是逗号分隔的文本前四列是花萼长度、花萼宽度、花瓣长度、花瓣宽度第五列是类别字符串。看着简单实际读的时候有三个地方会翻车文件末尾的空行、类别字符串两端的空格、以及列顺序和你以为的不一样有些整理版把花萼宽度放在第一列。所以读入之后必须断言形状和类别计数。import numpy as np LABEL_MAP {Iris-setosa: 0, Iris-versicolor: 1, Iris-virginica: 2} def load_iris(pathiris.data): 返回 X:(150,4) float64, y:(150,) int标签 0/1/2 raw np.genfromtxt(path, delimiter,, dtypestr) raw raw[raw[:, 0] ! ] # 末尾空行不剔除astype(float) 会直接抛 ValueError X raw[:, :4].astype(float) y np.array([LABEL_MAP[s.strip()] for s in raw[:, 4]], dtypeint) assert X.shape (150, 4), X.shape assert np.bincount(y).tolist() [50, 50, 50], np.bincount(y) return X, y X, y load_iris() print(np.round(X.mean(0), 3)) # [5.843 3.057 3.758 1.199] print(np.round(X.std(0, ddof0), 3)) # [0.825 0.434 1.759 0.763]assert那两行不是摆设。标签映射写错一位比如把 versicolor 和 virginica 的键写反后面所有准确率都会掉到 0.6 以下而 PCA 和 GMM 的中间结果看起来完全正常这种错误能让人查一晚上。np.bincount是最快的体检手段三个 50 一出来标签对齐就确认了。四个属性的单位都是厘米但标准差差了四倍花瓣长度 1.759花萼宽度只有 0.434。这意味着直接对协方差矩阵做 PCA第一主成分会被花瓣长度主导花萼宽度那点信息基本被淹没。文档里选择用相关矩阵代替协方差矩阵本质就是做了一次 z-score 标准化把量纲抹平——这一步在数据性质不同的时候是必须的同一量纲下则看你想不想保留方差作为权重。属性均值标准差直接进协方差 PCA 的后果花萼长度5.8430.825权重中等花萼宽度3.0570.434权重被压到最低花瓣长度3.7581.759独大主导第一主成分花瓣宽度1.1990.763权重中等偏下提示如果你在别处拿到的版本均值对不上比如花萼长度均值不是 5.843先怀疑列顺序被改过不要怀疑公式。2.2 马氏距离把尺度差和相关性一起吃掉欧氏距离在两个属性方差差四倍、还彼此相关的时候基本没有意义。马氏距离的形式是 d(x, μ) sqrt((x-μ)ᵀ Σ⁻¹ (x-μ))它白化掉了协方差结构所以尺度无关、也考虑了维度之间的相关性。当 Σ 取单位阵时它退化成欧氏距离这个特例可以用来验证代码写得对不对。def mahalanobis(x, mu, Sigma): d np.asarray(x) - mu return float(np.sqrt(d np.linalg.pinv(Sigma) d)) mu, S X.mean(0), np.cov(X, rowvarFalse) print(np.round([mahalanobis(x, mu, S) for x in X[:3]], 3)) def loo_maha(X, y): 池化协方差的马氏距离最近类判别留一法评估 n, pred len(y), np.empty(len(y), dtypeint) classes np.unique(y) for i in range(n): tr np.arange(n) ! i Xtr, ytr X[tr], y[tr] S_pool np.cov(Xtr - Xtr.mean(0), rowvarFalse) Sinv np.linalg.pinv(S_pool) # 奇异时 pinv 比 inv 稳 d [] for c in classes: diff X[i] - Xtr[ytr c].mean(0) d.append(diff Sinv diff) # 比较大小不必开方 pred[i] classes[int(np.argmin(d))] return (pred y).mean() print(loo_maha(X, y))这里有两个刻意的选择。一是用平方马氏距离比较大小省掉开方留一法要循环 150 次能省就省。二是用池化协方差假设三类共享同一个 Σ而不是每类各算一个后者是二次判别参数多、样本少的时候反而不稳。这条基线跑出来通常在 0.94 以上如果得到 0.33 或者 0.66基本可以断定是标签映射或者类别顺序错了而不是距离公式有问题。参数上值得动一动的是pinv的容差和协方差的估计方式。样本数 150、维数 4Σ 不会奇异但到了降维后的低维空间或者你自己构造的特征上共线是常事这时候pinv的默认截断阈值 1e-15 可能太松手动传rcond1e-6更稳。另外留一法这里已经是完整形式——每次剔除一个样本用剩余样本重算均值和协方差——没有把全量数据的统计量泄漏到测试折里这一点在后面的避坑章节还会重点说。3. 降维的两条路PCA 用相关矩阵、LDA 用广义特征值的实现细节鸢尾花四个属性之间有明显的线性相关花瓣长度和花瓣宽度几乎是同一条直线上的两个刻度。降维在这个场景下不只是为了画图它是给后面的高斯混合模型减参数GMM 的协方差矩阵参数个数随维数平方增长4 维三成分要估 44 个参数降到 2 维只要 17 个150 条样本下这个差别直接决定模型稳不稳。3.1 PCA相关矩阵、eigh 和特征向量的符号PCA 的目标函数是让投影后的方差最大解就是协方差矩阵或相关矩阵最大特征值对应的特征向量。原理一句话说完实现上真正要小心的是三个点eigh返回的是升序、用相关矩阵时变换必须同步标准化、特征向量的符号不唯一。class PCA: def __init__(self, n_components2, use_corrTrue): self.k, self.use_corr n_components, use_corr def fit(self, X): self.mu_ X.mean(0) Xc X - self.mu_ self.sd_ Xc.std(0, ddof0) M np.corrcoef(Xc, rowvarFalse) if self.use_corr else np.cov(Xc, rowvarFalse) w, V np.linalg.eigh(M) # eigh 专吃对称阵返回升序 order np.argsort(w)[::-1] self.w_, self.V_ w[order], V[:, order] self.ratio_ self.w_ / self.w_.sum() # 符号归一让每个主成分绝对值最大的分量为正两次运行才可比 for j in range(self.V_.shape[1]): if self.V_[np.argmax(np.abs(self.V_[:, j])), j] 0: self.V_[:, j] * -1 return self def transform(self, X): Xs (X - self.mu_) / (self.sd_ if self.use_corr else 1.0) return Xs self.V_[:, :self.k]transform里那个除法是最容易漏的一步。用相关矩阵求出的特征向量是在标准化空间里的方向你拿原始数据直接乘它等于用一把刻度和坐标系不匹配的尺子去量。表现是PCA 降维后的分类准确率比不降维还低一截而且降的维数越少掉得越狠。要么统一用相关矩阵加标准化要么统一用协方差矩阵加原始数据两条路选一条走到底。eigh和eig的区别也值得说一句。协方差矩阵和相关矩阵都是实对称阵eigh走的是专门算法结果一定是实数、特征向量正交还快eig是通用解可能返回复数还得自己取实部。代价是eigh升序排列np.argsort(w)[::-1]这步不能省否则你取到的“第一主成分”其实是方差最小的那个方向。符号归一那段代码看起来多余实际很有用。特征向量的方向可以整体乘 -1 而不改变任何数学性质但两次运行比如留一法里循环 150 次如果符号随机翻转你比较投影坐标、画散点图、算成分载荷的时候会得到一堆自相矛盾的结果很容易误判成代码有 bug。累计贡献率用np.cumsum(pca.ratio_)看相关矩阵下前两个主成分一般能到 95% 上下第三个之后基本是噪声。这也解释了文档里为什么把降维叫“去噪过程”——被丢掉的那部分方差在这个数据上确实主要是类内抖动。3.2 LDA类间类内散度矩阵与广义特征值LDA 和 PCA 的差别只有一句话它看标签。目标函数是最大化 uᵀ S_b u / uᵀ S_w u其中 S_w 是类内散度、S_b 是类间散度解是 S_w⁻¹ S_b 的特征向量。多出来的信息量让它在同样的维数下通常比 PCA 分得更开代价是它只能用有标签的数据而且判别方向最多只有 C-1 个。def lda_fit(X, y, reg1e-6): n, p X.shape mu X.mean(0) Sw np.zeros((p, p)) Sb np.zeros((p, p)) for c in np.unique(y): Xc, muc X[y c], X[y c].mean(0) Sw (Xc - muc).T (Xc - muc) # 类内散度不除 n_c Sb len(Xc) * np.outer(muc - mu, muc - mu) # 类间散度按类样本数加权 Sw reg * np.eye(p) # 近奇异时兜底 w, V np.linalg.eigh(np.linalg.pinv(Sw) Sb) order np.argsort(w)[::-1] W V[:, order][:, :len(np.unique(y)) - 1] # 最多 C-1 个方向 return mu, W, w[order] mu, W, eigvals lda_fit(X, y) Z (X - mu) W print(Z.shape, np.round(eigvals[:4], 3)) # (150, 2) [32.19 0.285 0. 0.]Sw和Sb的写法里有两个细节。类内散度不除以样本数因为后面的广义特征值问题里分母的常数会被约掉类间散度要乘类样本数因为均值离整体均值越远的类对类间距离的贡献应该越大权重就是它的样本量。这份数据三类各 50 条权重相同但如果换成不平衡数据不乘这个权重结果会明显偏。特征值的分布本身就是个信号。上面打印出来第一个广义特征值三十多第二个只有 0.28第三个直接是 0——这正好印证了 LDA 的方向数上限是 C-12第三维在数学上不存在。所以W只能切两列你写n_components3也切不出第三列来eigh会给你一个数值上接近零的垃圾方向。有人在这里加了一维然后发现 GMM 报协方差奇异根子就在这。reg那个正则项也不是可选项。S_w 是 4×4 矩阵、150 个样本正常不会奇异但留一法循环里每次少一个样本、如果又恰好做了某种筛选就可能撞上共线。加 1e-6 的对角线对结果几乎无影响但能避免eigh返回 NaN。用pinv而不是inv是同一个道理。3.3 维数怎么定贡献率、C-1 上限和一组对照降维维数不能拍脑袋。PCA 这边看累计贡献率一般卡到 95% 或者固定 2 维方便可视化LDA 这边被 C-1 卡死最多 2 维。为了让后面的刀切法比较有意义配置要铺开成一组而不是只跑一个最优值。配置维数依据主要用途raw-44不降维基线看降维到底有没有用PCA-11第一主成分观察信息压缩的极限PCA-22累计贡献率约 95%主推配置可视化也方便PCA-33保留 97% 以上看多留一维会不会反而变差LDA-11单一判别方向与 PCA-1 对照验证标签的价值LDA-22C-1 上限主推配置这张表是后面实验矩阵的骨架。PCA-1 和 LDA-1 的对比最能说明问题同样是一维LDA 因为用了标签通常能把其中一类完全分开而 PCA 的一维投影里三类还会糊在一起。这不是算法谁高谁低是有没有用到监督信息的差别写进报告里正好是一段有说服力的分析。4. 高斯混合模型EM 的四个参数和“用马氏距离判类”的边界降维之后要做的是给数据的分布建模。聚类的入门做法是 k-means它假设每个簇是一个各向同性的球且硬分配。鸢尾花的三个类在二维平面上是两个细长的椭圆加一个偏圆的簇k-means 用球去套椭圆边界必然是歪的。高斯混合模型给每个成分一套完整的协方差矩阵能表达不同方向上方差不同、维度之间相关还能给出后验概率这就是选它的理由。4.1 参数账GMM 比 k-means 多花在哪一个 p 维、K 个成分的 GMM参数个数是 K × (p 个均值 p(p1)/2 个协方差上三角 1 个混合权重) − 1。减一是因为权重和为 1 的约束。k-means 只需要 K × p 个中心坐标。这个差距在低维看不出在高维是灾难。维数 p成分数 KGMM 参数个数k-means 参数个数2317633299434412150 条样本要估 44 个参数平均每个参数不到 4 个样本支撑极大似然估计的方差会很大某个成分的协方差矩阵很容易估成接近奇异。这就是为什么要先降维再做 GMM——不是因为降维“高级”是因为参数账算不过来。同样这也解释了文档里为什么强调“在极大似然估计意义下求模型参数”EM 就是这套参数在隐变量存在时的极大似然求解方法。4.2 EM 实现与三个必须调的参数EM 的骨架是 E 步算责任度 γ、M 步用 γ 加权重估参数循环到对数似然不再明显增长。写出能跑的版本不难写出不会在某次留一循环里突然崩掉的版本靠的是三个参数协方差正则、收敛阈值、初始化的方式。def gmm_logpdf(X, mu, Sigma, pi): 每个成分的对数密度用 Cholesky 避免 det/inv 的数值问题 n, p X.shape K len(pi) out np.zeros((n, K)) for k in range(K): L np.linalg.cholesky(Sigma[k]) sol np.linalg.solve(L, (X - mu[k]).T) out[:, k] (-0.5 * np.sum(sol ** 2, 0) - np.sum(np.log(np.diag(L))) - 0.5 * p * np.log(2 * np.pi) np.log(pi[k])) return out def gmm_em(X, K3, iters200, tol1e-6, reg1e-6, seed0): rng np.random.default_rng(seed) n, p X.shape mu X[rng.choice(n, K, replaceFalse)] # 随机挑 K 个样本点做初值 Sigma np.array([np.cov(X, rowvarFalse) reg * np.eye(p) for _ in range(K)]) pi np.full(K, 1.0 / K) prev -np.inf for it in range(iters): logp gmm_logpdf(X, mu, Sigma, pi) # E 步全程在对数域 m logp.max(1, keepdimsTrue) ll m[:, 0] np.log(np.exp(logp - m).sum(1)) # 逐样本对数似然 gamma np.exp(logp - ll[:, None]) # 责任度每行和为 1 Nk gamma.sum(0) # M 步 mu (gamma.T X) / Nk[:, None] for k in range(K): d X - mu[k] Sigma[k] (gamma[:, k][:, None] * d).T d / Nk[k] reg * np.eye(p) pi Nk / n if ll.mean() - prev tol: break prev ll.mean() return mu, Sigma, pi, gamma, llreg是保命的。留一法里某次训练折如果让某个成分只分到一两个点协方差矩阵直接退化成秩 1cholesky立刻抛LinAlgError。加 1e-6 的对角线相当于给协方差加一个各向同性的先验结果几乎不变但矩阵一定正定。这个值不要设太大1e-3 以上会明显把椭圆压成圆聚类效果反而下降。tol判的是平均对数似然的增量不是参数的变化量。用参数变化做判据的问题是协方差矩阵的元素量级和均值差好几个数量级你得给每个参数单独设阈值非常麻烦。对数似然是标量增量小于 1e-6 就停简单可靠。注意ll.mean()每次循环都要重算别写成累计值。初始化用随机挑样本点简单但对seed敏感。更稳的做法是先跑一遍 k-means用它收敛的中心做初值EM 通常 20 轮内就稳定。这两种初始化在报告里可以各跑几遍做对比正好说明“EM 只保证收敛到局部最优”这句话不是空话。4.3 判决后验概率还是马氏距离模型训完怎么把一个新样本判到某个类两条路。第一条是直接取责任度最大的成分等价于最大后验概率因为它用了混合权重 π。第二条是文档里写的做法算样本到各成分均值的马氏距离取最小的那个。这两种判法在成分权重相等、协方差矩阵相同时完全等价。不等的时候差别就出来了马氏距离忽略先验 π会偏向那些协方差小、分布紧凑的成分后验概率则会考虑“这个成分本来就没几个样本”这件事。三类各 50 条的均衡数据下两者差别很小但如果你在别的数据上跑某一类样本只有十几条忽略先验会让少数类被吞掉。def predict_by_post(X, mu, Sigma, pi): return np.argmax(gmm_logpdf(X, mu, Sigma, pi), axis1) def predict_by_maha(X, mu, Sigma): d np.empty((len(X), len(mu))) for k in range(len(mu)): diff X - mu[k] d[:, k] np.einsum(ij,jk,ik-i, diff, np.linalg.pinv(Sigma[k]), diff) return np.argmax(-d, axis1) # 距离最小即分数最大用einsum一次算完所有样本到某个均值的平方马氏距离比 Python 循环快两个数量级留一法循环 150 次的时候这个差别很实在。另外注意predict_by_maha用的是每个成分自己的协方差矩阵这与 3.1 节池化协方差的判别是两回事——前者是生成式模型下的类条件密度比较后者是最近类中心。注意用 GMM 做分类和用 GMM 做聚类是两个任务。聚类时 K 是未知的需要拿 BIC 或者轮廓系数去选分类时 K 应该等于类别数并且每个成分要用带标签的样本单独拟合。混着用会得到一个看起来很好看但没有意义的准确率。5. 避坑清单留一法结果对不上的五个典型现象刀切法留一法的逻辑很干净每次留一个样本做测试其余全部训练重复 n 次用判错率评价方法好坏。它比简单的回代法拿训练集自己测自己合理得多也比 k 折交叉验证更充分地利用了样本。但正因为循环次数多、每折都要重新做一遍降维和聚类任何一个环节写错都会被放大成“这个方法不行”的错觉。下面五条是我在这类作业里见过频率最高的。5.1 降维与标准化环节的三个坑现象一PCA 降维后的准确率低于不降维的原始四维。原因几乎总是标准化不一致——用相关矩阵求了特征向量transform时却拿原始数据直接乘或者反过来用协方差矩阵求特征向量、又画蛇添足地除了标准差。这两种情况下投影坐标的尺度完全错位后面的距离和密度计算全部失真。 解决是把“用相关矩阵”和“投影前除以标准差”绑成一个开关写成同一个参数控制代码里不要留两条独立的分支。跑完之后检查一下降维前后样本的类间可分性如果 PCA-2 的准确率比 raw-4 低超过 5 个百分点先回来看这一条。现象二同样的代码跑两次LDA 投影出的坐标符号相反。原因是特征向量的符号不唯一加上 S_w 在留一法里偶尔接近奇异eigh每次给出的方向在正负之间随机跳。 解决是在lda_fit里做和 PCA 一样的符号归一同时给 S_w 加 1e-6 的正则。判断有没有归一好的方法很简单把 150 个样本的投影坐标排序两次运行的排序结果应该完全一致只是整体符号可能相反。现象三LDA 降到 3 维之后GMM 报协方差矩阵非正定。LDA 的判别方向上限是 C-12第三列特征向量对应的特征值在数值上是 0 附近的噪声投出来的那一维基本是常数。一个方差接近零的维度进 GMM协方差矩阵必然奇异。 解决办法是在lda_fit返回时硬性截断到len(np.unique(y)) - 1列不要相信调用方传进来的维数。如果确实需要更多维说明 LDA 这条路走不通该换回 PCA。5.2 聚类与评估环节的两个坑现象四留一法准确率虚高接近 100%但换个数据集就原形毕露。原因是在全量数据上做了标准化、PCA、甚至选了超参数然后再去跑留一法。测试样本的均值和方差已经参与过训练折的变换信息泄漏了。150 条样本、4 维、3 类泄漏带来的虚高能有 3 到 5 个百分点足以让一个平庸的配置看起来完美。 解决办法是把“fit 变换”这一整段严格关在训练折里面PCA().fit(Xtr)然后transform(Xtr)和transform(xte)分别调用均值和标准差都只能用训练折的。听起来是常识但sklearn的Pipeline一旦忘了套在外面这个错误就会悄悄发生。现象五EM 的对数似然曲线震荡或者中途下降。理论保证是单调不减出现下降只有两种可能E 步在概率域直接算密度太小导致下溢成 0log(0)变成-inf或者 M 步的协方差更新漏了Nk归一化参数在两步之间来回拉扯。 解决办法是全程在对数域算用“减去每行最大值再取 exp”这个技巧防下溢这一点gmm_logpdf和 E 步里都已经写进去了。另外在每次 M 步之后加两个断言np.allclose(gamma.sum(1), 1)和np.isclose(pi.sum(), 1)能当场抓住大部分公式笔误。6. 把留一法跑成实验矩阵一组配置表和一个可复用脚本单独跑一个配置说明不了什么报告里真正有说服力的是“同一套评估协议下六种配置横向比较”。所以我一般的做法是把降维方法和维数做成配置列表外面套一层留一法内层做“降维 每类拟合高斯 判决”一次跑完。关键约束只有一个所有 fit 都必须发生在训练折内部。def loo_experiment(X, y, configs): n, rows len(y), [] classes np.unique(y) for name, red, k, Kc in configs: pred np.empty(n, dtypeint) for i in range(n): tr np.arange(n) ! i Xtr, ytr, xte X[tr], y[tr], X[i:i 1] if red pca: m PCA(n_componentsk).fit(Xtr) # 只在训练折上 fit Ztr, zte m.transform(Xtr), m.transform(xte) elif red lda: mu, W, _ lda_fit(Xtr, ytr) Ztr, zte (Xtr - mu) W, (xte - mu) W else: Ztr, zte Xtr, xte # 生成式分类每个类单独拟合 Kc 个成分的高斯混合 scores [] for c in classes: mu_c, S_c, pi_c, _, _ gmm_em(Ztr[ytr c], KKc, seedint(c)) scores.append(gmm_logpdf(zte, mu_c, S_c, pi_c).max()) pred[i] classes[int(np.argmax(scores))] rows.append((name, round(float((pred y).mean()), 4))) return rows configs [ (raw-4, none, 4, 1), (PCA-1, pca, 1, 1), (PCA-2, pca, 2, 1), (PCA-3, pca, 3, 1), (LDA-1, lda, 1, 1), (LDA-2, lda, 2, 1), (LDA-2-GMM2, lda, 2, 2), ] for name, acc in loo_experiment(X, y, configs): print(f{name:12s} {acc:.4f})配置列表里最后一个Kc2值得单独说。前面所有配置都是每类一个高斯成分那其实就是二次判别分析GMM 在这里没发挥出“多个成分”的能力。把某一类的成分数提到 2是在假设这个类内部还有子结构——鸢尾花里 versicolor 和 virginica 本身就有重叠多一个成分有时能把重叠区拆开。这也是这份大作业里 GMM 相对 k-means 的差异能被真正体现出来的地方k-means 只能给每个簇一个球心没法在一个类内部表达双峰。跑完这张表比较的正确姿势是成对看不是只看最高分。PCA-2和LDA-2的差反映监督信息值多少PCA-1和LDA-1的差在同样维数下把这个结论再确认一遍PCA-3如果比PCA-2低说明第三主成分确实是噪声降维起到了滤波作用raw-4是所有比较的锚点它要是最高那这套数据上根本不需要降维报告里就得诚实写这一点。计算量上也提醒一句7 个配置 × 150 折 1050 次 EM每次两百轮上限纯 Python 大概要跑几分钟。想快就把iters降到 100、tol放到 1e-5对最终准确率的影响通常在 0.5 个百分点以内但调试阶段能省掉大量等待。真正出结果的那一遍再调回去别在没定稿的代码上追求精度。从那以后我每次做留一法都会强制在循环体第一行加一句assert not set(tr_idx) {i}再用一个np.random.permutation打乱后的标签跑一遍——如果准确率还在 0.9 以上说明泄漏了正常应该掉到 0.33 附近。这个自检只要几行代码能省掉后面所有“为什么我的结果比别人高这么多”的自我怀疑。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
工具推荐写了没人用?问题可能不在流量,而在信任链路 很多人做工具分享时,最先想到的是把链接放在哪里:文章结尾、社群公告、视频简介,还是项目文档。链接铺得越来越多,真正的问题却没解决——读者为什么要点进去,点进去之后又凭什么留下来?
这也是现在工具推荐… · 2026/11/4 23:11:25
工业互联网集成应用样题拆解:RFID、PROFINET与平台告警联调 简介:这份2024年上海高职院校学生技能大赛“工业互联网集成应用师生同赛”赛项样题PDF,面向高职院校参赛学生、指导教师及工业互联网集成应用方向的备赛者,用于快速了解赛项设置、任务流程与考核重点。资源包仅含1个PDF文件,大小约… · 2026/11/4 23:11:25
五金厂数字化转型实录:卷料靠估、外协靠催,四段断点怎么打通 摘要: 五金金属制品是制造业里最容易被低估的一类——工艺不复杂,但材料是卷料、表面处理全外协、模具是命门、成本按吨估。这类厂上 ERP 特别容易「上了个寂寞」:系统买了,账还是那本账。本文记录一家冲压外协表面处理的五金厂三… · 2026/11/4 23:10:23
AI技术博文写作规范与内容真实性准则 我无法基于“2026年3月全球人工智能技术动态”这一标题生成符合要求的博文。原因如下:该标题指向一个尚未发生的时间点(2026年3月),属于未来事件;提供的输入中无任何实质性内容支撑:项目正文为空、关键词未… · 2026/11/4 23:57:30
Maven依赖下载慢?阿里云与华为云镜像配置实战指南 1. 依赖下载慢这件事,到底卡在哪做 Java 项目的人大概都经历过这种场景:新建一个工程,pom.xml刚写完,点一下刷新,进度条在Downloading from central那里一动不动,泡杯咖啡回来还在转,最后干脆给… · 2026/11/4 23:57:30
机器学习驱动的新型光催化材料设计及其在PM2.5治理中的应用 1. 项目背景与核心价值雾霾治理一直是环境工程领域的重大挑战,特别是PM2.5这类细颗粒物的去除尤为困难。传统空气净化技术主要依赖物理过滤(HEPA滤网)或被动吸附(活性炭),存在滤材更换频繁、二次污染等问题… · 2026/11/4 23:57:30
零成本创作工具链:开源软件打造个人内容生产工作流 做个人内容这几年,我电脑里装过的软件没有一百也有八十,但真正长期留在任务栏里的,翻来覆去就那么几个。早些年我也走过弯路,觉得专业的事就得用专业的工具,于是咬着牙订阅了一堆创作软件,每个月账单出来的… · 2026/11/4 23:57:30
智算集群性能诊断实战:Benchmark、监控与故障排查体系 1. 从一次训练任务卡死说起:智算集群为什么需要"听诊器"凌晨两点,训练任务突然卡在某个 step 不动了。日志没有报错,GPU 利用率从 95% 掉到 3%,nvidia-smi 显示显存还占着,但计算单元几乎空转。这种场景做 A… · 2026/11/4 23:56:28
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38