资讯详情

资讯详情

建站行业动态 · 设计趋势 · 数字化升级干货

从判别到生成:基于概率生成模型的二分类原理与实现

从判别到生成:基于概率生成模型的二分类原理与实现 1. 项目概述从“分类”到“生成”的思维跃迁在机器学习的分类任务里我们最熟悉的路径可能是这样的拿到一堆数据直接训练一个模型比如逻辑回归、支持向量机或神经网络让它学会在特征空间里画一条“决策边界”把不同类别的样本分开。这种直接对后验概率 P(Y|X) 进行建模的方法被称为判别模型。它高效、直接在绝大多数二分类问题上表现优异是我们工具箱里的“瑞士军刀”。但今天我想带你换一个视角聊聊另一条路径概率生成模型。这个项目的核心就是探讨如何用生成模型的思路来解决二分类问题。初听可能有点绕生成模型不是用来生成新数据的吗比如生成一张逼真的人脸怎么还能用来做分类这正是其精妙之处。简单来说概率生成模型并不直接去拟合 P(Y|X)而是先去分别建模每一类数据本身的分布 P(X|Y)再利用贝叶斯定理“反推”出我们最终需要的 P(Y|X)。举个例子我们要区分一封邮件是“正常邮件”还是“垃圾邮件”。判别模型会直接学习“邮件内容”和“垃圾邮件”标签之间的关系。而生成模型则会分别学习“正常邮件的内容通常长什么样”P(内容|正常)和“垃圾邮件的内容通常长什么样”P(内容|垃圾)。当一封新邮件到来时我们就像法医鉴定一样分别计算它“像”正常邮件的程度和“像”垃圾邮件的程度再结合先验知识比如收件箱里垃圾邮件的普遍比例最终判断它更可能属于哪一类。这种方法听起来计算量更大但它带来了几个独特的优势首先它提供了对数据本身更深刻的理解我们不仅知道怎么分还知道了每一类数据“应该”长什么样。其次在数据不均衡时通过调整先验概率可以更优雅地处理。再者生成模型天然具备处理缺失数据、进行半监督学习的能力。对于刚入门的朋友理解生成式分类是打通机器学习“任督二脉”的关键一步它能让你从更本质的概率视角看待问题对于有经验的朋友重温这套理论或许能在面对某些复杂、数据稀缺或需要可解释性的分类场景时提供新的解题思路。2. 核心原理贝叶斯框架下的分类决策要理解基于概率生成模型的二分类我们必须回到概率论的基石——贝叶斯定理。整个方法的逻辑链条都构建于此之上。2.1 贝叶斯定理从因到果的桥梁贝叶斯定理的公式我们都熟悉P(A|B) P(B|A) * P(A) / P(B)。在分类的语境下我们将其具体化A代表类别 Y例如 Y0 或 Y1。B代表观察到的特征数据 X。P(Y|X)是我们最终需要的后验概率即在看到数据 X 后样本属于类别 Y 的概率。P(X|Y)是似然即在给定类别 Y 的条件下观察到数据 X 的概率。这正是生成模型需要学习的关键部分它描述了每一类数据的分布。P(Y)是先验概率即在看到任何数据之前我们对样本属于类别 Y 的初始信念比如数据集中两类样本的比例。P(X)是证据或边缘似然是一个归一化常数确保所有后验概率之和为1。在实际计算中我们常常通过比较不同类别的分子部分来做决策从而避开对 P(X) 的直接计算。因此对于二分类问题假设类别为 C1 和 C2当我们拿到一个新样本的特征向量x时我们会分别计算它属于两个类别的后验概率 P(C1|x) P(x|C1) * P(C1) / P(x) P(C2|x) P(x|C2) * P(C2) / P(x)我们的分类决策规则非常简单比较 P(C1|x) 和 P(C2|x) 的大小将样本 x 分配给后验概率更大的那个类别。由于分母 P(x) 相同这个比较等价于比较分子 P(x|C1)P(C1) 和 P(x|C2)P(C2) 的大小。注意这里蕴含了一个重要的思维转换。判别模型如逻辑回归直接通过一个函数如sigmoid将特征x映射到类别概率 P(Y|x)。而生成模型则是先“生成”出特征x在各类别下的可能性 P(x|Y)再结合先验“倒推”回类别概率。前者是“由果索因”后者是“由因推果”。2.2 生成模型的核心对 P(X|Y) 的假设既然核心是计算 P(x|C1) 和 P(x|C2)那么如何得到这两个概率分布呢这就是生成模型建模的焦点。我们无法知道真实的分布因此必须对其形式做出假设。最常见的假设是高斯分布正态分布。我们假设每一类别的特征数据都服从一个多元高斯分布。对于类别 Ck其分布由均值向量μ_k和协方差矩阵Σ_k决定 P(x|Ck) N(x|μ_k,Σ_k) (1/((2π)^(d/2)|Σ_k|^(1/2))) * exp(-1/2 (x-μ_k)^TΣ_k^(-1) (x-μ_k))这里的 d 是特征维度。在训练阶段我们的任务就是从训练数据中估计出这些参数对于每个类别 Ck用属于该类别的所有样本计算它们的样本均值作为μ_k的估计计算样本协方差矩阵作为Σ_k的估计。先验概率 P(Ck) 则可以用该类样本数占总样本数的比例来估计。2.3 从生成到判别决策边界的推导当我们把高斯分布的公式代入贝叶斯决策规则并取对数将连乘变为连加简化计算会得到一个关于x的二次函数。这个函数的零点集合即 P(C1|x) P(C2|x) 的点构成了分类的决策边界。这里有一个关键细节协方差矩阵的假设形式直接决定了决策边界的形状。情况一各类别共享同一个协方差矩阵 (Σ1 Σ2 Σ)。此时决策边界中的二次项x^T Σ^(-1) x会相互抵消最终决策函数简化为x的线性函数。这意味着决策边界是一条直线在二维空间或一个超平面在高维空间。这就是经典的线性判别分析LDA模型。它的决策边界是线性的计算高效且当数据真实分布接近此假设时效果很好。情况二各类别有各自的协方差矩阵 (Σ1 ≠ Σ2)。此时二次项无法抵消决策边界是一个二次曲线如椭圆、双曲线等。这就是二次判别分析QDA模型。它比LDA更灵活能刻画更复杂的类别边界但需要估计更多的参数两个协方差矩阵因此对数据量的要求更高也更容易过拟合。选择LDA还是QDA是一个偏差-方差权衡的经典问题。LDA假设强方差小但可能偏差大QDA假设弱更灵活偏差小但方差大。在实际操作中如果特征维度高或数据量少通常优先尝试LDA如果数据量充足且通过可视化或领域知识怀疑决策边界非线性可以尝试QDA并通过交叉验证来比较。3. 模型实现与关键步骤拆解理论清晰后我们进入实战环节。我将以Python为例手把手带你实现一个高斯生成模型分类器并深入每个步骤的细节。3.1 数据准备与探索性分析任何建模工作都始于数据。假设我们有一个数据集特征为X一个n_samples x n_features的矩阵标签为y取值为0或1的向量。import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # 生成模拟数据 X, y make_classification(n_samples500, n_features2, n_informative2, n_redundant0, n_clusters_per_class1, flip_y0.05, class_sep1.5, random_state42) # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, random_state42, stratifyy) # 可视化数据分布 plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) plt.scatter(X_train[y_train0, 0], X_train[y_train0, 1], alpha0.7, labelClass 0, cblue) plt.scatter(X_train[y_train1, 0], X_train[y_train1, 1], alpha0.7, labelClass 1, cred) plt.title(Training Set Distribution) plt.xlabel(Feature 1) plt.ylabel(Feature 2) plt.legend() plt.grid(True, alpha0.3) plt.subplot(1, 2, 2) plt.scatter(X_test[y_test0, 0], X_test[y_test0, 1], alpha0.7, labelClass 0, cblue) plt.scatter(X_test[y_test1, 0], X_test[y_test1, 1], alpha0.7, labelClass 1, cred) plt.title(Test Set Distribution) plt.xlabel(Feature 1) plt.ylabel(Feature 2) plt.legend() plt.grid(True, alpha0.3) plt.tight_layout() plt.show()这一步至关重要。可视化能帮你直观感受两类数据是否线性可分协方差结构是否相似。如果两类点的“形状”分散程度和方向看起来差不多LDA可能是个好选择如果一类是圆形聚集另一类是斜向椭圆形那么QDA可能更合适。3.2 模型训练参数估计的细节接下来我们根据训练数据估计生成模型所需的参数。我们将分别实现LDA共享协方差和QDA独立协方差的参数估计过程。class GaussianGenerativeModel: def __init__(self, model_typelda): 初始化生成模型分类器。 model_type: lda 或 qda self.model_type model_type self.priors None # 先验概率 P(Y) self.means None # 各类别均值向量 μ_k self.covariances None # 协方差矩阵 Σ_k (LDA时共享一个QDA时各有一个) self.shared_cov None # LDA的共享协方差矩阵 self.classes_ None def fit(self, X, y): 根据训练数据估计模型参数。 self.classes_ np.unique(y) n_classes len(self.classes_) n_features X.shape[1] # 1. 估计先验概率 self.priors np.array([np.mean(y c) for c in self.classes_]) # 2. 估计各类别均值向量 self.means np.array([X[y c].mean(axis0) for c in self.classes_]) # 3. 估计协方差矩阵 if self.model_type lda: # LDA: 计算各类别的协方差然后加权平均得到共享协方差 covs [] for idx, c in enumerate(self.classes_): X_c X[y c] # 计算该类别的无偏协方差估计注意自由度是 n_samples - 1 cov_c np.cov(X_c, rowvarFalse, biasFalse) covs.append((len(X_c) - 1) * cov_c) # 存储 (n_k - 1) * Σ_k # 共享协方差Σ_shared Σ_k (n_k - 1) * Σ_k / (N - K) self.shared_cov np.sum(covs, axis0) / (len(X) - n_classes) self.covariances [self.shared_cov.copy() for _ in range(n_classes)] elif self.model_type qda: # QDA: 为每个类别独立计算协方差矩阵 self.covariances [] for c in self.classes_: X_c X[y c] # 同样使用无偏估计 cov_c np.cov(X_c, rowvarFalse, biasFalse) self.covariances.append(cov_c) else: raise ValueError(model_type must be lda or qda) return self这里有几个实操要点协方差估计的无偏性np.cov函数默认使用biasFalse即除以 n-1 而非 n这是对总体协方差矩阵的无偏估计在统计学上更标准。在样本量不大时这一点很重要。LDA共享协方差的计算共享协方差矩阵是各类别协方差矩阵的加权平均权重是(n_k - 1)。分母是总样本数 N 减去类别数 K。这种计算方式确保了估计的稳定性。数值稳定性在高维或特征相关性很强时协方差矩阵可能接近奇异不可逆导致计算似然时出错。在实际工业级代码中通常会加入一个很小的正则化项如cov np.eye(n_features) * 1e-6来确保矩阵可逆。3.3 预测函数计算后验概率与做出决策参数齐备后我们需要实现预测函数。核心是计算对数后验概率避免数值下溢然后进行比较。def _log_likelihood(self, X, mean, cov): 计算多元高斯分布的对数似然忽略常数项。 n_features X.shape[1] # 计算协方差矩阵的逆和行列式的对数 try: cov_inv np.linalg.inv(cov) log_det_cov np.log(np.linalg.det(cov)) except np.linalg.LinAlgError: # 如果矩阵奇异添加微小正则化项 cov_reg cov np.eye(n_features) * 1e-6 cov_inv np.linalg.inv(cov_reg) log_det_cov np.log(np.linalg.det(cov_reg)) # 计算二次型部分: (x - μ)^T Σ^{-1} (x - μ) X_centered X - mean # 高效计算对每个样本计算二次型 # 利用 np.einsum 或 (X_centered cov_inv * X_centered).sum(axis1) quad_form np.einsum(ij,ij-i, X_centered cov_inv, X_centered) # 对数似然-1/2 * [log|Σ| (x-μ)^T Σ^{-1} (x-μ) d*log(2π)] # 常数项 d*log(2π) 在比较时可以省略 log_likelihood -0.5 * (log_det_cov quad_form) return log_likelihood def predict_proba(self, X): 预测样本属于各个类别的概率。 log_posteriors [] for idx, c in enumerate(self.classes_): # 对数后验 ∝ 对数似然 对数先验 log_likelihood self._log_likelihood(X, self.means[idx], self.covariances[idx]) log_posterior log_likelihood np.log(self.priors[idx]) log_posteriors.append(log_posterior) # 堆叠并转换为概率使用log-sum-exp技巧防止数值溢出 log_posteriors np.column_stack(log_posteriors) # log-sum-exp: log(Σ exp(a_i)) max_log log(Σ exp(a_i - max_log)) max_log log_posteriors.max(axis1, keepdimsTrue) exp_log np.exp(log_posteriors - max_log) probas exp_log / exp_log.sum(axis1, keepdimsTrue) return probas def predict(self, X): 预测样本类别。 probas self.predict_proba(X) return self.classes_[np.argmax(probas, axis1)]提示对数域计算与log-sum-exp技巧。概率值通常是非常小的数直接相乘容易导致数值下溢underflow为0。因此我们全程在对数域进行计算。在将对数后验转换回概率时直接计算np.exp(log_posterior)可能因为log_posterior是很大的负数而导致exp结果为0。log-sum-exp技巧通过减去最大值来稳定计算是概率计算中的标准操作务必掌握。3.4 决策边界可视化理解模型如何做决策最好的方式就是看它的决策边界。我们将训练好的LDA和QDA模型在二维特征空间上画出其决策边界。def plot_decision_boundary(model, X, y, title): 绘制模型在二维特征上的决策边界。 x_min, x_max X[:, 0].min() - 1, X[:, 0].max() 1 y_min, y_max X[:, 1].min() - 1, X[:, 1].max() 1 xx, yy np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02)) # 预测网格上每个点的类别概率 Z model.predict(np.c_[xx.ravel(), yy.ravel()]) Z Z.reshape(xx.shape) plt.figure(figsize(8, 6)) # 绘制决策区域 from matplotlib.colors import ListedColormap cmap_light ListedColormap([#AAAAFF, #FFAAAA]) plt.contourf(xx, yy, Z, alpha0.3, cmapcmap_light) # 绘制原始数据点 scatter plt.scatter(X[:, 0], X[:, 1], cy, edgecolork, s50, cmapplt.cm.Paired) plt.xlabel(Feature 1) plt.ylabel(Feature 2) plt.title(title) plt.legend(handlesscatter.legend_elements()[0], labels[Class 0, Class 1]) plt.grid(alpha0.3) plt.show() # 训练并可视化LDA lda_model GaussianGenerativeModel(model_typelda).fit(X_train, y_train) plot_decision_boundary(lda_model, X_train, y_train, LDA Decision Boundary (Linear)) # 训练并可视化QDA qda_model GaussianGenerativeModel(model_typeqda).fit(X_train, y_train) plot_decision_boundary(qda_model, X_train, y_train, QDA Decision Boundary (Quadratic))通过可视化你可以清晰地看到LDA的线性边界和QDA的曲线边界。这能直观地告诉你你的数据更适合哪种假设。4. 模型评估与深入分析模型建好了边界画出来了但它的性能到底如何我们需要一套客观的评估体系。对于二分类问题评估指标远不止一个准确率。4.1 全面理解二分类评价指标我们首先在测试集上进行预测并计算混淆矩阵这是所有指标的源头。from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc, precision_recall_curve # 在测试集上预测 y_pred_lda lda_model.predict(X_test) y_pred_proba_lda lda_model.predict_proba(X_test)[:, 1] # 取正类类别1的概率 # 混淆矩阵 cm_lda confusion_matrix(y_test, y_pred_lda) print(LDA Confusion Matrix:) print(cm_lda) print(\n *50 \n) # 详细的分类报告 print(LDA Classification Report:) print(classification_report(y_test, y_pred_lda, target_names[Class 0, Class 1]))混淆矩阵是一个2x2的表格预测为负类 (0)预测为正类 (1)实际为负类 (0)真阴性 (TN)假阳性 (FP)实际为正类 (1)假阴性 (FN)真阳性 (TP)基于此我们可以计算一系列指标准确率 (Accuracy): (TPTN)/(TPTNFPFN)。最直观但在类别不平衡时可能失真。精确率 (Precision): TP/(TPFP)。“查得准不准”。在所有被模型预测为正的样本中有多少是真的正样本。关注的是预测结果的质量。召回率 (Recall) / 灵敏度 (Sensitivity): TP/(TPFN)。“查得全不全”。在所有真实的正样本中模型找出了多少。关注的是模型对正类的覆盖能力。F1分数 (F1-Score): 2 * (Precision * Recall) / (Precision Recall)。精确率和召回率的调和平均数在两者需要权衡时是一个综合指标。特异度 (Specificity): TN/(TNFP)。与召回率相对关注模型对负类的识别能力。实操心得不要只看准确率尤其是在正负样本比例悬殊如欺诈检测、疾病筛查的场景下。例如一个垃圾邮件分类器如果简单地把所有邮件都判为正常邮件准确率可能有99%但召回率是0%这个模型是无效的。你需要根据业务目标选择核心指标如果追求“宁可错杀不可放过”如安检就优化召回率如果追求“证据确凿才行动”如法律判决就优化精确率。4.2 ROC曲线与AUC超越单一阈值上面的指标都依赖于一个固定的分类阈值默认0.5。但阈值是可以调整的提高阈值模型变得更“保守”只有非常确信时才判为正类这会提高精确率但降低召回率降低阈值则相反。ROC曲线描绘了当阈值从1到0变化时真正例率 (TPR Recall)和假正例率 (FPR 1 - Specificity)的变化关系。# 计算ROC曲线 fpr_lda, tpr_lda, thresholds_lda roc_curve(y_test, y_pred_proba_lda) roc_auc_lda auc(fpr_lda, tpr_lda) # 绘制ROC曲线 plt.figure(figsize(8, 6)) plt.plot(fpr_lda, tpr_lda, colordarkorange, lw2, labelfLDA ROC curve (area {roc_auc_lda:.3f})) plt.plot([0, 1], [0, 1], colornavy, lw2, linestyle--, labelRandom Guess) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel(False Positive Rate) plt.ylabel(True Positive Rate) plt.title(Receiver Operating Characteristic (ROC) Curve) plt.legend(loclower right) plt.grid(alpha0.3) plt.show() # 找到最佳阈值最靠近左上角的点 distances (fpr_lda**2 (1-tpr_lda)**2) optimal_idx np.argmin(distances) optimal_threshold thresholds_lda[optimal_idx] print(fOptimal threshold (closest to top-left): {optimal_threshold:.3f}) print(fAt this threshold - FPR: {fpr_lda[optimal_idx]:.3f}, TPR: {tpr_lda[optimal_idx]:.3f})AUC (Area Under Curve)是ROC曲线下的面积取值范围[0.5, 1]。它衡量的是模型整体的排序能力与阈值选择无关。AUC0.5表示模型没有区分能力等同于随机猜测AUC1表示完美模型。AUC是一个非常重要的综合性指标特别适用于类别不平衡的场景因为它关注的是模型将正样本排在负样本前面的能力。4.3 精确率-召回率曲线 (PR Curve)在不平衡数据集中负样本远多于正样本ROC曲线可能因为FPR很小的变化就看起来很好从而产生过于乐观的评估。此时精确率-召回率曲线 (PR Curve)更能反映模型在正类上的性能。precision_lda, recall_lda, _ precision_recall_curve(y_test, y_pred_proba_lda) pr_auc_lda auc(recall_lda, precision_lda) plt.figure(figsize(8, 6)) plt.plot(recall_lda, precision_lda, colorgreen, lw2, labelfLDA PR curve (area {pr_auc_lda:.3f})) # 随机模型的精确率是正类样本比例 baseline len(y_test[y_test1]) / len(y_test) plt.plot([0, 1], [baseline, baseline], colornavy, lw2, linestyle--, labelRandom Guess) plt.xlabel(Recall) plt.ylabel(Precision) plt.title(Precision-Recall Curve) plt.legend(locupper right) plt.grid(alpha0.3) plt.show()PR曲线越靠近右上角越好。PR AUC同样是一个综合指标。经验法则当正样本非常稀少时比如1%应主要参考PR曲线和PR AUC而不是ROC-AUC。5. 常见问题、陷阱与进阶思考在实际应用生成模型进行分类时你会遇到一些典型问题和挑战。这里我总结了一些“踩坑”经验和进阶思路。5.1 特征相关性与协方差矩阵估计高斯生成模型的核心假设之一是特征服从多元高斯分布。这个假设在现实中常常被违背带来两个主要问题特征非正态分布例如计数数据、长尾分布数据。解决方案包括特征变换对特征进行对数变换、Box-Cox变换等使其更接近正态分布。核密度估计放弃高斯假设使用更灵活的非参数方法估计 P(X|Y)但这会极大增加计算成本且容易过拟合。换用其他生成模型例如朴素贝叶斯假设特征条件独立或更复杂的模型如高斯混合模型(GMM)。高维与小样本问题当特征维度 d 很高而样本数 N 相对较少时协方差矩阵Σ有 d(d1)/2 个参数的估计会非常不稳定甚至不可逆奇异。这就是所谓的“维数灾难”。LDA的天然优势LDA假设共享协方差需要估计的参数大大减少一个协方差矩阵在一定程度上缓解了此问题。正则化LDA/QDA在协方差矩阵的对角线上添加一个小的常数 λ收缩即Σ_reg (1-λ)Σ λI。这相当于假设特征间有一定程度的独立性向单位矩阵收缩。λ 可以通过交叉验证选择。特征选择/降维使用PCA、LDA这里的LDA是线性判别分析一种有监督降维方法注意区分或基于领域知识将特征降至一个可控的维度。5.2 类别先验概率的影响与处理在先验概率 P(Y) 估计不准确或者业务上需要调整分类决策的倾向性时我们可以手动调整先验。 在我们的决策规则中比较的是 P(x|C1)P(C1) 和 P(x|C2)P(C2)。如果我们希望模型对某一类比如正类更敏感即使牺牲一些精确率我们可以人为调高该类别的先验概率。这等价于在决策函数中给该类别的对数后验加上一个偏置项。# 假设业务要求更关注召回正类类别1我们可以人为提高其先验 adjusted_priors np.array([0.3, 0.7]) # 原始可能是[0.5, 0.5] # 在预测时使用调整后的先验进行计算 # 只需在 predict_proba 函数中将 np.log(self.priors[idx]) 替换为 np.log(adjusted_priors[idx])这个技巧在代价敏感学习中非常有用。例如在医疗诊断中将健康人误判为病人假阳性和将病人误判为健康人假阴性的代价是不同的后者通常代价更高。通过调整先验或更一般地引入代价矩阵我们可以让模型的决策向代价更低的方向倾斜。5.3 与逻辑回归的对比与选择逻辑回归是经典的判别模型它直接对 P(Y1|X) 进行建模。一个有趣且重要的结论是当数据确实服从我们前面假设的高斯分布且各类别共享协方差矩阵时LDA与逻辑回归会得到相同的线性决策边界。但在其他情况下它们会产生不同的结果。如何选择数据假设如果你有较强的理由相信特征近似高斯分布且类别间协方差相似LDA可能更有效因为利用了数据分布信息参数估计更稳定。如果这些假设不成立逻辑回归更稳健。样本量在小样本情况下LDA的模型假设起到了正则化作用可能比逻辑回归表现更好。在大样本情况下逻辑回归的灵活性使其能逼近更复杂的边界。计算与概率输出两者都很快。逻辑回归直接输出校准过的概率在满足其模型假设时而生成模型输出的概率严重依赖于分布假设的正确性。多分类逻辑回归扩展到多分类OvR或softmax很自然。生成模型也可以自然地处理多分类只需为每个类别估计一个分布。我个人的经验是在特征工程之后如果特征看起来比较“规整”近似正态、无严重异常值我会把LDA作为一个强力的基线模型。它的训练速度极快且结果具有可解释性可以通过权重向量理解每个特征的重要性。如果LDA表现不佳我会转向更灵活的判别模型如逻辑回归或树模型。生成模型的价值尤其在于其提供数据生成视角和易于处理缺失值、半监督学习的能力这在某些特定场景下是不可替代的。最后别忘了模型评估的黄金准则始终在独立的测试集或通过稳健的交叉验证来评估模型性能避免因为模型复杂度的增加如从LDA到QDA而陷入过拟合的陷阱。生成模型为我们提供了一个强大而直观的概率框架理解它能让你在机器学习的工具箱里又多了一件趁手的兵器。

相关资讯