主题建模是一种常用的技术,主要用于将文本数据中的每个文档归类到一个或多个主题之下,这一过程通常不需要监督(即无需人工标注)。例如,可以将文档分为政治、体育、金融等主题。如果每个文档只分配一个主题,这实际上是一个文档分类任务。
在主题建模中,隐含狄利克雷分布(LDA)是最常用的分解方法之一。LDA模型试图找出频繁共现的单词组合,从而识别出主题。LDA认为每个文档都是若干主题的混合,但这里的主题与日常生活中所理解的主题有所不同,而是机器学习领域中的抽象概念。
我们应用LDA算法对电影评论数据集进行了处理,以展示其实际效果。在无监督文档模型中,去除那些出现在大量文档中的常见词汇是很重要的,因为这些词汇可能会主导分析结果。因此,我们删除了至少在15%的文档中出现的词汇,并保留了最常见的10000个词汇。以下是部分相关代码:
```python from sklearn.modelselection import GridSearchCV from sklearn.featureextraction.text import CountVectorizer
reviewstrain = loadfiles("D:/MovieDatabase/aclImdb/train") texttrain, ytrain = reviewstrain.data, reviewstrain.target
texttrain = [doc.replace(b"n", b" ") for doc in texttrain]
print("Samples per class (training): {}".format(np.bincount(y_train)))
reviewstest = loadfiles("D:/MovieDatabase/aclImdb/test") texttest, ytest = reviewstest.data, reviewstest.target
vect = CountVectorizer(maxfeatures=10000, maxdf=.15) vect.fit(texttrain) x = vect.transform(texttrain)
lda = LatentDirichletAllocation(ncomponents=10, learningmethod="batch", maxiter=25, randomstate=0) documenttopics = lda.fittransform(x)
print("主题个数和特征个数: {}".format(lda.components_.shape)) ```
通过运行上述代码,我们得到了一些初步结果,包括各类样本数量以及主题数量和特征数量。接下来,为了更好地理解这些主题的具体含义,我们查看了每个主题中最重要的词汇。以下是部分重要词汇:
```python import numpy as np from mglearn.tools import print_topics
featurenames = np.array(vect.getfeaturenames()) sorting = np.argsort(lda.components, axis=1)[:, ::-1]
mglearn.tools.printtopics(topics=range(10), featurenames=featurenames, sorting=sorting, topicsperchunk=5, nwords=10) ```
结果显示,某些主题可能与历史和平有关,另一些则可能涉及悲剧等话题。为了进一步细化分析,我们尝试使用更多主题,即100个主题,这样虽然分析会更加复杂,但也能使每个主题更具体地针对某一数据子集:
```python lda100 = LatentDirichletAllocation(ncomponents=100, learningmethod="batch", maxiter=25, randomstate=0) documenttopics100 = lda100.fittransform(x) sorting = np.argsort(lda100.components_, axis=1)[:, ::-1]
topics = np.array([9, 19, 29, 39, 49, 59, 69, 79, 89, 99]) mglearn.tools.printtopics(topics=topics, featurenames=featurenames, sorting=sorting, topicsperchunk=10, nwords=20) ```
此外,如果我们想单独查看某个特定主题,例如主题49,可以通过以下方式实现:
```python title49 = np.argsort(documenttopics100[:, 49])[::-1]
for i in title49[:10]: # 显示前两个句子 print(b".".join(texttrain[i].split(b".")[:2]) + b".n") ```
尽管LDA算法具有随机性,每次运行可能产生不同结果,但它依然是一个非常有用的工具,可以帮助我们从大量文本数据中提取有意义的主题。