机器学习NLP:在几分钟内使用LDA从数据集中提取主要主题
我最近开始学习关于主题建模的Latent Dirichlet Allocation(LDA),并且惊讶于它有多强大并且同时快速运行。主题建模是使用机器学习无监督学习来提取文档集合中出现的主要主题(表示为一组单词)的任务。
我在20个新闻组数据集上测试了该算法,该数据集包含来自新闻报道的许多部分的数千条新闻文章。在这个数据集中,我事先了解了主要新闻主题,并且可以验证LDA是否正确识别它们。
关于LDA
LDA用于将文档中的文本分类为特定主题。它构建了每个文档模型的主题和每个主题模型的单词,建模为Dirichlet分布。
每个文档都被建模为主题的多项分布,每个主题被建模为单词的多项分布。
LDA假设我们输入的每一段文本都包含与某种程度相关的单词。因此,选择正确的数据语料库至关重要。
它还假设文档是由多个主题组合而成。然后,这些主题基于其概率分布生成单词。
数据集
我使用的数据集是20Newsgroup数据集。它可以在sklearn数据集下使用,并且可以轻松下载,Python代码如下:
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset=’train’, shuffle = True)
newsgroups_test = fetch_20newsgroups(subset=’test’, shuffle = True)
这个数据集已经将新闻分类为关键主题
print(list(newsgroups_train.target_names))
数据集中有20个目标
‘alt.atheism’,
‘comp.graphics’,
‘comp.os.ms-windows.misc’,
‘comp.sys.ibm.pc.hardware’,
‘comp.sys.mac.hardware’,
‘comp.windows.x’,
‘misc.forsale’,
‘rec.autos’,
‘rec.motorcycles’,
‘rec.sport.baseball’,
‘rec.sport.hockey’,
‘sci.crypt’,
‘sci.electronics’,
‘sci.med’,
‘sci.space’,
‘soc.religion.christian’,
‘talk.politics.guns’,
‘talk.politics.mideast’,
‘talk.politics.misc’,
‘talk.religion.misc
从视觉上看,我们可以说这个数据集有一些广泛的主题,如:
- Science
- Politics
- Sports
- Religion
- Technology etc
在Python中使用LDA提取主题
1.预处理原始文本
这涉及以下内容:
- 标记化:将文本拆分为句子,将句子拆分为单词。将单词小写,并删除标点符号。
- 删除少于3个字符的单词。
- 删除所有stopwords。
- 词被词形化 - 第三人称的词被改为第一人称,过去和未来时态的动词被改为现在。
- 单词被简化为它们的根形式。
我们使用NLTK和gensim库来执行预处理,Python代码如下:
def lemmatize_stemming(text):
return stemmer.stem(WordNetLemmatizer().lemmatize(text, pos='v'))
# Tokenize and lemmatize
def preprocess(text):
result=[]
for token in gensim.utils.simple_preprocess(text) :
if token not in gensim.parsing.preprocessing.STOPWORDS and len(token) > 3:
result.append(lemmatize_stemming(token))
return result
生成的文本如下所示:
Original document:
['This', 'disk', 'has', 'failed', 'many', 'times.', 'I', 'would', 'like', 'to', 'get', 'it', 'replaced.']
Tokenized and lemmatized document:
['disk', 'fail', 'time', 'like', 'replac']
2.将文本转换为单词包 bag of words
在进行主题建模之前,我们将标记化和词形化的文本转换为bag of words——您可以将其看作是一个字典,其中键是单词,值是单词在整个语料库中出现的次数。
dictionary = gensim.corpora.Dictionary(processed_docs)
我们可以进一步过滤出现次数很少或频繁出现的单词。
现在,对于每个预处理文档,我们使用刚刚创建的dictionary对象将文档转换为bag of words。即对于每个文档,我们创建一个字典来报告有多少单词以及这些单词出现了多少次。
bow_corpus = [dictionary.doc2bow(doc) for doc in processed_docs]
结果如下
Word 453 ("exampl") appears 1 time.
Word 476 ("jew") appears 1 time.
Word 480 ("lead") appears 1 time.
Word 482 ("littl") appears 3 time.
Word 520 ("wors") appears 2 time.
Word 721 ("keith") appears 3 time.
Word 732 ("punish") appears 1 time.
Word 803 ("california") appears 1 time.
Word 859 ("institut") appears 1 time.
3.运行LDA
这实际上非常简单,因为我们可以使用gensim LDA模型。我们需要指定数据集中有多少主题。让我们说我们从8个独特的主题开始。
lda_model = gensim.models.LdaMulticore(bow_corpus,
num_topics = 8,
id2word = dictionary,
passes = 10,
workers = 2)
结果
该模型已建成。现在让我们解释它,看看结果是否有意义。
模型的输出是8个主题,每个主题按一系列单词分类。
Topic 1: Possibly Graphics Cards
Words: "drive" , "sale" , "driver" , *"wire" , "card" , "graphic" , "price" , "appl" ,"softwar", "monitor"
Topic 2: Possibly Space
Words: "space","nasa" , "drive" , "scsi" , "orbit" , "launch" ,"data" ,"control" , "earth" ,"moon"
Topic 3: Possibly Sports
Words: "game" , "team" , "play" , "player" , "hockey" , season" , "pitt" , "score" , "leagu" , "pittsburgh"
Topic 4: Possibly Politics
Words: "armenian" , "public" , "govern" , "turkish", "columbia" , "nation", "presid" , "turk" , "american", "group"
Topic 5: Possibly Gun Violence
Words: "kill" , "bike", "live" , "leav" , "weapon" , "happen" , *"gun", "crime" , "car" , "hand"