python主题建模可视化LDA和T-SNE交互式可视化

news2024/11/24 16:59:18

我尝试使用Latent Dirichlet分配LDA来提取一些主题。

最近我们被客户要求撰写关于主题建模的研究报告,包括一些图形和统计输出。 本教程以自然语言处理流程为特色,从原始数据开始,准备,建模,可视化论文。

我们将涉及以下几点

使用LDA进行主题建模
使用pyLDAvis可视化主题模型
使用t-SNE可视化LDA结果


相关视频:文本挖掘:主题模型(LDA)及R语言实现分析游记数据

文本挖掘:主题模型(LDA)及R语言实现分析游记数据

时长12:59


In [1]:

from scipy import sparse as sp
Populating the interactive namespace from numpy and matplotlib

In [2]:

docs = array(p_df['PaperText'])

 预处理和矢量化文档

In [3]:

from nltk.stem.wordnet import WordNetLemmatizer
from nltk.tokenize import RegexpTokenizer

def docs_preprocessor(docs):
    tokenizer = RegexpTokenizer(r'\w+')
    for idx in range(len(docs)):
        docs[idx] = docs[idx].lower()  # Convert to lowercase.
        docs[idx] = tokenizer.tokenize(docs[idx])  # Split into words.

    # 删除数字,但不要删除包含数字的单词。

    docs = [[token for token in doc if not token.isdigit()] for doc in docs]
    
    # 删除仅一个字符的单词。

    docs = [[token for token in doc if len(token) > 3] for doc in docs]
    
    # 使文档中的所有单词规则化

    lemmatizer = WordNetLemmatizer()
    docs = [[lemmatizer.lemmatize(token) for token in doc] for doc in docs]
  
    return docs

In [4]:

docs = docs_preprocessor(docs)

 计算双字母组/三元组:

主题非常相似,可以区分它们是短语而不是单个单词。

In [5]:

from gensim.models import Phrases
# 向文档中添加双字母组和三字母组(仅出现10次或以上的文档)。
bigram = Phrases(docs, min_count=10)
trigram = Phrases(bigram[docs])

for idx in range(len(docs)):
    for token in bigram[docs[idx]]:
        if '_' in token:
            # Token is a bigram, add to document.
            docs[idx].append(token)
    for token in trigram[docs[idx]]:
        if '_' in token:
            # token是一个二元组,添加到文档中。
            docs[idx].append(token)
Using TensorFlow backend.
/opt/conda/lib/python3.6/site-packages/gensim/models/phrases.py:316: UserWarning: For a faster implementation, use the gensim.models.phrases.Phraser class
  warnings.warn("For a faster implementation, use the gensim.models.phrases.Phraser class")

删除

In [6]:

from gensim.corpora import Dictionary

# 创建文档的字典表示

dictionary = Dictionary(docs)
print('Number of unique words in initital documents:', len(dictionary))

# 过滤掉少于10个文档或占文档20%以上的单词。

dictionary.filter_extremes(no_below=10, no_above=0.2)
print('Number of unique words after removing rare and common words:', len(dictionary))
Number of unique words in initital documents: 39534
Number of unique words after removing rare and common words: 6001

清理常见和罕见的单词,我们最终只有大约6%的词。

矢量化数据:
第一步是获得每个文档的单词表示。

In [7]:

corpus = [dictionary.doc2bow(doc) for doc in docs]

In [8]:

print('Number of unique tokens: %d' % len(dictionary))
print('Number of documents: %d' % len(corpus))
Number of unique tokens: 6001
Number of documents: 403

通过词袋语料库,我们可以继续从文档中学习我们的主题模型。

训练LDA模型 

In [9]:

from gensim.models import LdaModel

In [10]:

%time model = LdaModel(corpus=corpus, id2word=id2word, chunksize=chunksize, \
                       alpha='auto', eta='auto', \
                       iterations=iterations, num_topics=num_topics, \
                       passes=passes, eval_every=eval_every)
CPU times: user 3min 58s, sys: 348 ms, total: 3min 58s
Wall time: 3min 59s

如何选择主题数量?


LDA是一种无监督的技术,这意味着我们在运行模型之前不知道在我们的语料库中有多少主题存在。 主题连贯性是用于确定主题数量的主要技术之一。 

但是,我使用了LDA可视化工具pyLDAvis,尝试了几个主题并比较了结果。 四个似乎是最能分离主题的最佳主题数量。

In [11]:

import pyLDAvis.gensim
pyLDAvis.enable_notebook()

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) 

In [12]:

pyLDAvis.gensim.prepare(model, corpus, dictionary)

Out[12]:

我们在这看到什么?

左侧面板,标记为Intertopic Distance Map,圆圈表示不同的主题以及它们之间的距离。类似的主题看起来更近,而不同的主题更远。图中主题圆的相对大小对应于语料库中主题的相对频率。 

如何评估我们的模型? 

将每个文档分成两部分,看看分配给它们的主题是否类似。 =>越相似越好

将随机选择的文档相互比较。 =>越不相似越好

In [13]:

from sklearn.metrics.pairwise import cosine_similarity

p_df['tokenz'] = docs

docs1 = p_df['tokenz'].apply(lambda l: l[:int0(len(l)/2)])
docs2 = p_df['tokenz'].apply(lambda l: l[int0(len(l)/2):])

转换数据

In [14]:

corpus1 = [dictionary.doc2bow(doc) for doc in docs1]
corpus2 = [dictionary.doc2bow(doc) for doc in docs2]

# 使用语料库LDA模型转换


lda_corpus1 = model[corpus1]
lda_corpus2 = model[corpus2]

In [15]:

from collections import OrderedDict
def get_doc_topic_dist(model, corpus, kwords=False):
    
    '''
LDA转换,对于每个文档,仅返回权重非零的主题
此函数对主题空间中的文档进行矩阵转换
    '''
    top_dist =[]
    keys = []

    for d in corpus:
        tmp = {i:0 for i in range(num_topics)}
        tmp.update(dict(model[d]))
        vals = list(OrderedDict(tmp).values())
        top_dist += [array(vals)]
        if kwords:
            keys += [array(vals).argmax()]

    return array(top_dist), keys
Intra similarity: cosine similarity for corresponding parts of a doc(higher is better):
0.906086532099
Inter similarity: cosine similarity between random parts (lower is better):
0.846485334252

 让我们看一下每个主题中出现的单词。

In [17]:

def explore_topic(lda_model, topic_number, topn, output=True):
    """


输出topn词的列表
    """
    terms = []
    for term, frequency in lda_model.show_topic(topic_number, topn=topn):
        terms += [term]
        if output:
            print(u'{:20} {:.3f}'.format(term, round(frequency, 3)))
    
    return terms

In [18]:

term                 frequency

Topic 0 |---------------------

data_set             0.006
embedding            0.004
query                0.004
document             0.003
tensor               0.003
multi_label          0.003
graphical_model      0.003
singular_value       0.003
topic_model          0.003
margin               0.003
Topic 1 |---------------------

policy               0.007
regret               0.007
bandit               0.006
reward               0.006
active_learning      0.005
agent                0.005
vertex               0.005
item                 0.005
reward_function      0.005
submodular           0.004
Topic 2 |---------------------

convolutional        0.005
generative_model     0.005
variational_inference 0.005
recurrent            0.004
gaussian_process     0.004
fully_connected      0.004
recurrent_neural     0.004
hidden_unit          0.004
deep_learning        0.004
hidden_layer         0.004
Topic 3 |---------------------

convergence_rate     0.007
step_size            0.006
matrix_completion    0.006
rank_matrix          0.005
gradient_descent     0.005
regret               0.004
sample_complexity    0.004
strongly_convex      0.004
line_search          0.003
sample_size          0.003

 从上面可以检查每个主题并为其分配一个可解释的标签。 在这里我将它们标记如下:

In [19]:

top_labels = {0: 'Statistics', 1:'Numerical Analysis', 2:'Online Learning', 3:'Deep Learning'}

In [20]:

  '''
    # 1.删除非字母


    paper_text = re.sub("[^a-zA-Z]"," ", paper)
    # 2.将单词转换为小写并拆分


    words = paper_text.lower().split()
    # 3. 删除停用词


    words = [w for w in words if not w in stops]
    # 4. 删除短词


    words = [t for t in words if len(t) > 2]
    # 5. 形容词


    words = [nltk.stem.WordNetLemmatizer().lemmatize(t) for t in words]
In [21]:
from sklearn.feature_extraction.text import TfidfVectorizer

tvectorizer = TfidfVectorizer(input='content', analyzer = 'word', lowercase=True, stop_words='english',\
                                  tokenizer=paper_to_wordlist, ngram_range=(1, 3), min_df=40, max_df=0.20,\
                                  norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=True)

dtm = tvectorizer.fit_transform(p_df['PaperText']).toarray()

In [22]:

top_dist =[]
for d in corpus:
    tmp = {i:0 for i in range(num_topics)}
    tmp.update(dict(model[d]))
    vals = list(OrderedDict(tmp).values())
    top_dist += [array(vals)]

In [23]:

top_dist, lda_keys= get_doc_topic_dist(model, corpus, True)
features = tvectorizer.get_feature_names()

In [24]:

top_ws = []
for n in range(len(dtm)):
    inds = int0(argsort(dtm[n])[::-1][:4])
    tmp = [features[i] for i in inds]
    
    top_ws += [' '.join(tmp)]
    


cluster_colors = {0: 'blue', 1: 'green', 2: 'yellow', 3: 'red', 4: 'skyblue', 5:'salmon', 6:'orange', 7:'maroon', 8:'crimson', 9:'black', 10:'gray'}

p_df['colors'] = p_df['clusters'].apply(lambda l: cluster_colors[l])

In [25]:

from sklearn.manifold import TSNE
tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(top_dist)

In [26]:

p_df['X_tsne'] =X_tsne[:, 0]
p_df['Y_tsne'] =X_tsne[:, 1]

In [27]:

from bokeh.plotting import figure, show, output_notebook, save#输出文件
from bokeh.models import HoverTool, value, LabelSet, Legend, ColumnDataSource
output_notebook()

 BokehJS 0.12.5成功加载。

In [28]:

source = ColumnDataSource(dict(
    x=p_df['X_tsne'],
    y=p_df['Y_tsne'],
    color=p_df['colors'],
    label=p_df['clusters'].apply(lambda l: top_labels[l]),
#     msize= p_df['marker_size'],
    topic_key= p_df['clusters'],
    title= p_df[u'Title'],
    content = p_df['Text_Rep']
))

In [29]:

title = 'T-SNE visualization of topics'



plot_lda.scatter(x='x', y='y', legend='label', source=source,
                 color='color', alpha=0.8, size=10)#'msize', )

show(plot_lda)

 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/53430.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

142.创建序列化类、序列化测试、反序列化测试

1.创建序列化类 什么是序列化,为什么要序列化? 当前web api应用中,前端要用到从后台返回的数据来渲染页面的时候,一般都是使用的json类型的数据,因为json类型简单直观便于理解,那么就需要在django框架中&am…

openEuler 通过 手工方式 安装 ceph 步骤

ceph集群在openEuler手工安装过程openEuler手工安装ceph 安装步骤前置要求1.openEuler版本2. Python 33. Systemd4. Time synchronization (such as chrony or NTP)5. LVM2 for provisioning storage devices安装1. 创建用户ceph2. 安装 ceph3. 生成配置项3.1 机器及组件规划列…

【Confluence】预览中文附件出现乱码,离线Linux下安装字体

what: confluence页面预览含有中文的附件时乱码 why:Linux服务器上 缺少中文字体 how: 一、安装字体 1、拷贝字体:linux上/usr/share/fonts/路径下新建目录msttcore,将windows的C:\Windows\Fonts的字体文件拷贝到/usr/share/fonts…

Mac Typora + PicGo + Github配置图床

Mac Typora PicGo Github配置图床 为了能把自己整理的博客发到CSDN上集集赞又介于一张张贴图很麻烦,所以搞了搞图床试试效果 下载PicGo 会魔法的建议直接爬长城:PicGo 不会魔法的用山大的镜像:PicGo Github图床设置 新建项目 随便起个…

详解:进程程序替换

目录一、前言二、什么是进程程序替换?三、进程程序替换的原理四、为什么要进行进程程序替换?五、如何进行进程程序替换?(常见进程程序替换系统调用接口)六、利用所学综合知识实现一个shell总结一、前言 一般情况下,对应的语言写的…

ELMO语言模型

ELMOELMO提出背景:解决一词多义问题。模型结构:双层双向的LSTM,字符卷积,第一层lstm表示更多的句法特征,第二层lstm表示更多的语义特征从ELMO开始以后学的语言模型都是预训练语言模型。预训练模型:1.预训练…

微机-------输入/输出接口(第六章)

目录 输入/输出接口概述输入/输出接口的功能CPU与输入/输出接口之间的信息⭐⭐输入/输出端口的编址方式统一编址独立编址输入/输出接口概述 CPU与外部设备进行信息交换时的困难: ①CPU和外设的速度差异非常大 ②CPU不能和外设直接通过引脚连接 注意: CPU和外设之间必须要设置…

5G LDPC polar 3GPP 定案过程

前言 看到中科大袁老师一段关于3GPP 组织 在 5G LDPC, polar 编解码定案过程,简单分享一下 一 简介 整个方案上百家公司整整争论了一年,最终定下来 其里碑阶段分3段如下: 二 主要争论点 当初主要有两大纠纷: 1: 数字信道 和控制…

基于thinkphp校园二手交易网站#毕业设计

随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 东方二手交易网站设计管理系统网站主要的功能模块包括首页、个人中心、卖家管理、买家信息管理、商品信息管理、订单信息管理、商品分类管理、系统管理…

基于51单片机电子微波炉控制系统(源程序+仿真+原理图+全套资料)

资料编号:203 功能介绍: 该电子微波炉采用51单片机制作,有基本的加热、冷却、启动、停止等功能,并通过MCU 控制其加热、冷却时间,LED 数码管显示时间。程序采用C语言编写,仿真使用Proteus,程序…

Redis的分布式锁问题(十)最强分布式锁工具:Redisson

Redisson的引入 我们先来看看之前的基于setnx实现的分布式锁存在的问题: 我们之前实现的分布式锁是基于redis的setnx命令的特性的! 但是,这样子实现起来会有很多弊端! 不可重入 简单的来说就是一旦setnx [key] [value]后&…

这才是图扑数字孪生污水处理厂该有的样子

近年来,智慧水务、数字水务成为水务行业的热点领域。对于污水处理领域,如何贯彻落实双碳战略,积极推进智慧水厂建设,显得尤为关键。 图扑软件依托自主研发的 HT for Web 产品,并结合视频融合、BIM、5G、物联网、云计算…

matplotlib 中子图subplot 绘图时标题重叠解决办法

引言 使用Python的matplotlib库绘制子图发现标题发生了重叠。 原来的代码: plt.rcParams[font.family][SimHei] datayear_genfor i in range(1,11):plt.subplot(5,2,i)typetype_df.index[:][i-1]setplot_TypeTime(i,data,type)plt.show()上网上寻找解决办法。 按照…

Allegro添加渐近线操作指导

Allegro添加渐近线操作指导 Allegro支持添加渐近线,让线宽变化的地方进行圆环的过渡,对于射频信号优化有很大帮助,类似下图 具体操作如下 首先设置参数,route-Gloss-Parameters 点击Fillet and Taper Trace前面的方框 勾选Allowed DRC, Unused Nets 勾选Tapered Trac…

BLUElegend传奇引擎不使用路由器架设单传奇的办法

使用BLUE LEGEND架设传奇私发服单机的朋友,是不是因为找不到路由器而无法架设单机服务端呢,这里介绍一种方法不需要买路由器来架设。 为什么LEG引擎需要路由器才能架设呢? 网上找了很多教程都得不到答案,有些人说是为了固定ip地址…

[附源码]计算机毕业设计SpringBoot网上鲜花购物系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

leetcode-每日一题-1779-找到最近的有相同 X 或 Y 坐标的点(简单,数学思想)

今天这道每日一题很简单,没啥可说的,细心点即可 1779. 找到最近的有相同 X 或 Y 坐标的点 难度简单73收藏分享切换为英文接收动态反馈 给你两个整数 x 和 y ,表示你在一个笛卡尔坐标系下的 (x, y) 处。同时,在同一个坐标系下给你一…

基于verdaccio工具搭建npm私服vue组件库

大纲 搭建npm私服的必要性搭建npm私服操作步骤发布私有包的过程 一、搭建npm私服的必要性 下载速度更快便于管理,可以分配权限可以修改第三方包,放入我们得私服可以只在公司局域网中用,不公开 二、搭建npm私服的主要操作 环境准备 确保服…

Google单元测试框架gtest之官方sample笔记4--事件监控之内存泄漏测试

sample 10 使用event listener监控Water类的创建和销毁。在Water类中,有一个静态变量allocated,创建一次值加一,销毁一次值减一。为了实现这个功能,重载了new和delete关键字,然后在new和delete函数中,做all…

Sqoop概述 第1关:Sqoop概述

为了完成本关任务,你需要掌握: 1.Sqoop 概述; 2.Sqoop 基本架构。 Sqoop 概述 设计动机 Sqoop 从工程角度,解决了关系型数据库与 Hadoop 之间的数据传输问题,它构建了两者之间的“桥梁”,使得数据迁移工…