查看原文
其他

BERTopic 主题建模库 | 建议收藏

大邓 大邓和他的Python 2022-07-09


BERTopic 是一种主题建模技术,它利用 Transformer 和 c-TF-IDF 来创建密集的集群,允许轻松解释主题,同时在主题描述中保留重要词。

BERTopic亮点

  • 支持引导式Guided
  • 支持(半)监督式
  • 支持动态主题。
  • 支持可视化

安装

!pip3 install bertopic

准备数据

这里使用的新闻数据集, 共2000条。新闻类别涵 '娱乐', '教育', '游戏', '财经', '时政', '时尚', '科技', '体育', '家居', '房产'这里假设大家不知道有10类新闻题材, 构建模型的时候不会用到label字段的数据。

import pandas as pd

df = pd.read_csv('data/cnews.csv')
df.head()


# 新闻题材
print(df.label.unique())

#记录数
print(len(df))
['娱乐' '教育' '游戏' '财经' '时政' '时尚' '科技' '体育' '家居' '房产']
2000

这里定义了一个清洗数据函数clean_text,需要注意BERTopic需要先将中文分词改造成类似英文文本格式(用空格间隔词语)

import re
import jieba


stoptext = open('data/stopwords.txt', encoding='utf-8').read()
stopwords = stoptext.split('\n')

def clean_text(text):
    words = jieba.lcut(text)
    words = [w for w in words if w not in stopwords]
    return ' '.join(words)


test = "云南永善县级地震已致人伤间民房受损中新网月日电据云南昭通市防震减灾局官方网站消息截至日时云南昭通永善县级地震已造成人受伤其中重伤人轻伤人已全部送医院救治民房受损户间倒塌户间个乡镇所学校不同程度受损目前被损毁电力交通通讯设施已全部抢通修复当地已调拨帐篷顶紧急转移万人月日时分云南昭通永善县发生里氏级地震震源深度公里当地震感强烈此外成都等四川多地也有明显震感"
clean_text(test)
'云南 永善县 级 地震 已致 伤间 民房 受损 中新网 月 日电 云南 昭通市 防震 减灾 局 官方网站 消息 截至 日时 云南 昭通 永善县 级 地震 受伤 重伤 轻伤 送 医院 救治 民房 受损 户间 倒塌 户间 乡镇 学校 程度 受损 损毁 电力 交通 通讯 设施 抢通 修复 当地 调拨 帐篷 紧急 转移 万人 月 日 时分 云南 昭通 永善县 发生 里氏 级 地震 震源 深度 公里 当地 震感 成都 四川 多地 震感'

对2000条数据进行clean_text,得到的结果存储到content字段中。

我的macbook内存16G, 运行时间10s

df['content'] = df['text'].apply(clean_text)
df.head()


训练Topic模型

文本分析步骤包括构建特征工程和训练,在本文中,直接使用spacy的中文词向量,省去了特征模型的学习时间。

但这里需要

  1. 安装spacy
  2. 下载&安装zh_core_web_sm中文词向量模型

具体配置方法请参考 建议收藏 | nltk和spacy配置方法

from bertopic import BERTopic
import spacy

zh_model = spacy.load("zh_core_web_sm")

topic_model = BERTopic(language="chinese (simplified)"
                       embedding_model=zh_model,
                       calculate_probabilities=True
                       verbose=True)


docs = df['content'].tolist()
#2000条进行fit_transform需要1min
topics, probs = topic_model.fit_transform(docs)
100%|██████████| 2000/2000 [01:31<00:00, 21.91it/s]2021-10-28 12:11:25,583 - BERTopic - Transformed documents to Embeddings2021-10-28 12:11:34,582 - BERTopic - Reduced dimensionality with UMAP2021-10-28 12:11:34,718 - BERTopic - Clustered UMAP embeddings with HDBSCAN


CPU times: user 1min 50s, sys: 7.7 s, total: 1min 57sWall time: 1min 43s



主题模型方法

  • topic_model.get_topic_info 查看各主题信息
  • topic_model.find_topics(term, top_n=5)  查找term最有可能所属话题
  • topic_model.get_topic(0) 查看Topic 0的特征词
  • topic_model.visualize_topics() 话题间距离的可视化
  • topic_model.visualize_distribution(probs[0]) 查看某条文本的主题分布
  • topic_model.visualize_hierarchy(top_n_topics=20) 主题层次聚类可视化
  • topic_model.visualize_barchart(top_n_topics=6) 主题词条形图可视化
  • topic_model.visualize_heatmap(n_clusters=10) 主题相似度热力图
  • topic_model.visualize_term_rank() 可视化词语
  • topic_model.save()  保存主题模型

topic_model.get_topic_info()

similar_topics, similarity = topic_model.find_topics("美国", top_n=5)similar_topics
[0, 3, 1, 2, -1]

topic_model.get_topic(0)
[('中国', 0.017740927481291097), ('美国', 0.009187523853389844), ('国际', 0.007387509919710244), ('北京', 0.006355315208051378), ('台湾', 0.004591519972746738), ('上海', 0.00398117373168178), ('电影', 0.003959013801339396), ('文化', 0.003635760343311582), ('主持人 韩悦', 0.003598325963444241), ('全球', 0.0034710750361063997)]

topic_model.visualize_topics()


显示第一条新闻的主题概率分布

topic_model.visualize_distribution(probs[0])


为了理解主题的潜在层次结构,我们可以使用 scipy.cluster.hierarchy 创建聚类并可视化它们之间的关系。这有助于合并相似主题,达到降低主题模型主题数量nr_topics。

topic_model.visualize_hierarchy(top_n_topics=20)


topic_model.visualize_barchart(top_n_topics=6, width = 1000, height= 800)


BERTopic可将主题以embeddings形式(向量)表示, 因此我们可以应用余弦相似度来创建相似度矩阵。每两两主题可进行余弦计算,最终结果将是一个矩阵,显示主题间的相似程度。

topic_model.visualize_heatmap(n_clusters=10, width=1000, height=1000)

通过根据每个主题表示的 c-TF-IDF 分数创建条形图来可视化主题的选定词语。从主题之间和主题内的相对 c-TF-IDF 分数中获得见解。此外,可以轻松地将主题表示相互比较。


topic_model.visualize_term_rank()



更新主题模型

当您训练了一个模型并查看了代表它们的主题和单词时,您可能对表示不满意。也许您忘记删除停用词,或者您想尝试不同的 n_gram_range。我们可以使用函数 update_topics 使用 c-TF-IDF 的新参数更新主题表示。

经过更新,topic_model得到了更新,

topic_model.update_topics(df.content.tolist(), topics, n_gram_range=(13))

保存主题模型

模型训练特别耗时的情况下,可以考虑保存模型,这样下次运行代码,可以直接导入模型

# Save model
topic_model.save("my_model")

# Load model
# my_model = BERTopic.load("my_model")



代码下载

本文使用中文文本数据展示BERTopic部分功能,如果对英文数据感兴趣,可以前往 https://github.com/MaartenGr/BERTopic 深入学习。代码下载地址,点击访问

https://github.com/hidadeng/DaDengAndHisPython/tree/master/20211029BERTopic主题模型


近期文章

视频专栏课 | Python网络爬虫与文本分析

Shifterator库 | 词移图分辨两文本用词风格差异

DataShare | 6000+个股票的每日财经新闻  

SmartScraper | 简单、自动、快捷的Python网络爬虫

SHAP | 机器学习模型解释库

读完本文你就了解什么是文本分析

文本分析在经管领域中的应用概述

综述:文本分析在市场营销研究中的应用

文本分析方法在《管理世界》(2021.5)中的应用

中文金融情感词典发布啦 | 附代码

wordexpansion包 | 新增词向量法构建领域词典

语法最简单的微博通用爬虫weibo_crawler

hiResearch 定义自己的科研首页

SciencePlots | 科研样式绘图库

plydata库 | 数据操作管道操作符>>

plotnine: Python版的ggplot2作图库

Wow~70G上市公司定期报告数据集

漂亮~pandas可以无缝衔接Bokeh  

YelpDaset: 酒店管理类数据集10+G

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存