GENSIM官方文档(4.0.0beta最新版)-LDA模型评价与可视化
译文目录
GENSIM官方文档(4.0.0beta最新版)-面向新手的核心教程
GENSIM官方教程(4.0.0beta最新版)-LDA模型
GENSIM官方教程(4.0.0beta最新版)-Word2Vec词向量模型
GENSIM官方教程(4.0.0beta最新版)-LDA模型评价与可视化
博主全天在线,欢迎评论或私信讨论NLP相关问题
一、载入数据集并进行分词等预处理操作
from string import punctuation
from nltk import RegexpTokenizer
from nltk.stem.porter import PorterStemmer
from nltk.corpus import stopwords
from sklearn.datasets import fetch_20newsgroups
newsgroups = fetch_20newsgroups()
eng_stopwords = set(stopwords.words('english'))
tokenizer = RegexpTokenizer(r'\s+', gaps=True)
stemmer = PorterStemmer()
translate_tab = {ord(p): u" " for p in punctuation}
def text2tokens(raw_text):
"""分词"""
clean_text = raw_text.lower().translate(translate_tab)
tokens = [token.strip() for token in tokenizer.tokenize(clean_text)]
tokens = [token for token in tokens if token not in eng_stopwords]
stemmed_tokens = [stemmer.stem(token) for token in tokens]
return [token for token in stemmed_tokens if len(token) > 2] # skip short tokens
dataset = [text2tokens(txt) for txt in newsgroups['data']] # 用列表存储语料集
from gensim.corpora import Dictionary
dictionary = Dictionary(documents=dataset, prune_at=None)
dictionary.filter_extremes(no_below=5, no_above=0.3, keep_n=None) # 用 Dictionary 做数据清理
dictionary.compactify()
d2b_dataset = [dictionary.doc2bow(doc) for doc in dataset] # 转化成词袋模型
二、训练两个LDA模型
from gensim.models import LdaMulticore
num_topics = 15
lda_fst = LdaMulticore(
corpus=d2b_dataset, num_topics=num_topics, id2word=dictionary,
workers=4, eval_every=None, passes=10, batch=True,
)
lda_snd = LdaMulticore(
corpus=d2b_dataset, num_topics=num_topics, id2word=dictionary,
workers=4, eval_every=None, passes=20, batch=True,
)
三、可视化两个模型并比较
我们使用两种略有不同的可视化方法。如果您通过Jupyter notebook运行,则将获得一个不错的交互式Plotly热图。没Jupyter notebook也可以通过matplotlib获得热度图,但不能互动了。
(译者注:pip install dash来安装plotly)
def plot_difference_plotly(mdiff, title="", annotation=None):
"""用plotly可视化两个模型的不同点"""
import plotly.graph_objs as go
import plotly.offline as py
annotation_html = None
if annotation is not None:
annotation_html = [
[
"+++ {}<br>--- {}".format(", ".join(int_tokens), ", ".join(diff_tokens))
for (int_tokens, diff_tokens) in row
]
for row in annotation
]
data = go.Heatmap(z=mdiff, colorscale='RdBu', text=annotation_html)
layout = go.Layout(width=950, height=950, title=title, xaxis=dict(title="topic"), yaxis=dict(title="topic"))
py.iplot(dict(data=[data], layout=layout))
def plot_difference_matplotlib(mdiff, title="", annotation=None):
"""用matplotlib可视化两个模型的不同点"""
Uses matplotlib as the backend."""
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(18, 14))
data = ax.imshow(mdiff, cmap='RdBu_r', origin='lower')
plt.title(title)
plt.colorbar(data)
try:
get_ipython()
import plotly.offline as py
except Exception:
#
# 用不了plotly就用matplotlib
#
plot_difference = plot_difference_matplotlib
else:
py.init_notebook_mode()
plot_difference = plot_difference_plotly
Gensim可以帮助您可视化主题之间的差异。为此,可以使用LDA模型的diff() 方法。
diff() 返回距离矩阵mdiff和带有注释的矩阵annotation。
mdiff[i][j]指的是第一个模型产生的主题i和第二个模型产生的主题j之间的距离
annotation[i][j]指的是第一个模型产生的主题i和第二个模型产生的主题j之间最一致的词和最不一致的词。
案例一:可视化一个模型的主题之间的关联性
图例:
- X轴和y轴都代表主题
- 格子越红代表主题间差异越大
- 格子越蓝代表主题间差异越小
在理想的情况中,我们希望看到彼此之间相互关联的不同主题。在这种情况下,我们的矩阵如下所示:
import numpy as np
mdiff = np.ones((num_topics, num_topics))
np.fill_diagonal(mdiff, 0.)
plot_difference(mdiff, title="Topic difference (one model) in ideal world")
然而事实上矩阵可能很不一样。
mdiff, annotation = lda_fst.diff(lda_fst, distance='jaccard', num_words=50)
plot_difference(mdiff, title="Topic difference (one model) [jaccard distance]", annotation=annotation)
如果将模型与自身进行比较,则希望看到尽可能多的红色元素(对角线除外)。有了这张图片,您可以了解模型中哪些主题非常相似以及原因(如果将指针移至单元格,则可以阅读注释)。
杰卡德函数(Jaccard)是稳定且鲁棒的距离函数,但有时不够灵敏。让我们尝试使用海林格(Hellinger)距离。
mdiff, annotation = lda_fst.diff(lda_fst, distance='hellinger', num_words=50)
plot_difference(mdiff, title="Topic difference (one model)[hellinger distance]", annotation=annotation)
或许你会发现情况变糟了,但请记住好与坏不取决于这张图,而取决于你的模型要做的任务。
(译者注:
下面是我新冠舆情数据集上的聚类结果:我的轴是反的
案例二:可视化不同模型的主体之间的关联性。
有时我们需要比较不同模型所体现特征的差异性。
我们可以通过这种方式来可视化的查看。
mdiff, annotation = lda_fst.diff(lda_snd, distance='jaccard', num_words=50)
plot_difference(mdiff, title="Topic difference (two models)[jaccard distance]", annotation=annotation)
查看此矩阵,您可以在两个模型之间找到相似且不同的主题。该图还包括描述主题的交叉点和差异的相关标记。
(译者注:我反正觉得没太大实践价值,案例一或许有点用。)