主题模型(Topic Model)与LDA算法

2023-11-06

  • Topic Model

主题模型(Topic Model)是以非监督学习的方式对文档的隐含语义结构(latent semantic structure)进行聚类(clustering)的统计模型

主题模型认为在词(word)与文档(document)之间没有直接的联系,它们应当还有一个维度将它们串联起来,主题模型将这个维度称为主题(topic)。每个文档都应该对应着一个或多个的主题,而每个主题都会有对应的词分布,通过主题,就可以得到每个文档的词分布。依据这一原理,就可以得到主题模型的一个核心公式:

p(w_{i}|d_{j})=\sum_{k=1}^{K}p(w_{i}|t_{k})\times p(t_{k}|d_{j})

在一个已知的数据集中,每个词和文档对应的p(w_{i}|d_{j})都是已知的。而主题模型就是根据这个已知的信息,通过计算p(w_{i}|t_{k})p(t_{k}|d_{j})的值,从而得到主题的词分布和文档的主题分布信息。而要得到这个分布信息,现在常用的方法就是LSA(LSI)和LDA。其中LSA主要是采用SVD的方法进行暴力破解,而LDA则是通过贝叶斯学派的方法对分布信息进行拟合。

  • LDA算法

隐含狄利克雷分布(Latent Dirichlet Allocation, LDA)是由David Blei等人在2003年提出的,该方法的理论基础是贝叶斯理论。LDA根据词的共现信息的分析,拟合出词-文档-主题的分布,进而将词、文本都映射到一个语义空间中。

LDA算法假设文档中主题的先验分布和主题中词的先验分布都服从狄利克雷分布。在贝叶斯学派看来,先验分布+数据(似然)=后验分布。我们通过对已有数据集的统计,就可以得到每篇文档中主题的多项式分布和每个主题对应词的多项式分布。然后就可以根据贝叶斯学派的方法,通过先验的狄利克雷分布和观测数据得到的多项式分布,得到一组Dirichlet-multi共轭,并据此来推断文档中主题的后验分布,也就是我们最后需要的结果。那么具体的LDA模型应当如何进行求解,其中一种主流的方法就是吉布斯采样。结合吉布斯采样的LDA模型训练过程一般如下:

  1. 随机初始化,对语料中每篇文档中的每个词w,随机地赋予一个topic编号z。
  2. 重新扫描语料库,对每个词w按照吉布斯采样公式重新采样它的topic,在语料中进行更新。
  3. 重复以上语料库的重新采样过程直到吉布斯采样收敛。
  4. 统计语料库的topic-word共现频率矩阵,该矩阵就是LDA的模型。

经过以上的步骤,就得到一个训练好的LDA模型,接下来就可以按照一定的方式针对新文档的topic进行预估,具体步骤如下:

  1. 随机初始化,对当前文档中的每个词w,随机地赋予一个topic编号z。
  2. 重新扫描当前文档,按照吉布斯采样公式,重新采样它的topic。
  3. 重复以上过程直到吉布斯采样收敛。
  4. 统计文档中的topic分布即为预估结果。

具体的LDA理论可以参考rickjin写的LDA数学八卦:http://www.52nlp.cn/lda-math-%E6%B1%87%E6%80%BB-lda%E6%95%B0%E5%AD%A6%E5%85%AB%E5%8D%A6

  • 提取文本关键词

通过上面的LSI或LDA算法,我们得到了文档对主题的分布和主题对词的分布,接下来就是要利用这些信息来对关键词进行抽取。在我们得到主题对词的分布后,也据此得到词对主题的分布。接下来,就可以通过这个分布信息计算文档与词的相似性,继而得到文档最相似的词列表,最后就可以得到文档的关键词。

TF-IDF实现文本关键词提取的基础上,实现一个完整的主题模型,分别实现LSI、LDA算法,根据传入参数model进行选择。几个参数如下:

  • doc_list:是前面数据集加载方法的返回结果。
  • keyword_num:同上,为关键词数量。
  • model:本主题模型的具体算法,分别可以传入LSI、LDA,默认为LSI。
  • num_topics为主题模型的主题数量。

LSI和LDA的训练是根据现有的数据集生成文档-主题分布矩阵和主题-词分布矩阵,Gensim中有实现好的训练方法,直接调用即可。

from gensim import corpora, models

# 主题模型
class TopicModel(object):
    # 三个传入参数:处理后的数据集,关键词数量,具体模型(LSI、LDA),主题数量
    def __init__(self, doc_list, keyword_num, model='LSI', num_topics=4):
        # 使用gensim的接口,将文本转为向量化表示
        # 先构建词空间
        self.dictionary = corpora.Dictionary(doc_list)
        # 使用BOW模型向量化
        corpus = [self.dictionary.doc2bow(doc) for doc in doc_list]
        # 对每个词,根据tf-idf进行加权,得到加权后的向量表示
        self.tfidf_model = models.TfidfModel(corpus)
        self.corpus_tfidf = self.tfidf_model[corpus]

        self.keyword_num = keyword_num
        self.num_topics = num_topics
        # 选择加载的模型
        if model == 'LSI':
            self.model = self.train_lsi()
        else:
            self.model = self.train_lda()

        # 得到数据集的主题-词分布
        word_dic = self.word_dictionary(doc_list)
        self.wordtopic_dic = self.get_wordtopic(word_dic)

    def train_lsi(self):
        lsi = models.LsiModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)
        return lsi

    def train_lda(self):
        lda = models.LdaModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)
        return lda

    def get_wordtopic(self, word_dic):
        wordtopic_dic = {}

        for word in word_dic:
            single_list = [word]
            wordcorpus = self.tfidf_model[self.dictionary.doc2bow(single_list)]
            wordtopic = self.model[wordcorpus]
            wordtopic_dic[word] = wordtopic
        return wordtopic_dic

    # 计算词的分布和文档的分布的相似度,取相似度最高的keyword_num个词作为关键词
    def get_simword(self, word_list):
        sentcorpus = self.tfidf_model[self.dictionary.doc2bow(word_list)]
        senttopic = self.model[sentcorpus]

        # 余弦相似度计算
        def calsim(l1, l2):
            a, b, c = 0.0, 0.0, 0.0
            for t1, t2 in zip(l1, l2):
                x1 = t1[1]
                x2 = t2[1]
                a += x1 * x1
                b += x1 * x1
                c += x2 * x2
            sim = a / math.sqrt(b * c) if not (b * c) == 0.0 else 0.0
            return sim

        # 计算输入文本和每个词的主题分布相似度
        sim_dic = {}
        for k, v in self.wordtopic_dic.items():
            if k not in word_list:
                continue
            sim = calsim(v, senttopic)
            sim_dic[k] = sim

        for k, v in sorted(sim_dic.items(), key=functools.cmp_to_key(cmp), reverse=True)[:self.keyword_num]:
            print(k + "/ ", end='')
        print()

    @staticmethod
    # 词空间构建方法和向量化方法,在没有gensim接口时的一般处理方法
    def word_dictionary(doc_list):
        dictionary = []
        for doc in doc_list:
            dictionary.extend(doc)

        dictionary = list(set(dictionary))
        return dictionary

    def doc2bowvec(self, word_list):
        vec_list = [1 if word in word_list else 0 for word in self.dictionary]
        return vec_list

统一算法调用接口:

def topic_extract(word_list, model, pos=False, keyword_num=10):
    doc_list = load_data(pos)
    topic_model = TopicModel(doc_list, keyword_num, model=model)
    topic_model.get_simword(word_list)

对目标文本进行关键词提取:

if __name__ == '__main__':
    text =  '费尔南多·托雷斯(Fernando Jose Torres Sanz),1984年3月20日出生于西班牙马德里,' + \
            '西班牙足球运动员,司职前锋,效力于日本职业足球甲级联赛鸟栖砂岩足球俱乐部。' + \
            '托雷斯2001出道于马德里竞技,2007年加盟英超利物浦,2011年转会切尔西,' + \
            '期间帮助球队夺得了2012年欧洲冠军联赛冠军,其后以租借的形式加盟AC米兰,' + \
            '2014年12月,托雷斯宣布回归马德里竞技。2018年7月,托雷斯宣布加盟日本鸟栖砂岩足球俱乐部。' + \
            '2004年欧洲杯,托雷斯首次代表国家队参加国际大赛,2008年和2012年跟随西班牙队两度夺得欧洲杯冠军,' + \
            '2010年随队夺得世界杯冠军,其个人在2008年荣膺欧洲杯决赛MVP,2012获得欧洲杯金靴奖、2013年获得联合会杯金靴奖。'

    pos = True
    seg_list = seg_to_list(text, pos)
    filter_list = word_filter(seg_list, pos)

    print('LSI模型结果:')
    topic_extract(filter_list, 'LSI', pos)
    print('LDA模型结果:')
    topic_extract(filter_list, 'LDA', pos)

执行结果如下:

LSI模型结果:
大赛/ 代表/ 个人/ 形式/ 职业/ 国际/ 日本/ 加盟/ 运动员/ 冠军/ 
LDA模型结果:
大赛/ 职业/ 运动员/ 冠军/ 日本/ 形式/ 个人/ 代表/ 国际/ 国家队/ 

参考:https://book.douban.com/subject/30247776/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

主题模型(Topic Model)与LDA算法 的相关文章

  • 创建向量空间

    我有一个问题 我有很多文档 每一行都是由某种模式构建的 当然 我有这一系列的图案 我想创建一些向量空间 然后通过某种规则来向量这个模式 我还不知道这个规则是什么 即使这个模式像我的向量空间的 质心 然后向量当前文档的每一行 再次按照此规则
  • browserify :- 未捕获类型错误:fs.readFileSync 不是函数

    我试图在我的代码中使用natural js 在客户端使用它 我使用browserify 但它给出了一个错误 Uncaught TypeError fs readFileSync is not a function at loadDictio
  • 我应该如何使用 scikit learn 对以下列表进行矢量化?

    我想用 scikit 进行矢量化学习一个有列表的列表 我转到有训练文本的路径 我阅读了它们 然后我得到如下内容 corpus this is spam SPAM this is ham HAM this is nothing NOTHING
  • Keras 文本预处理 - 将 Tokenizer 对象保存到文件中以进行评分

    我按照以下步骤 大致 使用 Keras 库训练了一个情感分类器模型 使用 Tokenizer 对象 类将文本语料库转换为序列 使用 model fit 方法构建模型 评估这个模型 现在 为了使用此模型进行评分 我可以将模型保存到文件中并从文
  • 如何在 python-gensim 中使用潜在狄利克雷分配(LDA)来抽象二元组主题而不是一元组?

    LDA 原始输出 一元语法 主题1 水肺 水 蒸汽 潜水 主题2 二氧化物 植物 绿色 碳 所需输出 二元组主题 主题1 水肺潜水 水蒸气 主题2 绿色植物 二氧化碳 任何想法 鉴于我有一个名为docs 包含文档中的单词列表 我可以使用 n
  • 使用 Hadoop MapReduce 的计算语言学项目构想

    我需要做一个关于计算语言学课程的项目 是否有任何有趣的 语言 问题 其数据密集程度足以使用 Hadoop MapReduce 来解决 解决方案或算法应尝试分析并提供 语言 领域的一些见解 但是它应该适用于大型数据集 以便我可以使用 hado
  • 如何调整 NLTK 句子标记器

    我正在使用 NLTK 来分析一些经典文本 但我在按句子标记文本时遇到了麻烦 例如 这是我从以下内容中得到的片段莫比迪克 http www gutenberg org cache epub 2701 pg2701 txt import nlt
  • 如何有效计算文档流中文档之间的相似度

    我收集文本文档 在 Node js 中 其中一个文档i表示为单词列表 考虑到新文档以文档流的形式出现 计算这些文档之间相似性的有效方法是什么 我目前对每个文档中单词的归一化频率使用余弦相似度 我不使用 TF IDF 词频 逆文档频率 因为我
  • Blenderbot 微调

    我一直在尝试微调 HuggingFace 的对话模型 Blendebot 我已经尝试过官方拥抱脸网站上给出的传统方法 该方法要求我们使用 trainer train 方法来完成此操作 我使用 compile 方法尝试了它 我尝试过使用 Py
  • 语音识别中如何处理同音词?

    对于那些不熟悉什么是同音字 https en wikipedia org wiki Homophone是的 我提供以下示例 我们的 是 嗨和高 到 太 二 在使用时语音API https developer apple com docume
  • 从文本文件中提取与输入单词最相似的前 N ​​个单词

    我有一个文本文件 其中包含我使用 BeautifulSoup 提取的网页内容 我需要根据给定的单词从文本文件中找到 N 个相似的单词 流程如下 从中提取文本的网站 https en wikipedia org wiki Football h
  • 如何训练斯坦福 NLP 情感分析工具

    地狱大家 我正在使用斯坦福核心 NLP 包 我的目标是对推文直播进行情感分析 按原样使用情感分析工具对文本 态度 的分析非常差 许多积极因素被标记为中性 许多消极因素被评为积极 我已经在文本文件中获取了超过一百万条推文 但我不知道如何实际获
  • 用于估计(一元)困惑度的 NLTK 包

    我正在尝试计算我所拥有的数据的困惑度 我正在使用的代码是 import sys sys path append usr local anaconda lib python2 7 site packages nltk from nltk co
  • NLTK 中的无监督 HMM 训练

    我只是想进行非常简单的无监督 HMM 训练nltk http www nltk org 考虑 import nltk trainer nltk tag hmm HiddenMarkovModelTrainer from nltk corpu
  • SpaCy 模型“en_core_web_sm”的词汇量大小

    我尝试在 SpaCy 小模型中查看词汇量 model name en core web sm nlpp spacy load model name len list nlpp vocab strings 只给了我 1185 个单词 我也在同
  • 快速NLTK解析成语法树

    我正在尝试将数百个句子解析为语法树 我需要快速完成 问题是如果我使用 NLTK 那么我需要定义一个语法 而我不知道我只知道它会是英语 我尝试使用this https github com emilmont pyStatParser统计解析器
  • 快速 shell 命令删除文本文件中的停用词

    我有一个 2GB 的文本文件 我正在尝试从此文件中删除经常出现的英语停用词 我有 stopwords txt 包含这样的 a an the for and I 使用 shell 命令 例如 tr sed 或 awk 执行此操作的快速方法是什
  • 保存具有自定义前向功能的 Bert 模型并将其置于 Huggingface 上

    我创建了自己的 BertClassifier 模型 从预训练开始 然后添加由不同层组成的我自己的分类头 微调后 我想使用 model save pretrained 保存模型 但是当我打印它并从预训练上传时 我看不到我的分类器头 代码如下
  • 使用 SciKit-learn 和大型数据集进行文本分类

    首先 我昨天开始学习Python 我正在尝试使用 SciKit 和大型数据集 250 000 条推文 进行文本分类 对于该算法 每条推文都将表示为 4000 x 1 向量 因此这意味着输入为 250 000 行和 4000 列 当我尝试在
  • 如何从 Pandas DataFrame 转换为 Tensorflow BatchDataset 以进行 NLP?

    老实说 我想弄清楚如何转换数据集 格式 pandasDataFrame或 numpy 数组 转换为简单文本分类张量流模型可以训练用于情感分析的形式 我使用的数据集类似于 IMDB 包含文本和标签 正面或负面 我看过的每个教程要么以不同的方式

随机推荐

  • 教你手机如何查看真实的IP地址

    有朋友不会查询自己手机的IP地址 很多时候我们需要使用vpn切换手机当前的IP 如何判断我们切换IP成功了呢 今天站长就教你手机如何查看目前真实的IP地址 1 打开手机浏览器 2 在搜索框里输入 ip 然后点击搜索 在搜索结果页面就会显示你
  • ESP32 上快捷部署 Tensorflow lite 机器学习(TinyML)

    在这篇文章中 我将向您展示使用 Arduino IDE 将 TensorFlow Lite 模型部署到 ESP32 的最简单方法 无需任何编译内容 Arduino 库 这个 Arduino 库是为了简化使用 Arduino IDE 将用于微
  • 4.8xml于json

    HTTP 协议 HyperText Transfer Protocol 超文本传输协议 是 TCP IP 协议集中的协议 是一个简单的请求 响应协议 指 定了客户端发送给服务器的消息以及服务器的响应 所有的 WWW 文件都必须遵守这个标准
  • matplotlib绘制饼状图

    源自http blog csdn net skyli114 article details 77508430 ticket ST 41707 PzNbUDGt6R5KYl3TkWDg passport csdn net pyplot使用pl
  • 接口测试基础

    目录 一 接口及接口测试概念 1 接口 接口的类型 2 接口测试 二 HTTP协议 1 HTTP协议的特点 2 URL格式 3 HTTP请求 4 HTTP响应 三 接口规范 1 传统风格接口 2 RESTful风格接口 四 接口测试流程 1
  • Python 11. OpenCV 透视变换

    import cv2 import numpy as np from matplotlib import pyplot as plt img cv2 imread pic4 PNG rows cols img shape 2 cv2 ims
  • 支持图文转换!PSD文档处理工具Aspose全新升级

    Aspose PSD是高级PSD和入门级AI文件格式操作API 允许创建和编辑Photoshop文件 并提供更新图层属性 添加水印 执行图形操作或将一种文件格式转换为另一种文件的功能 没有任何Adobe Photoshop或Adobe Il
  • [系统

    系统环境说明 系统 Deepin V20 平台 amd64 参考文献 asdf maven asdf document asdf plugins asdf vm安装 见多版本管理命令行工具asdf vm安装及使用 asdf vm安装Mave
  • 「C++学习笔记」面向.Net Core的(C++)CLR类库非专业入门(+使用Opencv)

    关键词 C CLR Net Core Net Famework Opencv C 目录 什么是CLR类库 本文说明 创建Demo程序 调用dll 通过项目引用 通过dll文件引用 其他还没完全清楚的坑 有关C CLI这块的资料真的很少而且都
  • 如何看待ChatGPT

    如何看待ChatGPT 如何看待ChatGPT 语言学家乔姆斯基说 这是一个抄袭的机器 欺骗性机器 ChatGPT使用大量文本数据进行训练 然后以一种令人信服的修饰语句展现 这使得它和人的互动能力更加契合 但是仍然不是一个充满创造力的智能机
  • 微信小程序之拨打电话

    微信小程序拨打电话功能的实现是采用wx makePhoneCall 具体方法如下 wxml lt view gt 电话 15888888888 lt view data ph 15888888888 bindtap callPhone gt
  • 【Android 12 AOSP学习】Android 12源码下载编译

    一 搭建环境 liunx系统 Ubuntu20 04 Android系统 12 1 安装 Repo 下载Repo前先安装 curl 库 sudo apt get install curl 下载好 curl 库后 设置清华源下载 Repo 然
  • 前端 JavaScript 提取 JSON 数据

    原文地址 假如我们从后端接收到了以下 JSON 数据 id 1 name Xu Albter age 18 使用 JSON parse 方法处理以上数据 将其转换为 JavaScript 对象 var obj JSON parse id 1
  • select函数缺陷分析

    与poll和epoll不同 select函数是事件为单位组织文件描述符 监视的行为较为单一 函数原型 int select int nfds fd set readfds fd set writefds fd set exceptfds s
  • 链表应用:两数相加

    关于链表 链表是一种极其重要的数据结构 因为对指针和抽象思维的要求较高 一度成为身边同学最痛恨的对象 我在将这里演示如何使用链表制作一个可以按位储存数字的容器 鉴于本人亦初学者 有错误请各位在评论区指正 这里还是以介绍链表为主 算法部分苦于
  • SpringCloud和微服务介绍

    SpringCloud介绍 微服务架构是什么 微服务实例的开发 服务的注册与发现 负载均衡 服务容错 API网关 分布式配置中心 调试 部署 持续集成 SpringCloud介绍 SpringCloud是在SpringBoot的基础上构建的
  • 一个完整详细的二维SVR案例分析过程

    文章目录 案例介绍 数据预处理 函数拟合仿真 SVR建模 模型调参 案例介绍 首先 此次案例是以油气开发为背景 选取加粗样式其中重要的两个参数含油饱和度和孔隙度分别作为此次案例的自变量和因变量进行试验 按照正常的案例分析步骤进行操作 此次为
  • 神经网络(ANN)

    算法介绍 概念 人工神经网络是由具有适应性的简单单元组成的广泛并行互连的网络 它的组织能够模拟生物神经神经系统对真实世界物体所作出的交互反应 在实际应用中 80 90 的人工神经网络模型是采用误差反转算法或其变形形式的网络模型 一个神经网络
  • 小程序的配置文件和小程序的模板语法

    微信小程序 小程序的配置文件 一个小程序应用程序会包括 会有最基本的两种配置文件 一种是全局的 app json 一种是页面自己的 page json 注意 配置文件中不可以出行注释 1 1 全局配置文件 app json app json
  • 主题模型(Topic Model)与LDA算法

    Topic Model 主题模型 Topic Model 是以非监督学习的方式对文档的隐含语义结构 latent semantic structure 进行聚类 clustering 的统计模型 主题模型认为在词 word 与文档 docu