ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

从西瓜数据集实战线性判别分析:原理推导与Python代码实现

2026/9/4 6:26:12 拓冰建站 浏览量
从西瓜数据集实战线性判别分析:原理推导与Python代码实现 简介本资源是一份面向机器学习初学者与实践者的线性判别分析LDA教学实践包聚焦特征降维与多类分类任务以经典西瓜数据集3.0为载体完整呈现LDA在Python中的建模、训练与评估全流程。压缩包共10个文件含2个核心Python脚本LDA.py与self_def.py、1个CSV格式的西瓜数据集watermelon_3a.csv、3个XML配置文件及辅助开发文件如.iml、.pyc、.DS_Store总大小仅12KB轻量易部署适合嵌入课程实验或自学项目。已有584人下载学习资源结构简洁清晰src目录封装主程序逻辑data目录存放原始数据.idea配置支持PyCharm快速调试。读者可直接运行代码完成数据加载、训练集划分、LDA模型拟合、预测及classification_report性能评估同时获得对高斯假设、类内/类间散度理解的实践入口是掌握监督式降维方法的实用入门材料。1. 项目概述从“西瓜数据集”到线性判别分析LDA的实战之旅如果你刚接触机器学习面对一堆算法名词感到头大那“线性判别分析”Linear Discriminant Analysis, LDA绝对是一个值得你花时间吃透的经典算法。它不像深度学习那样需要海量数据和算力也不像某些黑盒模型那样难以解释。LDA的核心思想非常直观找到一个投影方向让不同类别的数据在这个方向上投影后类间的距离尽可能大类内的距离尽可能小。听起来是不是有点像在人群中找一条路让不同队伍的人站得尽量分开而同一队伍的人站得尽量紧凑这个经典的“降维”兼“分类”算法在文本主题建模另一个LDALatent Dirichlet Allocation、人脸识别、生物信息学等领域至今仍有广泛应用。今天我们就用一个非常接地气的“西瓜数据集”来手把手实现LDA。这个数据集在周志华老师的《机器学习》俗称“西瓜书”里被反复使用数据量小、特征明确是理解算法原理的绝佳“教具”。我们将用Python从零开始不依赖高级的scikit-learn封装当然最后也会对比一下一步步推导公式、编写代码、可视化结果让你不仅知道怎么调包更明白包里的每一行代码在算什么。你会发现LDA.zip里装的不仅是代码更是一套理解监督式降维与分类的完整思维模型。2. LDA的核心原理与数学推导拆解2.1 问题定义我们要解决什么假设我们手头有一个数据集比如我们的“西瓜数据集”每个西瓜样本有多个特征如密度、含糖率并且每个样本都有一个已知的类别标签如好瓜、坏瓜。LDA要解决的核心问题是如何利用这些已知的类别信息找到原始特征空间的一个低维投影通常是直线或平面使得在这个新的低维空间里不同类别的样本能最大程度地被区分开。这带来了两个直接的好处1.降维将高维数据可视化到二维或三维便于我们观察和理解。2.分类可以直接在这个投影后的低维空间里构建一个简单的分类器比如找一个分类阈值。2.2 核心思想类内小类间大LDA的目标可以用一个优化问题来精确描述。我们目标是找到一个投影向量w将样本x投影到一维空间y w^T x。LDA希望投影后满足类内散度Within-class scatter最小化同一类别样本的投影点尽可能聚集在一起方差小。类间散度Between-class scatter最大化不同类别样本的投影点的中心尽可能远离。如何量化“散度”呢这里引入了散度矩阵的概念。类内散度矩阵Sw衡量每个类别内部样本的分散程度。计算方法是每个类别样本与其类别均值的协方差矩阵之和。Sw Σ_i Σ_{x∈X_i} (x - m_i)(x - m_i)^T其中m_i是第i类的均值向量。类间散度矩阵Sb衡量不同类别中心之间的分散程度。计算方法是每个类别的样本数乘以该类均值与总体均值的差的外积之和。Sb Σ_i n_i (m_i - m)(m_i - m)^T其中m是全体样本的总体均值向量n_i是第i类的样本数。投影后类内散度变为w^T Sw w类间散度变为w^T Sb w。我们的优化目标就是最大化它们的比值即寻找w使得下式最大J(w) (w^T Sb w) / (w^T Sw w)这个J(w)就是著名的“广义瑞利商”Generalized Rayleigh Quotient。2.3 求解特征值分解的登场如何求解使J(w)最大的w呢在数学上可以证明最优的投影方向w满足方程Sb w λ Sw w这被称为广义特征值问题。通常Sw是可逆的上式可以转化为标准特征值问题Sw^{-1} Sb w λ w也就是说我们要求解矩阵Sw^{-1} Sb的特征值和特征向量。其中最大特征值对应的特征向量就是我们要找的、使得类间区分度最大的投影方向。如果我们想投影到多维比如二维就取前k个最大特征值对应的特征向量组成投影矩阵W。注意这里有一个非常重要的前提就是Sw必须是可逆的。这就要求样本数量必须大于特征维度且特征之间不能存在完全的线性相关性。在实际应用中如果Sw奇异不可逆需要进行正则化处理如加上一个很小的单位矩阵Sw εI或者先使用PCA进行降维。2.4 LDA与PCA的本质区别很多人容易混淆LDA和主成分分析PCA。这里务必厘清PCA无监督寻找数据方差最大的投影方向目标是保留最多的数据信息方差完全无视样本的类别标签。LDA有监督寻找能最好区分已知类别的投影方向目标是最大化分类潜力强烈依赖类别标签。用一个比喻PCA是给你一堆混在一起的彩色珠子它帮你找到一条线让所有珠子在这条线上铺得最开方差最大不管颜色。LDA是已知哪些珠子是红色、哪些是蓝色它帮你找到一条线让红色珠子和蓝色珠子在这条线上分别聚成两团且两团离得尽量远。3. 西瓜数据集解析与Python环境准备3.1 西瓜数据集3.0α 深度解析我们采用“西瓜书”第3章最经典的“西瓜数据集3.0α”。这个数据集虽然小但涵盖了连续值和离散值为了聚焦LDA核心我们通常只选取两个连续特征密度和含糖率以及一个二分类标签好瓜是和坏瓜否。原始数据可能如下表所示编号密度含糖率好瓜10.6970.460是20.7740.376是............170.5930.042否这个数据集非常适合教学维度低只有2个特征投影结果可以轻松在二维平面上可视化直观理解LDA的投影直线。样本少总共17个样本手动计算或调试代码都非常方便。线性可分性数据在二维平面上大致是线性可分的LDA能发挥出很好的效果。在实际代码中我们会将“是”标记为类别1“否”标记为类别0并将特征数据整理成一个(17, 2)的矩阵X标签整理成一个(17,)的向量y。3.2 Python环境与工具库清单我们将使用最基础的科学计算库来实现LDA确保每一步都清晰可见。# 环境准备所需库 import numpy as np import matplotlib.pyplot as plt from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as SKLDA # 用于对比 # 确保可复现性 np.random.seed(42)核心库说明NumPy整个项目的基石。所有矩阵运算均值、协方差、特征值分解都依赖它。务必理解其数组广播和矩阵乘法。Matplotlib用于可视化。我们将绘制原始数据散点图、LDA投影方向、以及投影后的数据分布直方图。scikit-learn仅用于最后的结果验证和对比。我们会用它的LDA实现来检验我们自己编写的算法是否正确。一个关键的实操心得在开始编码前我强烈建议你在Jupyter Notebook或支持交互的Python环境中进行。这样你可以随时打印中间变量如Sw,Sb, 特征值等的形状和值与手算或逻辑推导进行比对这是理解算法、调试代码最有效的方式。4. 从零手撕LDA代码实现4.1 数据加载与预处理首先我们手动输入西瓜数据集并进行标准化处理。虽然LDA本身不受量纲影响因为其优化目标是一个比值但良好的数据习惯是从标准化开始。def load_watermelon_data(): 加载西瓜数据集3.0α (密度 含糖率) # 特征X: 密度, 含糖率 X np.array([ [0.697, 0.460], [0.774, 0.376], [0.634, 0.264], [0.608, 0.318], [0.556, 0.215], [0.403, 0.237], [0.481, 0.149], [0.437, 0.211], [0.666, 0.091], [0.243, 0.267], [0.245, 0.057], [0.343, 0.099], [0.639, 0.161], [0.657, 0.198], [0.360, 0.370], [0.593, 0.042], [0.719, 0.103] ]) # 标签y: 1为好瓜(是), 0为坏瓜(否) y np.array([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]) return X, y X, y load_watermelon_data() print(f数据形状: X{X.shape}, y{y.shape}) print(f类别分布: 好瓜{sum(y1)}个, 坏瓜{sum(y0)}个) # 数据标准化 (Z-score标准化) def standardize(X): mean np.mean(X, axis0) std np.std(X, axis0) return (X - mean) / std, mean, std X_std, X_mean, X_std_dev standardize(X) print(标准化后的前5个样本:\n, X_std[:5])注意这里标准化存储了均值和标准差这是一个好习惯。在后续将新样本投影到LDA空间时你需要用同样的均值和标准差先对新样本进行标准化然后再乘以我们求得的投影矩阵W。很多初学者会忘记这一步导致预测错误。4.2 核心计算类内与类间散度矩阵这是LDA算法的核心步骤。我们需要分别计算每个类别的均值、总体均值然后套用公式计算Sw和Sb。def compute_lda_components(X, y): 计算LDA所需的散度矩阵和投影向量 参数: X: 标准化后的特征矩阵 (n_samples, n_features) y: 标签向量 (n_samples,) 返回: W: 投影矩阵 (n_features, n_components) eigenvalues: 特征值 n_features X.shape[1] labels np.unique(y) # 计算总体均值 overall_mean np.mean(X, axis0) # 初始化 Sw 和 Sb 为零矩阵 Sw np.zeros((n_features, n_features)) Sb np.zeros((n_features, n_features)) for label in labels: # 获取当前类别的样本 X_i X[y label] # 计算当前类别的均值 mean_i np.mean(X_i, axis0) # 计算当前类别的类内散度矩阵并累加到 Sw # X_i - mean_i 是中心化后的矩阵 Sw (X_i - mean_i).T (X_i - mean_i) # 等价于 np.cov(X_i.T, biasTrue) * (len(X_i)-1) # 计算当前类别的类间散度矩阵贡献并累加到 Sb n_i len(X_i) mean_diff (mean_i - overall_mean).reshape(-1, 1) # 转换为列向量 Sb n_i * (mean_diff mean_diff.T) # 求解广义特征值问题 Sw^{-1} Sb w λ w # 使用 np.linalg.eig 求解但更稳定的方式是使用 np.linalg.pinv(Sw) Sb # 因为Sw可能接近奇异使用伪逆更稳健 Sw_inv np.linalg.pinv(Sw) # 使用伪逆代替逆提高数值稳定性 M Sw_inv Sb # 计算特征值和特征向量 eigenvalues, eigenvectors np.linalg.eig(M) # 特征值和特征向量是复数由于数值计算我们取实部 eigenvalues np.real(eigenvalues) eigenvectors np.real(eigenvectors) # 按特征值降序排序 idx eigenvalues.argsort()[::-1] eigenvalues eigenvalues[idx] eigenvectors eigenvectors[:, idx] # 我们通常选择非零特征值对应的特征向量。 # 对于二分类问题Sb的秩最大为1因此最多只有一个非零特征值对应一个投影方向。 # 我们选取前 min(n_features, len(labels)-1) 个特征向量对于二分类就是1个。 n_components min(n_features, len(labels) - 1) W eigenvectors[:, :n_components] return W, eigenvalues W, eig_vals compute_lda_components(X_std, y) print(投影向量 W (列向量):\n, W) print(对应的特征值:\n, eig_vals) print(投影向量形状:, W.shape)关键点解析Sw的计算(X_i - mean_i).T (X_i - mean_i)是协方差矩阵的(n-1)倍。这是计算类内散度最直接的方式。Sb的计算mean_diff被重塑为列向量mean_diff mean_diff.T得到一个矩阵乘以样本数n_i后累加。使用伪逆np.linalg.pinv这是实现中的关键技巧。直接求逆np.linalg.inv(Sw)在Sw接近奇异即特征间相关性很强或样本数少于特征数时会报错。伪逆提供了数值上更稳定的解。特征值分解结果np.linalg.eig返回的特征值和特征向量可能是复数这是浮点数计算中的微小误差导致的我们取实部即可。投影维度选择LDA能降维到的最大维度是min(n_features, n_classes-1)。对于二分类问题无论原始特征有多少维投影后最多只有一维一条直线。我们的西瓜数据是二维特征二分类所以W是一个(2, 1)的矩阵即一个投影方向。4.3 数据投影与结果可视化得到投影方向W后我们就可以将原始数据投影到这条直线上并直观地看到分类效果。def project_and_visualize(X, y, W): 将数据投影到LDA方向并可视化 # 投影: Y X * W X_projected X W # 创建画布 fig, axes plt.subplots(1, 2, figsize(14, 5)) # 子图1: 原始数据及LDA投影方向 ax1 axes[0] # 绘制原始数据点 ax1.scatter(X[y1, 0], X[y1, 1], cred, markero, label好瓜, alpha0.7, s80) ax1.scatter(X[y0, 0], X[y0, 1], cblue, markers, label坏瓜, alpha0.7, s80) # 绘制LDA投影方向直线 # 直线的方向由W决定我们过原点画一条线因为数据已标准化中心在原点 # 生成直线上的点 line_x np.linspace(X[:,0].min()-0.5, X[:,0].max()0.5, 100) # W是(2,1)矩阵W[1]/W[0]是斜率 if abs(W[0]) 1e-10: # 避免除零 line_y (W[1]/W[0]) * line_x ax1.plot(line_x, line_y, k--, linewidth2, labelfLDA投影方向 (斜率{W[1]/W[0]:.3f})) else: # 如果W[0]接近0说明投影方向接近y轴 ax1.axvline(x0, colork, linestyle--, linewidth2, labelLDA投影方向 (垂直)) # 绘制样本点到投影方向的垂线可选更直观 for i in range(len(X)): x_point X[i] # 计算投影点坐标 # 投影到方向向量W上 proj (x·w)/(w·w) * w w_vec W.flatten() proj_coeff np.dot(x_point, w_vec) / np.dot(w_vec, w_vec) proj_point proj_coeff * w_vec ax1.plot([x_point[0], proj_point[0]], [x_point[1], proj_point[1]], gray, alpha0.3, linewidth0.5) ax1.set_xlabel(密度 (标准化后)) ax1.set_ylabel(含糖率 (标准化后)) ax1.set_title(原始数据与LDA投影方向) ax1.legend() ax1.grid(True, linestyle--, alpha0.5) ax1.axis(equal) # 子图2: 投影后的数据分布直方图 ax2 axes[1] # 获取两类投影后的值 proj_good X_projected[y1].flatten() proj_bad X_projected[y0].flatten() # 绘制直方图 ax2.hist(proj_good, bins8, alpha0.7, colorred, label好瓜, edgecolorblack) ax2.hist(proj_bad, bins8, alpha0.7, colorblue, label坏瓜, edgecolorblack) # 计算并绘制两类投影中心的垂线 mean_good np.mean(proj_good) mean_bad np.mean(proj_bad) ax2.axvline(xmean_good, colordarkred, linestyle-, linewidth2, labelf好瓜中心 ({mean_good:.3f})) ax2.axvline(xmean_bad, colordarkblue, linestyle-, linewidth2, labelf坏瓜中心 ({mean_bad:.3f})) # 计算一个简单的分类阈值两类中心的平均值 simple_threshold (mean_good mean_bad) / 2 ax2.axvline(xsimple_threshold, colorgreen, linestyle--, linewidth3, labelf分类阈值 ({simple_threshold:.3f})) ax2.set_xlabel(投影值) ax2.set_ylabel(频数) ax2.set_title(投影后数据分布直方图) ax2.legend() ax2.grid(True, linestyle--, alpha0.5) plt.tight_layout() plt.show() return X_projected, simple_threshold X_proj, threshold project_and_visualize(X_std, y, W) print(f投影后数据形状: {X_proj.shape}) print(f建议的分类阈值 (两类中心均值): {threshold:.4f})可视化解读左图你可以清晰地看到一条黑色虚线那就是LDA找到的最佳投影方向。所有样本点都沿着灰色细线“垂落”到这条黑线上。我们的目标就是让红色圆圈好瓜和蓝色方块坏瓜在这条黑线上的投影点尽可能地各自聚集且两团离得远。右图直方图展示了投影后的结果。红色和蓝色的柱子分别代表好瓜和坏瓜投影值的分布。两条深色竖线是它们的中心绿色虚线是取两个中心点中点得到的简单分类阈值。可以看到在这个一维投影空间里两类数据基本被分开了只有极少部分重叠。这证明了LDA投影的有效性。4.4 分类器构建与性能评估投影之后我们实际上得到了一个一维特征。在这个一维空间里构建分类器就非常简单了最常见的就是用一个阈值来划分。def lda_classifier(X_projected, threshold): 简单的阈值分类器 # 假设投影后好瓜的投影值通常更大取决于W的方向 # 如果投影值大于阈值预测为好瓜(1)否则为坏瓜(0) return (X_projected threshold).astype(int).flatten() # 在训练集上应用分类器 y_pred lda_classifier(X_proj, threshold) # 计算准确率 accuracy np.mean(y_pred y) print(f基于LDA投影和阈值分类的训练集准确率: {accuracy:.2%}) # 更严谨的做法查看分类决策 print(\n样本预测详情 (编号 真实标签 投影值 预测标签):) for i in range(len(X)): print(f{i1:2d}: {y[i]} - {X_proj[i,0]:7.4f} - {y_pred[i]} {✓ if y[i]y_pred[i] else ✗})注意事项这里我们直接在训练集上评估准确率会偏高过拟合。在实际项目中必须使用未见过的测试集或交叉验证来评估模型性能。对于这个微型教学数据集我们主要是为了理解流程。5. 与scikit-learn实现对比及高级话题5.1 使用scikit-learn验证为了验证我们手写的LDA是否正确最好的办法是调用业界标准的scikit-learn实现进行对比。def compare_with_sklearn(X_std, y): 与scikit-learn的LDA进行对比 # 使用sklearn的LDA指定降维到1维 sk_lda SKLDA(n_components1) X_proj_sk sk_lda.fit_transform(X_std, y) # 注意sklearn的fit_transform直接返回降维后的数据 # 获取sklearn计算出的投影向量 # sklearn的coef_是判别函数的系数方向与我们的W有关但不直接相等。 # 更直接的是获取标量化后的特征向量。 # sklearn将投影向量存储在scalings_属性中 W_sk sk_lda.scalings_[:, :1] # 取第一列 print(scikit-learn 计算出的投影向量 (scalings_):\n, W_sk) print(我们手写代码计算出的投影向量 W:\n, W) # 比较方向是否一致可能差一个符号因为方向相反不影响分类 # 计算两个向量的余弦相似度绝对值 cos_sim np.abs(np.dot(W.flatten(), W_sk.flatten()) / (np.linalg.norm(W) * np.linalg.norm(W_sk))) print(f\n投影向量方向余弦相似度 (绝对值): {cos_sim:.6f}) print((非常接近1说明方向一致)) # 比较投影后的数据可能差一个缩放因子和符号 # 将我们的投影数据与sklearn的进行相关性比较 corr np.corrcoef(X_proj.flatten(), X_proj_sk.flatten())[0,1] print(f投影后数据的相关系数: {corr:.6f}) print((非常接近1或-1说明线性相关即投影本质相同)) # 使用sklearn的模型进行预测 y_pred_sk sk_lda.predict(X_std) accuracy_sk np.mean(y_pred_sk y) print(f\nscikit-learn LDA 训练集准确率: {accuracy_sk:.2%}) print(f我们手写LDA的准确率: {np.mean(lda_classifier(X_proj, threshold)y):.2%}) compare_with_sklearn(X_std, y)运行这段代码你会发现我们的投影方向W与sklearn的scalings_可能方向相反余弦相似度接近-1但投影后数据的相关系数绝对值接近1。这是完全正常的因为投影直线没有正反方向之分w和-w是同一个子空间。分类准确率也应该是一致的。这个对比验证了我们手写LDA核心逻辑的正确性。5.2 多分类LDA与维度选择我们的例子是二分类。对于多分类问题C2个类别LDA的原理完全一样。此时Sb矩阵的秩最大为C-1。这意味着我们最多可以找到C-1个有意义的投影方向对应C-1个非零特征值。这些投影方向张成了一个最多C-1维的子空间。在代码实现上你只需要修改n_components参数例如设置为min(n_features, n_classes-1)然后取前n_components个特征向量组成投影矩阵W。投影后的数据X_projected X W将是一个(n_samples, n_components)的矩阵。如何选择降维后的维度k一个常用的方法是观察特征值。特征值λ_i的大小代表了对应投影方向的重要性区分能力。你可以计算累计贡献率累计贡献率 前k个特征值之和 / 所有特征值之和然后选择一个k使得累计贡献率达到一个较高的阈值如95%。对于分类任务有时直接选择k n_classes - 1也是一个合理的默认值。5.3 LDA的假设与局限性没有哪个算法是万能的LDA也不例外它建立在几个关键假设之上正态性假设每个类别的数据特征服从多元正态分布。在实际中虽然轻微偏离此假设LDA仍可工作但严重偏离会影响性能。同方差性假设所有类别的协方差矩阵相同即Sw矩阵。这是我们推导中Sw是各类别协方差矩阵之和的前提。如果不同类别数据形状差异很大比如一个类是圆形散开另一个类是扁椭圆形LDA的效果会打折扣。线性可分性LDA寻找的是线性投影。如果原始数据本身是非线性可分的比如环形分布线性投影无法很好地区分此时需要考虑核判别分析KDA或其他非线性方法。一个重要的实操心得在应用LDA前快速检查数据是否大致符合这些假设是个好习惯。例如可以分别画出每个类别特征的分布直方图或Q-Q图来检查正态性可以计算每个类别的协方差矩阵并观察它们是否相似。当假设被严重违反时朴素贝叶斯分类器对特征独立性假设敏感或二次判别分析QDA放松同方差假设可能是更好的选择。6. 常见问题、调试技巧与扩展应用6.1 报错与问题排查速查表问题现象可能原因解决方案Sw矩阵奇异无法求逆1. 样本数少于特征数。2. 特征之间存在完全线性相关。1. 增加样本或使用正则化Sw λI。2. 进行特征选择或先用PCA降维。特征值/特征向量出现复数数值计算误差Sw^{-1}Sb不是严格的对称矩阵。取np.real()获取实部通常不影响结果。或使用scipy.linalg.eigh求解广义特征值问题。投影后分类效果很差1. LDA的假设正态、同方差严重不满足。2. 数据本质是非线性可分的。1. 尝试对数据进行变换如对数变换使其更接近正态。2. 使用QDA、核方法或非线性分类器。与sklearn结果符号相反投影方向w和-w是等价的。检查投影后数据的相关系数如果绝对值接近1则结果一致。可通过比较分类准确率验证。多分类时维度超过C-1试图获取多于C-1个投影方向。将n_components设置为min(n_features, n_classes-1)。6.2 性能优化与数值稳定技巧正则化Regularization当Sw接近奇异时在Sw上加一个小的正则化项λ * I单位矩阵是标准做法。这相当于在优化目标中加入了对投影向量w的L2范数惩罚防止过拟合并提高数值稳定性。lambda_reg 1e-4 # 一个很小的正数 Sw_reg Sw lambda_reg * np.eye(Sw.shape[0]) Sw_inv np.linalg.inv(Sw_reg) # 此时可以直接求逆使用更稳定的求解器对于广义特征值问题Sb w λ Sw w可以使用scipy.linalg.eigh函数它专门用于求解厄米特实对称矩阵的特征值问题并支持广义形式数值上更稳定。from scipy.linalg import eigh eigenvalues, eigenvectors eigh(Sb, Sw) # 直接求解广义特征值问题先进行PCA预降维白化如果特征维数很高可以先使用PCA将数据降到较低维度比如保留95%方差然后再应用LDA。这能有效缓解小样本问题并去除噪声。6.3 超越西瓜数据集LDA的实际应用场景理解了LDA在西瓜数据集上的运作后你可以将其应用到更广泛的领域图像识别与计算机视觉在人脸识别中LDA常被称为Fisherfaces被用来提取最能区分不同人脸的线性特征。将每张人脸图像拉成一个高维向量LDA可以找到区分不同人的低维子空间。生物信息学与医学诊断在基因表达数据分析中样本患者有成百上千个基因特征的表达量标签是疾病类型如癌症亚型。LDA可以用于寻找对区分疾病亚型最重要的基因组合并实现降维可视化。文本分类与主题模型注意这里的LDA通常是潜在狄利克雷分布与线性判别分析同名但完全不同。不过线性判别分析本身也可以用于文本分类例如将文档的词袋模型向量投影到低维空间后再分类。故障诊断与质量控制在工业生产中传感器会采集设备的多维运行数据。LDA可以学习正常状态和各类故障状态下的数据投影当新数据投影点偏离正常区域时即可预警。最后再分享一个小技巧当你使用LDA作为分类前的降维工具时不妨将它与最简单的分类器如最近邻、线性SVM在投影后的低维空间上结合。这样构建的管道Pipeline往往比直接在原始高维空间使用复杂分类器更高效、更不容易过拟合且模型可解释性更强。你可以用sklearn.pipeline.Pipeline轻松实现这一流程并利用网格搜索来优化LDA的维度和分类器的参数。本文还有配套的精品资源点击获取