用 Python 实现 LDA

LDA主题模型简介及Python实现 一、LDA主题模型简介 LDA主题模型主要用于推测文档的主题分布,可以将文档集中每篇文档的主题以概率分布的形式给出根据主题进行主题聚类或文本分类。 LDA主题模型不关心文档中单词的顺序,通常使用词袋特征(bag-of-word feature)来代表文档。词袋模型介绍可以参考这篇文章:文本向量化表示——词袋模型 - 知乎 了解LDA模型,我们需要先了解LDA的生成模型,LDA认为一篇文章是怎么形成的呢? LDA模型认为主题可以由一个词汇... 阅读详情

原文出处:Jordan Barber

  • LDA 是什么
  • LDA 演练
    • 需要用到的包
    • 导入文档
    • 清洗文档 
      • 分词
      • 移除停用词
      • 词干提取
    • 创建 document-term matrix
    • 应用 LDA 模型
    • 检查结果
    • LDA 原理
    • 完整代码

LDA 是什么?

隐含狄利克雷分布(以下简写为 LDA)是一种主题模型,它基于一组文档中的词频生成主题。对于在给定的文档集中准确合理地找到主题的混合,LDA 是一种非常有效的方法。

LDA 演练

这一部分,我会用一个高度简化过的文档集来演练生成一个 LDA 模型的过程。这并不是对 LDA 的全面讲解。这个演练的目的是为大家准备数据,以及用 LDA 模型得到相应输出的核心步骤提供指导。

需要用到的包

该演练当中使用的 Python 包有:

  • NLTK, Python 的一个自然语言处理工具包。对于任何一种自然语言的处理都非常有用。
    • 在 Mac/Unix 下使用 pip 安装:$ sudo pip install -U nltk.
  • stop_words,一个包含停用词的 Python 包。
    • 在 Mac/Unix 下使用 pip 安装:$ sudo pip install stop-words.
  • gensim,包含我们要用到的 LDA 模型的一个主题模型包。 
    • 在 Mac/Unix 下使用 pip 安装:$ sudo pip install gensim.

导入文档

这是我们的文档用例:

doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
doc_e = "Health professionals say that brocolli is good for your health."

# compile sample documents into a list
doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]  

清洗文档

数据清洗对于生成一个有效的主题模型是极其极其重要的:俗话说,“输入的是垃圾,得到的一定也是垃圾”(Garbage in, garbarge out.)。下面的步骤就是自然语言处理的常见方法:

  • 分词:将文档转化为其原子元素。
  • 停用词处理:移除无意义的词。
  • 词干提取:将同义词合并。

分词

分词即将一个文档分成其原子元素。在这个例子中,我们将其分为单词。分词有很多种方法,我们用的是 NLTK 的 tokenize.regexp 模块:

from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'\w+') 

上面的代码会匹配所有单字字符,直到其遇到像空格这样的非单字的字符。这是个很简单的方法,但是会出现一些问题,比如像“don't”这样的单词就会被分成两个词“don”和“t“。NLTK 提供了很多像 nltk.tokenize.simple 这样的预留的特定结构的词。对于特殊用例,最好还是用 regex 和不断的迭代来使你的文档精确地分词。

注意:这个例子是对单个文档调用 tokenize()。你需要创建一个 for 循环来遍历所有文档。用下面这个脚本做个示例。

raw = doc_a.lower()
tokens = tokenizer.tokenize(raw)

>>> print(tokens)
['brocolli', 'is', 'good', 'to', 'eat', 'my', 'brother', 'likes', 'to', 'eat', 'good', 'brocolli', 'but', 'not', 'my', 'mother'] 

文档 doc_a 现在就是一个词的列表了。

停用词

英语中的一些特定组成部分,比如“for”,“or”这样的连词,或是“the”这种词对主题模型毫无意义。这些词叫做停用词,需要从我们的单词列表中移除。

停用词的定义是非常灵活的,在不同种类的文档中对应的停用词的含义是不同的。比如,如果我们要为一系列音乐评论做主题模型,那像“The Who”(英国的一支摇滚乐队)这种词就会有点麻烦,因为“the”通常都会作为一个常见的停用词而被移除。你可以根据实际情况来创建自己的停用词列表,或者用其他的包。

在我们的例子中,我们使用 Pypi 的 stop_words 包,这是一个相对比较保守的列表。我们可以调用 get_stop_words() 来创建一个停用词列表:

from stop_words import get_stop_words

# create English stop words list
en_stop = get_stop_words('en') 

现在,移除停用词只是一个循环遍历我们的单词的工作了,将每一个词都和 en_list 列表作比较。

# remove stop words from tokens
stopped_tokens = [i for i in tokens if not i in en_stop]

>>> print(stopped_tokens)
['brocolli', 'good', 'eat', 'brother', 'likes', 'eat', 'good', 'brocolli', 'mother'] 

词干提取

词干提取是 NLP 的另一个常见技术,它用于将相似的单词去除词缀得到词根。例如:“stemming”,“stemmer”,“stemmed”都有相似的意思;词干提取就是去除这些词的词缀而得到词根“stem”。这对主题模型来说很重要,否则如果将这些单词看做不同的实体,会降低他们在模型中的重要程度。

和停用词一样,词干提取也是非常灵活的,有些方法在特定的情形下可能会出问题。Porter stemming algorithm 是使用最广泛的方法。我们从 NLTK 中引入 Porter Stemmer 模块来实现这个算法:

from nltk.stem.porter import PorterStemmer

# Create p_stemmer of class PorterStemmer
p_stemmer = PorterStemmer() 
注意,p_stemmer 要求所有单词的类型都是 str。p_stemmer 以词干的形式返回字符串参数。

# stem token
texts = [p_stemmer.stem(i) for i in stopped_tokens]

>>> print(stemmed_tokens)
['brocolli', 'good', 'eat', 'brother', 'like', 'eat', 'good', 'brocolli', 'mother'] 

构建 document-term matrix

(译注:document-term matrix 是一个描述文档词频的矩阵,每一行对应文档集中的一篇文档,每一列对应一个单词,这个矩阵可以根据实际情况,采用不同的统计方法来构建。)

清洗阶段的结果就是文本(texts),从单个的文档中整理出来的分好词,去除了停用词而且提取了词干的单词列表。假设我们已经循环遍历了所有文档,将每份文档都整理成为了文本。现在,文本就是一个(单词)列表的列表了,每个单词列表就代表一份原文档。

要生成一个 LDA model,我们需要知道每个词在文档中出现的频繁程度。为此我们需要用到一个叫 gensim 的包来构建 document-term matrix:

from gensim import corpora, models

dictionary = corpora.Dictionary(texts) 

Dictionary() 方法遍历所有的文本,为每个不重复的单词分配一个单独的整数 ID,同时收集该单词出现次数以及相关的统计信息。试试用 print(dictionary.token2id) 来查看每个单词的id。

接下来,我们要将 dictionary 转化为一个词袋:

doc2bow() 方法将 dictionary 转化为一个词袋。得到的结果 corpus 是一个向量的列表,向量的个数就是文档数。在每个文档向量中都包含一系列元组。举个例子,print(corpus[0]) 结果如下:

>>> print(corpus[0])
[(0, 2), (1, 1), (2, 2), (3, 2), (4, 1), (5, 1)] 

这个元组列表代表我们的第一个文档 doc_a。元组的形式是(单词 ID,词频)。所以如果 print(dictionary.roken2id) 显示 brocolli 的 id 是 0,那么第一个元组就代表 brocolli 这个词在 doc_a 里出现了两次。只有在文档中出现过的词才会包含在 doc2bow() 中,否则它将不会出现在文档向量之中。

应用 LDA 模型

corpus 是一个 document-term matrix,现在,我们已经为生成一个 LDA 模型做好准备了:

ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=3, id2word = dictionary, passes=20) 

LdaModel 类的详细描述可以在 gensim 文档中查看。我们的实例中用到的参数:

参数:

  • num_topics: 必须。LDA 模型要求用户决定应该生成多少个主题。由于我们的文档集很小,所以我们只生成三个主题。
  • id2word:必须。LdaModel 类要求我们之前的 dictionary 把 id 都映射成为字符串。
  • passes:可选。模型遍历语料库的次数。遍历的次数越多,模型越精确。但是对于非常大的语料库,遍历太多次会花费很长的时间。

检查结果

我们的 LDA 模型已经用 ldamodel 储存好了。我们可以用 print_topic 和 print_topics 方法来查看主题:

>>> print(ldamodel.print_topics(num_topics=3, num_words=3))
['0.141*health + 0.080*brocolli + 0.080*good', '0.060*eat + 0.060*drive + 0.060*brother', '0.059*pressur + 0.059*mother + 0.059*brother'] 

这是什么意思呢?每一个生成的主题都用逗号分隔开。每个主题当中有三个该主题当中最可能出现的单词。即使我们的文档集很小,这个模型依旧是很可靠的。还有一些需要我们考虑的问题:

- health, brocolli 和 good 在一起时有很好的含义。

- 第二个主题有点让人疑惑,如果我们重新查看源文档,可以看到 drive 有很多种含义:driving a car 意思是开车,driving oneself to improve 是激励自己进步。这是我们在结果中需要注意的地方。

- 第三个主题包含 mother 和 brother,这很合理。

调整模型的主题数和遍历次数对于得到一个好的结果是很重要的。两个主题看起来更适合我们的文档。

ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=2, id2word = dictionary, passes=20)

>>> print(ldamodel.print_topics(num_topics=2, num_words=4))
['0.054*pressur + 0.054*drive + 0.054*brother + 0.054*mother', '0.070*brocolli + 0.070*good + 0.070*health + 0.050*eat'] 

LDA 到底做了什么?

这个解释有点长,但是对于理解我们千辛万苦生成的模型非常有帮助。

LDA 假定文档是从主题的混合生成的。这些主题又是由一些单词的特定概率分布而生成的。就像我们演练的模型一样。换句话说,LDA 假定文档以以下步骤生成:

  1. 确定一个文档中的单词数。假设我们的文档有六个单词。 
  2. 确定该文档由哪些主题混合而来,例如,这个文档包含 1/2 的“健康”(health)主题和 1/2 的“蔬菜”(vegetables)主题。
  3. 用每个主题的多项分布生成的单词来填充文档中的单词槽。在我们的例子中,“健康”主题占文档的 1/2,或者说占三个词。“健康”主题有“diet”这个词的可能性是 20%,或者有“execise" 这个词的概率是 15%,单词槽就是基于这些概率来填充的。

基于文档如何生成的假定,LDA 反其道而行之,并尝试找出最初哪些主题会创建这些文档。

完整代码

from nltk.tokenize import RegexpTokenizer
from stop_words import get_stop_words
from nltk.stem.porter import PorterStemmer
from gensim import corpora, models
import gensim

tokenizer = RegexpTokenizer(r'\w+')

# create English stop words list
en_stop = get_stop_words('en')

# Create p_stemmer of class PorterStemmer
p_stemmer = PorterStemmer()
    
# create sample documents
doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
doc_e = "Health professionals say that brocolli is good for your health." 

# compile sample documents into a list
doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]

# list for tokenized documents in loop
texts = []

# loop through document list
for i in doc_set:
    
    # clean and tokenize document string
    raw = i.lower()
    tokens = tokenizer.tokenize(raw)

    # remove stop words from tokens
    stopped_tokens = [i for i in tokens if not i in en_stop]
    
    # stem tokens
    stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]
    
    # add tokens to list
    texts.append(stemmed_tokens)

# turn our tokenized documents into a id <-> term dictionary
dictionary = corpora.Dictionary(texts)
    
# convert tokenized documents into a document-term matrix
corpus = [dictionary.doc2bow(text) for text in texts]

# generate LDA model
ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=2, id2word = dictionary, passes=20)​ 


关于 LDA 原理的更多分析,推荐两份资料《LDA 数学八卦》和《LDA 漫游指南》。

LDA(线性判别分析(普通法))详解 —— matlab 前言 正题 1.LDA的思想 2. 瑞利商(Rayleigh quotient)与广义瑞利商(genralized Rayleigh quotient) 3. 二类LDA原理 4.多类LDA原理 5.LDA算法流程 二类LDA matlab举例: 1.读取数据集 2.分离数据集 3.求解w 4.输出降维后的数据集 阅读详情

相关推荐

词典构造方法之LDA主题模型

词典构造方法之LDA主题模型 主题模型LDA原理理解 LDA是一种非监督学习技术,可以用来识别大规模文档集(document collection)或语料库(corpus)中潜藏的主题信息。它采用了词袋(bag of words)的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。但是词袋方法没有考虑词与词之间的顺序,这简化了问题,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。 举例来说,假设

KaikebaAI的博客 2568

LDA主题模型及Python实现

LDA(Latent Dirichlet Allocation)是一个三层贝叶斯概率模型,包括词、主题和文档三个层次。它可以将文档集中每篇文档的主题以概率分布的形式给出,从而通过分析一些文档抽取出它们的主题(分布)出来后,便可以根据主题(分布)进行主题聚类或文本分类。同时,它是一种典型的词袋模型,即一篇文档是由一组词构成,词与词之间没有先后顺序的关系。

qq_36128101的博客 1万+

Python手写实现LDA与QDA算法

近期实验室在上一门机器学习的讨论班,第一次作业中有一道题要求实现LDA算法与QDA算法,这里LDA部分参考了以下文章与教材,详细的推导在下面的文章里也有介绍: 机器学习算法推导&手写实现03——线性判别分析 《The Elements of Statistical Learning 》 QDA部分则是由LDA部分改装成的。LDA与QDA的区别就在于LDA的判别函数值为: δk(x)=xTΣ−1μk−12μkTΣ−1μk+log⁡πk.\delta_k(x) = x^T\Sigma^{-1}\mu

qq_39051660的博客 3076

lda模型的python实现

LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,最近看了点资料,准备使用python实现一下。至于数学模型相关知识,某度一大堆,这里也给出之前参考过的一个挺详细的文档lda算法漫游指南这篇博文只讲算法的sampling方法python实现。完整实现项目开源python-LDA   lda模型变量申请及初始化 # #伪代码 # 输

小清新的技术缘的博客 7521

大佬整理出来的干货:LDA模型实现—Python文本挖掘

前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http://t.cn/A6Zvjdun 1、简介 在机器学习领域,LDA是两个常用模型的简称:Linear Discriminant Analysis和Latent Dirichlet All...

qq_46614154的博客 4603

LDA主题模型Python实现

如果你有一个文本文件,那么以下这段代码可以帮助你实现LDA主题模型。大家可以根据自己不同的需求进行自定义修改,模型主体是不变的。运行过后,你可以得到一个html文件,如下所示。

m0_73963149的博客 1579

python实现LDA主题建模

本文详细介绍了如何使用Python实现LDA主题建模。LDA是一种用于主题建模的概率图模型,其基本思想是:每个文档是由一组主题混合而成的,每个主题又由一组词汇构成,而LDA试图找到最佳的主题和词汇组合,以解释给定的文本数据。

2301_79959211的博客 2285

『LDA主题模型』用Python实现主题模型LDA

用Python gensim包实现主题模型LDA。最后打印出文档-主题分布以及主题-词分布。

酒狂的博客 9083

【机器学习】python实现LDA多类问题

【机器学习】python实现LDA多类问题1.读取数据集2.进行LDA特征提取    2.1 将样本分类关于LDA的原理已经在之前讲过了,详情可戳:【机器学习】LDA线性判别分析本节主要用python实现LDA推广到多类的问题。【注意】本文的运行环境是windows+Pycharm+python3.6。【参考】线性判别分析(LDA)和python实现(多分类问题)https://blog.csdn...

gogo小Sa的专栏 6232

Python实现LDA模型

潜在狄利克雷分配(LDA,Latent Dirichlet Allocation)是一种非常流行的主题模型,它可以对文本进行主题建模。本文将介绍如何使用Python实现LDA模型,并附上相应的源代码。gensim提供了一个叫做Corpora的模块,可以很方便地构建文档-单词矩阵。本文介绍了如何使用Python实现LDA模型,并给出了相应的源代码。通过这篇文章的学习,读者可以进一步加深对LDA模型的理解,并在实际应用中进行使用。首先,我们需要对数据进行预处理。最后,我们可以使用LDA模型进行主题建模了。

. 1348

主题模型LDA的优缺点及Python实现

总结来说,LDA是一种强大的主题模型,可以用于文本数据的语义分析、特征提取和主题发现等任务。但需要注意的是,LDA是一种无监督学习方法,需要预先设定主题数量,并且忽略了单词之间的顺序和上下文信息。在实际应用中,我们需要结合具体任务和数据的特点,综合考虑LDA的优缺点,来选择合适的主题模型或者结合其他技术手段来提高模型的性能。:LDA可以将文本数据转化为主题-词分布和文档-主题分布,从而提取文本的关键特征。通过分析主题分布,我们可以发现文本背后的潜在主题结构,揭示文本的深层含义。下面是使用Python中的。

HackSquad的博客 1573

Fisher线性判别(LDA)python实现

LDA概述 首先,LDA是一个用于分类的有监督算法。 基本想法非常质朴,不失一般性的以二维平面二分类为例: 对于两类样本点,我们的目的是想找一条直线,将两类样本点映射到这条直线上时,使这两类之间的类间间距最大,类内间距最小。 图形上的直观理解如下。 对于第一张图,不同类映射到同一条直线上时出现混叠区域,难以判别类别。 对于第二张图,不同类映射到同一条直线上时没有混叠,分界鲜明(类间间距最大),且同...

weixin_42698229的博客 3869

Python实现LDA模型的完美指南

本文还有配套的精品资源,点击获取 简介:本资源详细介绍了如何使用Python中的Gensim库实现LDA(隐含狄利克雷分布)模型,这是一种广泛应用于文本挖掘的主题模型。LDA模型能够揭示文档集合中的隐含主题结构。资源包括文本预处理、向量化方法选择、模型构建、训练和结果分析等步骤,并探讨了如何将LDA应用于文本分类、推荐系统和搜索引擎改进等实际问题。学习此课程设计,你将掌握L...

weixin_31749299的博客 6061

基于LDA的文本主题聚类Python实现

LDA简介 LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,也称为一个三层贝叶斯概率模型,包含词、主题和文档三层结构。所谓生成模型,就是说,我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。文档到主题服从多项式分布,主题到词服从多项式分布。 LDA是一种非监督机器学习技术,可以用来识别大规模...

徐奕的专栏 1万+

掌握Python中LDA算法的实现和应用

主题模型是一种统计模型,用于从文档集合中发现主题信息。LDA,即隐含狄利克雷分布(Latent Dirichlet Allocation),是其中一种最常用的非监督机器学习算法。它通过分析文档中词语的分布,假设每个文档是由一系列主题的混合构成,而每个主题又是由一定比例的词语组成。这种算法在自然语言处理领域有着广泛的应用,如文本聚类、信息检索、推荐系统等。LDA算法的核心是将文档-词语矩阵转化为文档-主题和主题-词语两个概率分布,这两个分布是模型的两个隐藏层。

weixin_35756624的博客 1100

Python中LDA主题模型的实现与应用

LDA,即隐狄利克雷分布(Latent Dirichlet Allocation),是一种文档主题生成模型,由David Blei等人在2003年提出。LDA模型假设文档是由一系列主题构成,而每个主题又是由一系列词项以某种概率分布生成的。通过统计分析文档集合,LDA能够揭示隐藏在文本中的主题结构,对于理解大量文本内容的主题分布具有重要意义。Python作为一种强大的编程语言,在数据分析和机器学习领域广受欢迎。

weixin_34392511的博客 1098

python实现lda聚类_LDA主题模型原理解析与python实现

#-*- coding:utf-8 -*-import loggingimport logging.configimport ConfigParserimport numpy as npimport randomimport codecsimport osfrom collections import OrderedDict#获取当前路径path = os.getcwd()#导入日志配置文件log...

weixin_39884144的博客 1532

通达信浮筹多空波段抓牛擒龙指标公式源码

VAR33:=VA3>=REF(VA4,1) AND C<REF(C,1) AND VAR19=60 AND VAR18=0 AND 活跃线>=REF(活跃线,1) AND VA12<REF(VA13,1);DRAWTEXT(VAR28 AND COUNT(VAR28,30)=1,65,' ★超涨注意风险'),COLOR0000FF;DRAWTEXT(VAR26 AND COUNT(VAR26,30)=1,90,' ←继续等'),COLOR00FFFF;浮筹线:VA3,COLORFF00FF;

2401_86043146的博客 5260

LDA的Python实现代码介绍

LDA的Python实现代码介绍 去发现同类优质开源项目:https://gitcode.com/ 本文档提供了LDA(隐狄利克雷分布)模型的Python实现代码,旨在帮助LDA初学者学习和参考。通过这个资源,您可以了解到LDA模型的基本概念及其在Python中的实现方法。 资源简介 此代码适用于刚接触LDA模型的用户,希望能对大家的学术研究和实际应用提供一定的帮助。代码的结构清晰,注释详细,便于...

gitblog_06788的博客 319

电子产品设计中EFT防护的关键技术与实践

本文深入探讨了电子产品设计中EFT(快速瞬变脉冲群)防护的关键技术与实践。文章从EFT干扰的原理入手,系统阐述了通过优化PCB布局与地平面设计、构建电源与信号端口滤波防护电路、精选核心器件以及实施软件容错策略,来构建多层次、系统性的抗干扰防线,助力产品稳定通过严苛的电磁兼容测试。

e4f5g6h的博客 786

高效利用ChEMBL数据库:从靶点查询到活性数据处理的完整指南

本文提供了高效利用ChEMBL数据库的完整指南,从靶点查询到活性数据处理。详细介绍了靶点精准定位、高级过滤技巧、数据导出优化以及活性数据清洗、特征工程和可视化等实战技巧,帮助药物研发人员快速获取和处理生物活性数据,提升工作效率。

weixin_29278805的博客 792
上一篇: 常见分类方法
下一篇: Python 编程小问题汇总(一)
zhurouwan
博客等级 码龄10年 70粉丝 7原创
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值