【NLP】使用 LSA、PLSA、LDA 和 lda2Vec 进行主题建模

一、说明

        本文是对主题建模及其相关技术的更新全面概述在自然语言理解(NLU)任务中,有一个镜头层次结构,通过它我们可以提取含义 - 从单词到句子到段落到文档。在文档级别,理解文本的最有用方法之一是分析其主题(另请参阅 NER)。在文档集合中学习、识别和提取这些主题的过程称为主题建模。

        在这篇文章中,我们将通过当今最流行的4种技术来探索主题建模:LSA,pLSA,LDA和更新的基于深度学习的lda2vec。

二、概述

        所有主题模型都基于相同的基本假设:

  • 每个文档都由主题的混合组成,并且
  • 每个主题都由一组单词组成。

        换句话说,主题模型是围绕这样一种想法构建的,即我们文档的语义实际上由一些我们没有观察到的隐藏或“潜在”变量控制。因此,主题建模的目标是揭示这些潜在的变量 - 主题 - 塑造我们的文档和语料库的含义。这篇博文的其余部分将建立对不同主题模型如何发现这些潜在主题的理解。

三、模型LSA

3.1 原理简述

        潜在语义分析 (LSA) 是主题建模的基础技术之一。核心思想是获取我们拥有的内容(文档和术语)的矩阵,并将其分解为单独的文档-主题矩阵和主题-术语矩阵。

        第一步是生成我们的文档术语矩阵。给定词汇表中的 m 个文档和 n 个单词,我们可以构造一个 m × n 个矩阵 A,其中每行代表一个文档,每列代表一个单词。在最简单的 LSA 版本中,每个条目可以只是第 j 个单词在第 i 个文档中出现的次数的原始计数。然而,在实践中,原始计数的效果不是特别好,因为它们没有考虑文档中每个单词的重要性。例如,“核”一词可能比“试验”一词更多地告诉我们有关给定文件的主题的信息。

        因此,LSA 模型通常用 tf-idf 分数替换文档术语矩阵中的原始计数。Tf-idf,或术语频率-反文档频率,为文档 中的术语 j 分配权重,如下所示:

        直观地说,当一个术语在文档中频繁出现但很少出现在语料库中时,它有很大的权重。“build”一词可能经常出现在文档中,但由于它在语料库的其余部分可能相当常见,因此它的tf-idf 分数不高。但是,如果“绅士化”一词经常出现在文档中,因为它在语料库的其余部分更罕见,它将具有更高的 tf-idf 分数。

        一旦我们有了文档术语矩阵 A,我们就可以开始思考我们的潜在主题了。事情是这样的:A很可能非常稀疏,非常嘈杂,并且在其许多维度上都非常冗余。因此,为了找到捕获单词和文档之间关系的少数潜在主题,我们希望对 A 执行降维。

        这种降维可以使用截断的 SVD 执行。SVD 或奇异值分解是线性代数中的一种技术,它将任何矩阵 M 分解为 3 个独立矩阵的乘积:M=U*S*V,其中 S 是 M 奇异值的对角矩阵。至关重要的是,截断的 SVD 通过仅选择 t 个最大奇异值并仅保留 U 和 V 的前 t 列来降低维数。在这种情况下,t 是一个超参数,我们可以选择和调整以反映我们想要查找的主题数量。

        直观地说,这只认为在我们变换后的空间中保留了最重要的t个维度。

        在这种情况下,U ∈ R^(m ⨉ t) 成为我们的文档主题矩阵,V ∈ R^(n ⨉ t) 成为我们的术语主题矩阵。在 U 和 V 中,列对应于我们的 t 主题之一。在 U 中,行表示以主题表示的文档向量;在 V 中,行表示以主题表示的术语向量。

        使用这些文档向量和项向量,我们现在可以轻松地应用余弦相似性等度量来评估:

  • 不同文档的相似性
  • 不同单词的相似性
  • 术语(或“查询”)和文档的相似性(当我们想要检索与搜索查询最相关的段落时,这在信息检索中很有用)。

3.2 代码

        在 sklearn 中,LSA 的简单实现可能如下所示:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
from sklearn.pipeline import Pipeline
documents = ["doc1.txt", "doc2.txt", "doc3.txt"] # raw documents to tf-idf matrix: 
vectorizer = TfidfVectorizer(stop_words='english', use_idf=True, smooth_idf=True)
# SVD to reduce dimensionality: 
svd_model = TruncatedSVD(n_components=100,         // num dimensionsalgorithm='randomized',n_iter=10)
# pipeline of tf-idf + SVD, fit to and applied to documents:
svd_transformer = Pipeline([('tfidf', vectorizer), ('svd', svd_model)])
svd_matrix = svd_transformer.fit_transform(documents)# svd_matrix can later be used to compare documents, compare words, or compare queries with documents

LSA使用起来既快速又高效,但它确实有一些主要缺点:

  • 缺乏可解释的嵌入(我们不知道主题是什么,组件可能是任意的正/负)
  • 需要非常大的文档和词汇集才能获得准确的结果
  • 表示效率较低

四、模型PLSA

4.1 模型概述

        pLSA,或概率潜在语义分析,使用概率方法而不是SVD来解决问题。核心思想是找到一个具有潜在主题的概率模型,该模型可以生成我们在文档术语矩阵中观察到的数据。特别是,我们想要一个模型 P(D,W),对于任何文档 d 和单词 w,P(d,w) 对应于文档术语矩阵中的该条目。

        回想一下主题模型的基本假设:每个文档由主题的混合组成,每个主题由一组单词组成。pLSA为这些假设增加了概率自旋:

  • 给定文档 d,主题 z 存在于该文档中,概率为 P(z|d)
  • 给定一个主题 z,单词 w 从 z 中抽取,概率为 P(w|z)

从形式上讲,同时看到给定文档和单词的共同概率为:

直观地说,这个等式的右侧告诉我们看到某个文档的可能性有多大,然后根据该文档的主题分布,在该文档中找到某个单词的可能性有多大

在本例中,P(D), P(Z|D) 和 P(W|Z) 是我们模型的参数。P(D)可以直接从我们的语料库中确定。P(Z|D) 和 P(W|Z) 建模为多项式分布,可以使用期望最大化算法 (EM) 进行训练。在不对算法进行全面数学处理的情况下,EM 是一种为模型找到最可能的参数估计的方法,该方法依赖于未观察到的潜在变量(在我们的例子中是主题)。

有趣的是,P(D,W) 可以使用一组不同的 3 个参数等效地参数化:

我们可以通过将模型视为生成过程来理解这种等价性。在我们的第一个参数化中,我们从带有 P(d) 的文档开始,然后使用 P(z|d) 生成主题,然后使用 P(w|z) 生成单词。在这个参数化中,我们从 P(z) 的主题开始,然后使用 P(d|z) 独立生成文档,使用 P(w|z) 独立生成单词。

https://www.slideshare.net/NYCPredictiveAnalytics/introduction-to-probabilistic-latent-semantic-analysis

这种新的参数化之所以如此有趣,是因为我们可以看到我们的pLSA模型与LSA模型之间的直接平行:

其中主题 P(Z) 的概率对应于奇异主题概率的对角矩阵,给定主题 P(D|Z) 的文档的概率对应于我们的文档主题矩阵 U,而给定主题 P(W|Z) 对应于我们的术语-主题矩阵 V

那么这告诉我们什么呢?尽管它看起来完全不同,并且以非常不同的方式处理问题,但pLSA实际上只是在LSA之上添加了对主题和单词的概率处理。这是一个更加灵活的模型,但仍存在一些问题。特别:

  • 因为我们没有参数来建模 P(D),所以我们不知道如何为新文档分配概率
  • pLSA的参数数量随着我们拥有的文档数量线性增长,因此容易过度拟合

我们不会查看 pLSA 的任何代码,因为它很少单独使用。一般来说,当人们正在寻找超出LSA提供的基线性能的主题模型时,他们会转向LDA。LDA 是最常见的主题模型类型,它扩展了 PLSA 以解决这些问题。

五、LDA

5.1 LDA原理概述

        LDA 代表 潜在狄利克雷分配。LDA是pLSA的贝叶斯版本。特别是,它使用狄利克雷先验来表示文档主题和单词主题分布,从而有助于更好地泛化。

        我不打算深入讨论狄利克雷分布,因为这里和这里有非常好的直观解释。然而,作为简要概述,我们可以将狄利克雷视为“分布之上的分布”。从本质上讲,它回答了这个问题:“给定这种类型的分布,我可能会看到哪些实际概率分布?

        考虑比较主题混合物的概率分布的非常相关的示例。假设我们正在查看的语料库包含来自 3 个非常不同的主题领域的文档。如果我们想对此进行建模,我们想要的分布类型将是一个非常重的权重一个特定主题,而根本不给其余主题太多权重。如果我们有 3 个主题,那么我们可能会看到的一些特定概率分布是:

  • 混合物 X90% 主题 A、5% 主题 B、5% 主题 C
  • 混合物Y:5%主题A,90%主题B,5%主题C
  • 混合物 Z:5% 主题 A、5% 主题 B、90% 主题 C

        如果我们从这个狄利克雷分布中得出一个随机概率分布,由单个主题的大权重参数化,我们可能会得到一个非常类似于混合物 X、混合物 Y 或混合物 Z 的分布。我们不太可能对 33% 的主题 A、33% 的主题 B 和 33% 的主题 C 的分布进行抽样。

        这本质上就是狄利克雷分布所提供的:一种对特定类型的概率分布进行采样的方法。回想一下pLSA的模型:

        在pLSA中,我们对一个文档进行采样,然后是一个基于该文档的主题,然后是一个基于该主题的单词。以下是 LDA 的模型:

        从狄利克雷分布 Dir(α),我们绘制一个随机样本,表示特定文档的主题分布或主题混合。此主题分布为 θ。从 θ 中,我们根据分布选择一个特定的主题 Z。

接下来,从另一个狄利克雷分布 Dir(β),我们选择一个表示主题 Z 的单词分布的随机样本。这个词分布是φ。从φ中,我们选择w这个词。

从形式上讲,从文档生成每个单词的过程如下(请注意,此算法使用 c 而不是 z 来表示主题):

https://cs.stanford.edu/~ppasupat/a9online/1140.html

LDA 通常比 pLSA 效果更好,因为它可以轻松地推广到新文档。在 pLSA 中,文档概率是数据集中的固定点。如果我们没有看到文档,我们就没有该数据点。在LDA中,数据集用作文档主题分布的狄利克雷分布的训练数据。如果我们还没有看到文档,我们可以轻松地从狄利克雷分布中采样并从那里继续前进。

5.2 法典

        LDA很容易成为最流行(通常是最有效的)主题建模技术。它在 gensim 中可用,易于使用:

from gensim.corpora.Dictionary import load_from_text, doc2bow
from gensim.corpora import MmCorpus
from gensim.models.ldamodel import LdaModel
document = "This is some document..."
# load id->word mapping (the dictionary)
id2word = load_from_text('wiki_en_wordids.txt')
# load corpus iterator
mm = MmCorpus('wiki_en_tfidf.mm')
# extract 100 LDA topics, updating once every 10,000
lda = LdaModel(corpus=mm, id2word=id2word, num_topics=100, update_every=1, chunksize=10000, passes=1)
# use LDA model: transform new doc to bag-of-words, then apply lda
doc_bow = doc2bow(document.split())
doc_lda = lda[doc_bow]
# doc_lda is vector of length num_topics representing weighted presence of each topic in the doc

使用 LDA,我们可以从文档语料库中提取人类可解释的主题,其中每个主题都以与它们最密切相关的单词为特征。例如,主题 2 可以用“石油、天然气、钻井、管道、梯形石、能源”等术语来描述。此外,给定一个新文档,我们可以得到一个表示其主题混合的向量,例如 5% 主题 1、70% 主题 2、10% 主题 3 等。这些载体通常对下游应用非常有用。

六、深度学习中的LDA:lda2vec

        那么,这些主题模型在更复杂的自然语言处理问题中考虑在哪里呢?

        在这篇文章的开头,我们谈到了能够从各个层面的文本中提取意义是多么重要——单词、段落、文档。在文档级别,我们现在知道如何将文本表示为主题的混合。在单词级别,我们通常使用类似word2vec的东西来获取向量表示。lda2vec 是 word2vec 和 LDA 的扩展,它共同学习单词、文档和主题向量

这是它的工作原理。

        LDA2VEC专门建立在word2vec的skip-gram模型之上,以生成词向量。如果你不熟悉skip-gram和word2vec,你可以在这里阅读它,但本质上它是一个神经网络,通过尝试使用输入词来预测周围的上下文词来学习词嵌入。

        使用 lda2vec,我们不是直接使用词向量来预测上下文词,而是利用上下文向量进行预测。此上下文向量创建为另外两个向量的总和:单词向量和文档向量

        词向量是由前面讨论的相同的skip-gram word2vec模型生成的。文档矢量更有趣。它实际上是另外两个组件的加权组合:

  • 文档权重向量,表示文档中每个主题的“权重”(稍后转换为百分比)
  • 主题矩阵,表示每个主题及其相应的向量嵌入

文档向量和单词向量一起为文档中的每个单词生成“上下文”向量。lda2vec 的强大之处在于,它不仅可以学习单词的词嵌入(和上下文向量嵌入),还可以同时学习主题表示和文档表示。

https://multithreaded.stitchfix.com/blog/2016/05/27/lda2vec

有关该模型的更详细概述,请查看Chris Moody的原始博客文章(Moody在2年创建了lda2016vec)。代码可以在穆迪的github存储库和这个Jupyter Notebook示例中找到。

七、结论

        很多时候,我们将主题模型视为“正常工作”的黑盒算法。幸运的是,与许多神经网络不同,主题模型实际上非常可解释,并且诊断、调整和评估更加简单。希望这篇博文能够解释您需要的基本数学、动机和直觉,并为您提供足够的高级代码来入门。请在评论中留下您的想法,祝您黑客愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/20377.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 集成Druid的监控数据库连接池的最佳实践

免费的chatgpt福利送上 http://124.220.104.235:31105/web/chatgpt 1.数据库连接池介绍 1.1JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤 在主程序(如servlet、beans)中建立数据库连接 进行sql…

第6章 NVMe 介绍 6.1-6.3

6.1 AHCI 到 NVMe AHCI协议。NVMe协议。 HDD 和早期的 SSD 绝大多数都是使用SATA接口,跑的是AHCI,它是一种系统接口标准。 后来,AHCI 和 SATA 不能满足高性能和低时延 SSD 的需求,SSD 需要更快、更高效的协议和接口。因此 NVMe 出…

相对绝对定位父元素不设置宽度,根据子元素撑开(white-space: nowrap;)

要做一个如下的弹窗,很简单。但是当要切换成多语言或者数据是动态的话(title可能会很长),那么弹窗固定宽度就不适用了。 有可能会出现下图的情况 也有可能出现下面的情况,文字被换行了(有时候这种情况也是…

Python爬虫实战之原神公告获取

前言 好久不见了吧,博主最近也是成为了准高三,没有太多时间去创作文章了,所以这篇文章很有可能是高考前最后一篇文章了(也不一定😉) 言归正传,本次文章主要讲解如何去爬取原神官网的公告(我不玩原神!&…

Linux 常用命令

认识 Linux 目录结构 Linux 系统中,磁盘上的文件和目录被组成一棵目录树,每个节点都是目录或文件 Linux 是一个树形目录结构。Linux 上没有盘符概念,不分 C 盘等,根目录 \ 的地位相当与 Java 的 Object ——几个特殊的目录&…

符号化的正确姿势

GUI方式 将 .ips crash report 文件拖放到 Xcode > Window > Devices and Simulators > View Device Logs中, 然后导出 .crash 符号化文件. 使用条件: crash report 对应的 Archive 包是在本机构建的 symbolicatecrash symbolicatecrash 是一个 exec (可执行文件), …

【深度学习】受限玻尔兹曼机 (RBM) 初学者指南

一、说明 受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)是一种基于能量模型的人工神经网络。它只有一个隐层,将输入层和隐层中的每个神经元互相连接,但不同层的神经元之间没有连接。RBM是一种无向的概率图模型&am…

【RocketMQ】005-Docker 部署 RocketMQ

【RocketMQ】005-Docker 部署 RocketMQ 文章目录 【RocketMQ】005-Docker 部署 RocketMQ一、部署1、拉取镜像MQ 镜像可视化平台镜像 2、创建挂载目录创建 nameserver 挂载目录创建 broker 目录创建 broker 配置文件目录 3、编辑配置文件4、启动服务启动 nameserver启动 broker启…

论文笔记--TinyBERT: Distilling BERT for Natural Language Understanding

论文笔记--TinyBERT: Distilling BERT for Natural Language Understanding 1. 文章简介2. 文章概括3 文章重点技术3.1 Transformer Distillation3.2 两阶段蒸馏 4. 数值实验5. 文章亮点5. 原文传送门6. References 1. 文章简介 标题:TinyBERT: Distilling BERT fo…

GPON MAC SFP ONU模块介绍与应用

伴随着网络通讯技术的发展,pon无源光网络正逐步走进人们的视野;在这之前你是否仅知道以太网接入?相比与以太网接入,pon作为一种点到多点网络,具有运维成本低、服务范围广、资源占用少等优势;我们最为熟知的…

FlinkCDC第四部分-同步mysql到mysql,ctrl就完事~(flink版本1.17.1)

本文介绍了不同源单表-单表同步,不同源多表-单表同步。 注:此版本支持火焰图 Flink版本:1.17.1 环境:Linux CentOS 7.0、jdk1.8 基础文件: flink-1.17.1-bin-scala_2.12.tgz、 flink-connector-jdbc-3.0.0-1.16.…

centos7根分区、文件系统扩容

1、 输入lsblk,查看到新硬盘sde,根目录现71G. 2、 创建分区fidisk /dev/sde 3、 刷新分区 partprobe /dev/sde,并创建物理卷 pvcreate /dev/sde1 4、 查看卷组名 vgdisplay 5、 将物理卷扩展到卷组 vgextend centos /dev/sde1 6、 查看逻辑巻…