首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

python主题LDA建模和t-SNE可视化

本文中的代码片段仅供您在阅读时更好地理解。有关完整的工作代码,请参阅完整资料。

我们将首先介绍主题建模和t-SNE,然后将这些技术应用于两个数据集:20个新闻组和推文。

相关视频

什么是主题建模?

主题模型是一套算法/统计模型,可以揭示文档集中的隐藏主题。文档通常涉及不同比例的多个主题,特别是在跨学科文档中(例如,60%关于生物学,25%关于统计学,15%关于计算机科学的生物信息学文章)。主题模型在数学框架中检查和发现主题可能是什么以及每个文档的主题可能性。

T-SNE

t-SNE或t分布随机邻域嵌入是用于高维数据可视化的维数降低算法。这部分是为了减轻人类不能(至少现在不能)感知超过3-D的向量空间这一事实。

这是一个降维并在三维空间中可视化的示例(信用:Google嵌入项目)

t-SNE是不确定的,其结果取决于数据批次。换句话说,相对于批次中的其他数据点,相同的高维数据点可以被转换成不同批次的不同2-D或3-D向量。

可以使用各种语言实现t-SNE,但速度可能会有所不同。

环境

15-inch MacBook Pro, macOS Sierra

2.2 GHz Intel Core i7 processor

16 GB 1600 MHz DDR3 memory

1.将10,000 x 50矩阵转换为10,000 x 2

C ++和Python

real 1m2.662s

user 1m0.575s

sys 0m1.929s

Python sklearn

real 3m29.883s

user 2m22.748s

sys 1m7.010s

2.将20,000 x 50矩阵转换为20,000 x 2

C ++和Python

real 2m40.250s

user 2m32.400s

sys 0m6.420s

Python sklearn

real 6m54.163s

user 4m17.524s

sys 2m31.693s

3.将1,000,000 x 25矩阵转换为1,000,000 x 2

C ++和Python

real 224m55.747s

user 216m21.606s

sys 8m21.412s

Python sklearn

out of memory... :(

t-SNE的作者说,他们“已经将这项技术应用于数据集,最多有3000万个例子”(尽管他没有指定数据和运行时的维度)。如果你有一个更大的数据集,你可以扩大你的硬件,调整参数(例如,sklearn的t-SNE中的angle参数),或尝试替代(如LargeVis,其作者声称“与tSNE比较,LargeVis显着降低了图形构建步骤的计算成本“。我还没有测试过它。

把它放在一起:20个新闻组的例子

在本节中,我们将在20个新闻组数据集上应用LDA算法,以发现每个文档中的基础主题,并使用t-SNE将它们显示为组。

获取数据

sklearn具有检索和过滤20个新闻组数据的功能:

from sklearn.datasets import fetch_20newsgroups

remove = ('headers', 'footers', 'quotes')

newsgroups\_train = fetch\_20newsgroups(subset ='train', remove =remove)

newsgroups\_test = fetch\_20newsgroups(subset ='test', remove =remove)

news = \[' ' .join(filter(unicode .isalpha, raw .lower() .split())) for raw in

newsgroups\_train .data + newsgroups\_test .data\]LDA模型

在我们获得清理后的数据后,我们可以对数据进行矢量化并训练LDA模型:

import lda

from sklearn.feature_extraction.text import CountVectorizer

n_topics = 20 # 主题数目

n_iter = 500 # 循环次数

cvectorizer = CountVectorizer(min\_df =5, stop\_words ='english')

cvz = cvectorizer .fit_transform(news)

lda\_model = lda .LDA(n\_topics =n\_topics, n\_iter =n_iter)

X\_topics = lda\_model .fit_transform(cvz)

其中X\_topics是18,846(num\_news)乘20(n\_topics)矩阵。注意,我们在这里有一个很好的概率解释:每一行是属于某个主题的这个新闻的概率分布(由我们的LDA模型学习)(例如,X\_topics[0][0]代表属于主题1的第一个新闻的可能性)。

用t-SNE减少到2-D

我们有一个学习过的LDA模型。但我们无法直观地检查我们的模型有多好。t-SNE来分析:

from sklearn.manifold import TSNE

tsne\_model = TSNE(n\_components =2, verbose =1, random_state =0, angle =.99, init='pca')

# 20-D -> 2-D

tsne\_lda = tsne\_model .fit\_transform(X\_topics)可视化组及其关键字

现在,我们已准备好使用流行的Python可视化库来可视化新闻组和关键字。

首先我们做一些设置工作(导入类和函数,设置参数等):

import numpy as np

import bokeh.plotting as bp

from bokeh.plotting import save

from bokeh.models import HoverTool

n\_top\_words = 5

colormap = np .array(\[

"#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c",

"#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5",

"#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f",

"#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5"

\])

然后我们找到每个新闻最可能的主题:

\_lda\_keys = \[\]

for i in xrange(X_topics .shape\[0\]):

\_lda\_keys += _topics\[i\] .argmax(),

并获得每个主题的顶级单词:

topic_summaries = \[\]

topic\_word = lda\_model .topic\_word\_ # 所有主题关键词

vocab = cvectorizer .get\_feature\_names()

for i, topic\_dist in enumerate(topic\_word):

topic\_words = np .array(vocab)\[np .argsort(topic\_dist)\]\[: -(n\_top\_words + 1): -1\] # 获得数据

topic\_summaries .append(' ' .join(topic\_words)) # 加到单词列表

我们绘制新闻(每个点代表一个新闻):

title = '20 newsgroups LDA viz'

num\_example = len(X\_topics)

plot\_lda = bp .figure(plot\_width =1400, plot_height =1100,

title =title,

tools ="pan,wheel\_zoom,box\_zoom,reset,hover,previewsave",

x\_axis\_type =None, y\_axis\_type =None, min_border =1)

plot\_lda .scatter(x =tsne\_lda\[:, 0\], y =tsne_lda\[:, 1\],

color =colormap\[\_lda\_keys\]\[:num_example\],

source =bp .ColumnDataSource({

"content": news\[:num_example\],

"topic\_key": \_lda\_keys\[:num\_example\]

}))

#绘制每个主题的关键词:

topic\_coord = np .empty((X\_topics .shape\[1\], 2)) * np .nan

for topic\_num in \_lda_keys:

if not np .isnan(topic_coord) .any():

break

topic\_coord\[topic\_num\] = tsne\_lda\[\_lda\_keys .index(topic\_num)\]

for i in xrange(X_topics .shape\[1\]):

plot\_lda .text(topic\_coord\[i, 0\], topic\_coord\[i, 1\], \[topic\_summaries\[i\]\])

hover = plot_lda .select(dict(type =HoverTool))

hover .tooltips = {"content": "@content - topic: @topic_key"}

save(plot_lda, '{}.html' .format(title))

你会得到一个像这样的交互式图表:

当我们为每个文档分配一个主要主题时,有些情况最可能的主题的概率相当低(极端情况是每个主题被分配5%,即,均匀分布)。换句话说,我们的模型无法为这样的新闻分配主题。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230117A03XFF00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券