深入理解 Latent Dirichlet Allocation

一、什麼是 Latent Dirichlet Allocation

Latent Dirichlet Allocation (LDA) 是一種用於文本主題建模的概率圖模型。它假設每個文檔是從多個主題中隨機生成的,每個主題又由多個單詞組成。但是,實際給定的文檔,主題和單詞都是不知道的,這些變量是潛在變量。LDA 通過訓練可以推斷出每個文檔的主題分布和每個主題內單詞分布。

LDA 的模型可以用一個圖來表示,如下所示:

digraph {
  rankdir=LR;
  subgraph cluster1 {
     node [style=filled,color=white];
     W1 W2 W3 W4;
     label = "Words";
     fontsize = 16;
  }
  subgraph cluster2 {
     node [style=filled,color=white];
     T1 T2 T3 T4;
     label = "Topics";
     fontsize = 16;
  }
  subgraph cluster3 {
     node [style=filled,color=white];
     D1 D2 D3;
     label = "Documents";
     fontsize = 16;
  }
  subgraph cluster4 {
     node [style=filled,color=lightgrey];
     Z11 Z12 Z13 Z14 Z15;
     label = "Topic Assignments";
     fontsize = 12;
  }
  subgraph cluster5 {
     node [style=filled,color=lightgrey];
     Z21 Z22 Z23 Z24 Z25;
     label = "Topic Assignments";
     fontsize = 12;
  }
  subgraph cluster6 {
     node [style=filled,color=lightgrey];
     Z31 Z32 Z33 Z34 Z35;
     label = "Topic Assignments";
     fontsize = 12;
  }
  D1 -> Z11 -> {T1 T3};
  D1 -> Z12 -> {T2 T4};
  D2 -> Z21 -> {T1 T3};
  D2 -> Z22 -> {T2 T4};
  D3 -> Z31 -> {T1 T2};
  D3 -> Z32 -> {T2 T3};
  D3 -> Z33 -> {T3};
  D3 -> Z34 -> {T3 T4};
  D3 -> Z35 -> {T4};
  {T1 T2 T3 T4} -> W1;
  {T1 T2 T3 T4} -> W2;
  {T1 T2 T3 T4} -> W3;
  {T1 T2 T3 T4} -> W4;
}

這張圖中,表示一篇文檔 $D_i$ 是由一個主題集合 $\{T_1, T_2, …, T_k\}$ 中各個主題按一定概率組合而成的。每個主題 $T_i$ 都是一個單詞集合 $\{w_1, w_2, …, w_n\}$,生成主題的過程類似於文檔到主題的過程,即每個單詞 $w_j$ 按一定概率被分配到某個主題 $T_i$ 上。

二、LDA 模型的數學推導

為了更好地理解 LDA,我們需要了解一下 Dirichlet 分布,它是 LDA 模型中的一個關鍵概率分布。

2.1 Dirichlet 分布

Dirichlet 分布是一種多元隨機變量分布,它的一維形式是 Beta 分布。Dirichlet 分布是一個 $K$ 維概率分布向量 $\boldsymbol{\theta}=\{\theta_1, \theta_2, …, \theta_K\}$ 的概率密度函數,公式如下:

$$
p(\boldsymbol{\theta}|\boldsymbol{\alpha})=\frac{1}{B(\boldsymbol{\alpha})}\prod_{k=1}^{K}\theta_k^{\alpha_k-1}
$$

其中 $\boldsymbol{\alpha}$ 是一個 $K$ 維向量,稱為 Dirichlet 分布的超參數,它控制了分布的形態。

對於一個概率分布 $\boldsymbol{\theta}$,如果 $\alpha_1=\alpha_2=…=\alpha_K=1$,則稱這個分布是均勻分布。

那麼 Dirichlet 分布有什麼應用呢?在 LDA 模型中,每個主題的單詞分布和每個文檔的主題分布都可以看作是一個 Dirichlet 分布的實現。

2.2 Gibbs Sampling

Gibbs Sampling 是一種基於馬爾科夫鏈 Monte Carlo 方法,用於從複雜分布中採樣的技術。在 LDA 模型中,我們使用 Gibbs Sampling 算法從後驗概率分布中採樣文檔的主題分布和主題的單詞分布。

Gibbs Sampling 算法有以下幾個步驟:

  1. 隨機選擇一個文檔 $D_i$ 和一個詞 $w_{ij}$;
  2. 從 $D_i$ 中移除 $w_{ij}$;
  3. 通過後驗概率計算 $w_{ij}$ 屬於每個主題的概率,即 $p(z_{ij}=k|z_{-ij},w)$;
  4. 根據上一步計算出的概率,採樣一個新的主題 $k_{new}$;
  5. 將 $w_{ij}$ 分配到 $k_{new}$ 中;
  6. 重複上述步驟多次,採樣到的文檔的主題分布和主題的單詞分布就是後驗概率分布中的一個樣本。

2.3 LDA 模型的推導

了解了 Dirichlet 分布和 Gibbs Sampling 算法之後,來看一下 LDA 模型的數學推導。

我們假設有 $K$ 個主題,每個主題由一個概率向量 $\boldsymbol{\phi_k}$ 表示,其中第 $j$ 個元素 $\phi_{kj}$ 表示主題 $k$ 中單詞 $j$ 的概率。

每個文檔 $D_i$ 由一個主題分布向量 $\boldsymbol{\theta_i}$ 表示,其中第 $k$ 個元素 $\theta_{ik}$ 表示文檔 $D_i$ 中主題 $k$ 出現的概率。

在給定主題 $\boldsymbol{\phi_k}$ 和文檔主題分布 $\boldsymbol{\theta_i}$ 的情況下,單詞 $w_{ij}$ 屬於主題 $k$ 的概率可以通過以下公式計算:

$$
p(z_{ij}=k|w_{ij},\boldsymbol{\phi_k},\boldsymbol{\theta_i})=\frac{\phi_{kw_{ij}}\theta_{ik}}{\sum_{l=1}^{K}\phi_{lw_{ij}}\theta_{il}}
$$

其中,$z_{ij}$ 表示單詞 $w_{ij}$ 的主題分配,即 $z_{ij}=k$ 表示 $w_{ij}$ 屬於主題 $k$。

對於給定的文檔集 $\boldsymbol{D}$,我們希望求得主題分布 $\boldsymbol{\theta}$ 和主題的單詞分布 $\boldsymbol{\phi}$,使得每篇文檔 $\boldsymbol{d_i}$ 的單詞序列 $\boldsymbol{w_i}$(其中每個單詞 $w_{ij}$ 屬於某個主題 $z_{ij}$)的生成概率最高:

$$
p(\boldsymbol{D}|\boldsymbol{\alpha},\boldsymbol{\beta})=\prod_{i=1}^{M}p(\boldsymbol{d_i}|\boldsymbol{\alpha},\boldsymbol{\beta})=\prod_{i=1}^{M}\int_{\boldsymbol{\theta}}\sum_{\boldsymbol{z}}p(\boldsymbol{d_i}|\boldsymbol{\theta},\boldsymbol{\beta})p(\boldsymbol{\theta}|\boldsymbol{\alpha})p(\boldsymbol{z}|\boldsymbol{\theta})d\boldsymbol{\theta}
$$

其中 $\boldsymbol{\alpha}$ 和 $\boldsymbol{\beta}$ 都是 Dirichlet 分布的超參數。

對於某個文檔 $\boldsymbol{d_i}$,我們可以使用 Gibbs Sampling 迭代得到 $T$ 個樣本 $\{\boldsymbol{\theta_i^{(t)}},\boldsymbol{z_i^{(t)}}\}$。在得到所有文檔的 $T$ 個樣本之後,我們可以針對每個單詞 $w_{ij}$,計算它所屬主題的分布 $p(z_{ij}=k|\boldsymbol{D})$,這個分布即為 LDA 模型的推斷結果。

三、LDA 實現

3.1 數據預處理

在實現 LDA 之前,我們需要對文本數據進行預處理,包括分詞、去停用詞、詞幹提取等。這裡我們以新聞數據集為例,通過 Python 中的 NLTK 庫進行文本預處理。

import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer

nltk.download('stopwords')
nltk.download('punkt')

def preprocess(text):
    tokens = word_tokenize(text)
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if not w.lower() in stop_words]
    stemmer = PorterStemmer()
    tokens = [stemmer.stem(w) for w in tokens]
    return tokens

# 讀取文件
with open('news.txt', 'r') as f:
    raw_text = f.read()

# 預處理文本
tokens = preprocess(raw_text)

3.2 構建詞典

在 LDA 中,我們需要構建一個詞典,將詞語映射為整數。這個詞典的大小決定了單詞分布的維度。我們可以在文本預處理的過程中,統計每個單詞出現的次數,然後通過給每個單詞分配一個唯一的整數來構建詞典。

# 構建詞典
vocab = {}
for word in tokens:
    if word not in vocab:
        vocab[word] = len(vocab)

3.3 計算單詞分布

在 LDA 中,單詞的分布與主題的分布同等重要。我們需要計算每個主題中每個單詞的概率分布。這裡我們仍然使用詞頻作為單詞分布的度量,即對於主題 $k$ 中的單詞 $w_j$,其概率為:

$$
\phi_{kj}=\frac{n_{kj}}{\sum_{j=1}^{W}n_{kj}}
$$

其中,$n_{kj}$ 表示主題 $k$ 中單詞 $w_j$ 出現的次數,而分母則是主題 $k$ 中的總單詞數。

import numpy as np

# 初始化單詞分布
K = 10  # 主題數
W = len(vocab)  # 詞彙量
beta = np.ones((K, W))  # 每個主題的單詞分布
for k in range(K):
    for w in range(W):
        beta[k, w] += np.sum(n[k, vocab_inv[w], :])
    beta[k, :] /= np.sum(beta[k, :])

3.4 計算文檔主題分布

在 LDA 中,我們還需要計算每篇文檔的主題分布。這可以通過 Gibbs Sampling 算法得到。我們初始化文檔主題分布為一個均勻分布,然後迭代多次,使得文檔

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/288693.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-24 03:00
下一篇 2024-12-24 03:00

相關推薦

  • Elasticsearch API使用用法介紹-get /_cat/allocation

    Elasticsearch是一個分布式的開源搜索和分析引擎,支持全文檢索和數據分析,並且可伸縮到上百個節點,處理PB級結構化或非結構化數據。get /_cat/allocation…

    編程 2025-04-28
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、字節與比特 在討論byte轉int之前,我們需要了解字節和比特的概念。字節是計算機存儲單位的一種,通常表示8個比特(bit),即1字節=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25
  • 深入剖析MapStruct未生成實現類問題

    一、MapStruct簡介 MapStruct是一個Java bean映射器,它通過註解和代碼生成來在Java bean之間轉換成本類代碼,實現類型安全,簡單而不失靈活。 作為一個…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱“存儲程序控制原理”,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的總線來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25

發表回復

登錄後才能評論