正在加载中...

展开本页目录
算法教程LDA-主题模型

LDA-主题模型

No.064 · 在线教程

LDA-主题模型 模块的真实实现位于 core/ldacalculator.py。该模块不是自写 Gibbs 采样器,而是先用 CountVectorizer 构造文档-词项矩阵,再调用 sklearn.decomposition.LatentDirichletAllocati…

LDA-主题模型

1. 方法概述

LDA-主题模型 模块的真实实现位于 core/lda_calculator.py。该模块不是自写 Gibbs 采样器,而是先用 CountVectorizer 构造文档-词项矩阵,再调用 sklearn.decomposition.LatentDirichletAllocation 完成主题推断:

$$ X=\mathrm{CountVectorizer}(\mathcal{D}) \tag{1} $$

$$ \mathcal{M}=\mathrm{LatentDirichletAllocation}(X) \tag{2} $$

设语料为

$$ \mathcal{D}=\{d_i\}_{i=1}^{N} \tag{3} $$

其中 \(d_i\) 为第 \(i\) 篇文档。模块的目标是从无标签文本中学习 \(K\) 个潜在主题,并输出每个主题的高权重词以及每篇文档的主题分布。

2. 文本清洗与词袋表示

2.1 文本清洗

程序会把所选文本列强制转成字符串,并执行 _clean_text()。其处理逻辑包括:

  • 可选转小写 lowercase
  • 可选删除数字 remove_numbers
  • 可选删除标点 remove_punct
  • 将连续空白压缩为单个空格

记清洗函数为 \(\mathrm{Clean}(\cdot)\),则

$$ \tilde{d}_i=\mathrm{Clean}(d_i) \tag{4} $$

若清洗后文本长度为 0,则该文档会被直接删除。也就是说,真正进入建模的是清洗后的非空语料 \(\tilde{\mathcal{D}}\)。

2.2 CountVectorizer 词表构造

代码使用 CountVectorizer 将文本表示为文档-词项矩阵:

$$ X\in\mathbb{N}^{N\times V},\qquad X_{iv}=c(v,\tilde{d}_i) \tag{5} $$

其中 \(V\) 为词表大小,\(c(v,\tilde{d}_i)\) 表示词项 \(v\) 在文档 \(\tilde{d}_i\) 中的出现次数。

该实现真实暴露的词表控制参数包括:

  • max_features
  • min_df
  • max_df
  • ngram_min
  • ngram_max
  • token_mode
  • stopwords_source

其中:

$$ \mathrm{ngram\_range}=(n_{\min},n_{\max}) \tag{6} $$

token_mode="word" 时使用词级分析;当 token_mode="char" 时显式设置 analyzer="char",即改为字符级 \(n\)-gram。停用词来源支持 none / english / custom 三种模式;若是 custom,会从用户给定路径读取停用词表。

3. LDA 概率模型与实际训练方式

3.1 LDA 的主题生成观点

从理论上,LDA 假设每篇文档有一个主题混合向量,每个主题有一个词分布。记第 \(i\) 篇文档的主题分布为 \(\theta_i\),第 \(k\) 个主题的词分布为 \(\phi_k\),则通常写作

$$ \theta_i\sim \mathrm{Dir}(\alpha),\qquad \phi_k\sim \mathrm{Dir}(\beta) \tag{7} $$

对文档中的第 \(n\) 个词,先采样主题,再采样词项:

$$ z_{in}\sim \mathrm{Cat}(\theta_i),\qquad w_{in}\sim \mathrm{Cat}(\phi_{z_{in}}) \tag{8} $$

其中 \(\alpha\) 对应文档-主题先验,\(\beta\) 对应主题-词先验。

3.2 本实现的真实训练入口

工程上,这个模块直接调用 sklearnLatentDirichletAllocation

$$ \mathcal{M}=\mathrm{LDA}\!\left( K,\text{max\_iter},\text{learning\_method}, \text{learning\_decay},\text{learning\_offset}, \alpha,\beta \right) \tag{9} $$

其中:

  • \(K=\text{n\_topics}\)
  • learning_method 只能取 batchonline
  • doc_topic_prior 对应 \(\alpha\)
  • topic_word_prior 对应 \(\beta\)

代码中还有一个细节:用户输入的 alpha/beta 若为空、None、非数值,或小于等于 0,则会被转为 None,即不手动指定先验而交由 sklearn 使用默认设置。

3.3 文档主题分布与主题词分布

模型训练后,通过

$$ \Theta=\mathrm{fit\_transform}(X) \tag{10} $$

得到文档主题分布矩阵 \(\Theta\in\mathbb{R}^{N\times K}\)。代码会再次做行归一化:

$$ \theta_{ik}\leftarrow \frac{\theta_{ik}}{\sum_{j=1}^{K}\theta_{ij}} \tag{11} $$

以确保每篇文档的主题概率和为 1。

主题词分布则根据 lda.components_ 归一化得到:

$$ \phi_{kv}=\frac{\mathrm{components}_{kv}}{\sum_{u=1}^{V}\mathrm{components}_{ku}} \tag{12} $$

随后对每个主题按 \(\phi_{kv}\) 从大到小排序,截取 top_n_words 个词,形成 topic_wordtopic_summary 两张结果表。

4. 结果构造、指标与图表

4.1 主题规模

该实现把“主题规模”定义为该主题在所有文档中的概率总和:

$$ \mathrm{TopicSize}_k=\sum_{i=1}^{N}\theta_{ik} \tag{13} $$

注意这不是“主题出现的文档数”,而是文档主题概率的累计值。导出的 主题概要 表中的 topic_size 列就是按这个公式得到的。

4.2 评价指标

代码直接在训练所用的整份文档-词项矩阵 \(X\) 上计算两类指标:

$$ \mathrm{Perplexity}=\exp\!\left(-\frac{\log p(W)}{\sum_i L_i}\right) \tag{14} $$

$$ \mathrm{LogLikelihood}=\log p(W) \tag{15} $$

这里 \(W\) 表示整份语料,\(L_i\) 表示第 \(i\) 篇文档的词数。实际数值分别来自 lda.perplexity(dtm)lda.score(dtm)

这意味着当前实现没有单独的验证集或测试集,perplexitylog_likelihood 都是在训练语料本身上评估得到的,而不是留出集指标。

4.3 实际导出的图表与 Excel 工作表

save_to_excel() 的真实导出内容包括:

  • 原始数据
  • 清洗文本
  • 指标
  • 词表
  • 主题词分布
  • 文档主题分布
  • 主题概要
  • 参数
  • 图表索引

其中图表目录 <结果文件名>_plots 下会保存两张图片:

  • topic_sizes.png
  • doc_topic_heatmap.png

热力图只展示前 50 篇文档、前 15 个主题的局部矩阵,这一点在代码中由 min(50, doc_topic.shape[0])min(15, doc_topic.shape[1]) 控制。

5. 复现脚本与界面参数

5.1 复现脚本

结果页提供“导出复现代码”按钮,会生成 repro_lda_时间戳.py。该脚本会:

  • 尝试把原始输入文件复制到结果目录下的 repro_inputs/
  • 固化本次分析参数
  • 再次调用同一个 LDACalculator

因此复现脚本不是独立重写算法,而是对当前模块的一次参数快照。

5.2 界面默认参数

ui/upload_widget.py 可以确认,该模块默认参数大致为:

  • n_topics=5
  • max_iter=20
  • learning_method=batch
  • learning_decay=0.7
  • learning_offset=10
  • max_features=5000
  • min_df=0.02
  • max_df=0.95
  • top_n_words=10
  • random_state=42

这些默认值会直接影响词表规模、主题数量和迭代行为。

6. 实现说明与注意事项

结合真实代码,可以把该模块概括为:一个基于 CountVectorizer + sklearn LDA 的无监督主题发现工具。它支持词级/字符级 \(n\)-gram、英文或自定义停用词、batch/online 两种学习方式,并能导出主题词分布、文档主题分布和基础图表。

但它也有明显边界:

  • 不做自动主题数选择;
  • 不输出主题一致性 coherence
  • 不使用留出集评估;
  • 不做 pyLDAvis 之类的交互式可视化;
  • 评价指标与主题结果都基于同一份训练语料。

因此,这个实现更适合做工程化的快速主题探索,而不是严格的主题模型研究型评估流程。

7. 论文写作模板

可在论文“方法部分”中写为:

“本文采用基于 CountVectorizerLatentDirichletAllocation 的 LDA 主题模型对文本语料进行无监督主题发现。首先,对原始文本执行清洗、停用词过滤与词级或字符级 \(n\)-gram 向量化,构造文档-词项矩阵;其次,利用 LDA 学习文档主题分布与主题词分布,并对文档主题权重进行归一化处理;随后,结合主题 Top 词、文档主题分布、主题规模以及训练语料上的困惑度和对数似然对主题结构进行解释;最后,输出主题词表、文档主题表与可视化结果,为后续主题归纳和文本内容分析提供依据。”

8. 单篇终审补充

8.1 图题与表题对齐建议

  • 原始数据 表可写为:表X LDA 原始文本数据表。
  • 清洗文本 表可写为:表X LDA 清洗后文本表。
  • 指标 表可写为:表X LDA 模型指标表。
  • 词表 表可写为:表X LDA 词表统计表。
  • 主题词分布 表可写为:表X LDA 主题词分布表。
  • 文档主题分布 表可写为:表X LDA 文档主题分布表。
  • 主题概要 表可写为:表X LDA 主题概要表。
  • 参数 表可写为:表X LDA 参数设置表。
  • 图表索引 表可写为:表X LDA 图表索引与路径清单。
  • topic_sizes.png 建议写为:图X LDA 主题规模图。
  • doc_topic_heatmap.png 建议写为:图X LDA 文档主题分布热力图。

8.2 终审说明

  • 当前代表性结果目录中的真实主工作簿可采用 LDA分析结果_20260324_001708.xlsx,复现输出为 LDA复现结果_20260324_001708.xlsx。论文若列文件名,应区分主运行结果与复现结果。
  • 当前真实工作表为 原始数据/清洗文本/指标/词表/主题词分布/文档主题分布/主题概要/参数/图表索引,终稿表题应按这套中文工作表口径落地。
  • 当前稳定实体图文件只有 topic_sizes.pngdoc_topic_heatmap.png 两张。热力图仅展示前 50 篇文档、前 15 个主题的局部矩阵,正文若说明图义,应写清它不是全量文档-主题矩阵。
  • 真实 repro 脚本为 repro_lda_*.py,并通过 SRC_FILE = 'repro_inputs/lda_sample.csv'repro_inputs/lda_ui_flow_input.csv 读取输入副本。附录中的复现实验说明应保持 repro_inputs/... 相对路径结构。
  • 当前困惑度和对数似然都是基于训练语料本身计算,不是留出集指标。论文结果部分不能把 指标 表误写成“测试集 perplexity”。

8.3 全量强化补充

  • 本轮按真实磁盘再次核对,算法目录为 具体的算法3/NLP基础/LDA-主题模型,代表性结果目录为 具体的算法3/NLP基础/LDA-主题模型/results/LDA-主题模型分析结果_20260324_001708
  • 该目录实际包含两份工作簿:主运行结果 LDA分析结果_20260324_001708.xlsx 与复现输出 LDA复现结果_20260324_001708.xlsx。两份工作簿的真实工作表一致,均为 原始数据清洗文本指标词表主题词分布文档主题分布主题概要参数图表索引
  • 当前图目录分为 LDA分析结果_20260324_001708_plots/LDA复现结果_20260324_001708_plots/ 两套,实体图均为 topic_sizes.pngdoc_topic_heatmap.png。因此这篇可以明确写成“主/复现双工作簿 + 双图目录”的结构。
  • 当前 repro 脚本为 repro_lda_20260324_001708.py,并通过 SRC_FILE = 'repro_inputs/lda_sample.csv' 读取输入副本;该文件在 repro_inputs/ 中实际存在。
  • 需要排除干扰目录。ui_flow_pytest_lda 是测试累积目录,里面保留了多轮复现输出;论文与交付说明应优先使用 LDA-主题模型分析结果_20260324_001708 这一手动单次目录。
  • 当前热力图仍然只是局部展示矩阵,因此即便主/复现两套图都存在,正文也不能把它写成全量文档-主题矩阵可视化。

9. 软件实现核查补充(2026-07)

  • 当前实现的主结果目录应写作 具体的算法3/NLP基础/LDA-主题模型/results/LDA-主题模型分析结果_20260324_001708,主工作簿以 LDA分析结果_20260324_001708.xlsx 为准。
  • 正文应围绕 原始数据清洗文本指标词表主题词分布文档主题分布主题概要参数图表索引 来写,图则对应 topic_sizes.pngdoc_topic_heatmap.png
  • LDA分析结果_20260324_001708.xlsxLDA复现结果_20260324_001708.xlsx 属于主运行/复现并存的同目录结果,不要写成两套完全不同的模型。
  • repro_lda_20260324_001708.py + repro_inputs/lda_sample.csv 是标准 repro_inputs 复现口径,正文和附录要与主/复现工作簿区分开写。