基于sklearn实现LDA主题模型(附实战案例)

news2024/12/28 9:49:35

目录

LDA主题模型

1.LDA主题模型原理

2.LDA主题模型推演过程

3.sklearn实现LDA主题模型(实战)

3.1数据集介绍

3.2导入数据

3.3分词处理

 3.4文本向量化

3.5构建LDA模型

3.6LDA模型可视化 

3.7困惑度 


LDA主题模型


1.LDA主题模型原理


        其实说到LDA能想到的有两个含义,一种是线性判别分析(Linear Discriminant Analysis),一种说的是概率主题模型:隐含狄利克雷分布(Latent Dirichlet Allocation,简称LDA)。
        现在讨论的是主题模型这个东西,它通俗点说吧,就是可以将一篇文中的主题以概率分布的形式来给出,从而通过去分析一些文档抽取出来它们的主题(分布)以后,就可以根据主题(分布)进行主题聚类或文本分类。同时,它是一种典型的词袋子模型,也就是说一篇文档是由一组词构成,词与词之间没有先后顺序的关系。除此之外,一篇文章它可以包含多个主题,文章中每一个词都由是其中的一个主题生成。
        我们其实很简单就可以想到我们是如何生成的文章?就是给几个主题,然后按一定的概率去选择主题,以一定的概率选择这个主题所包含的词汇,最终组合成一篇文章。LDA就是反过来的,给它一篇文章,去推断该文章的主题分布是什么。

2.LDA主题模型推演过程


        我们先从一个类似LDA的模型开始,它就是PLSA模型,它类型属于有向边概率图模型。比如说我有一批数据,有部分是垃圾邮件,有部分是正常邮件,来个新数据,我怎么判定它是不是垃圾邮件?我们首先需要建立词汇表(使用现有的单子字典或者将邮件里的单词统计下得到字典),然后随机一个矩阵,经过训练后让这个矩阵去表示那个词,为啥不用onehot呢?因为比较稀疏,很容易梯度爆炸。然后套到贝叶斯公式里: P(C|X) = P©*P(X|C) / P(X),会有个问题,它没有办法解决一词多意或者多词一意的问题,会导致我们计算文本之间相似度时候的不准确性。我们找到个解决办法就是为每一篇文档加上一个主题。其实它核心的过程就是选定文章生成主题,确定主题生成词。在这个过程里,我们其实并没有关注词和词之间的出现顺序,所以PLSA是一种词袋子方法。它主要应用于信息检索,过滤,自然语言处理等领域,考虑到词分布和主题分布,使用EM最大期望算法去学习参数。

        然后我们将PLSA模型加上一个贝叶斯框架就是我们的LDA主题模型了,换句话说LDA就是PLSA的贝叶斯版本,朴素贝叶斯的文本分类问题里的两个基础条件是:①条件独立;②每个特征的重要性都是一样的。

        LDA在选主题和选词两个参数都弄成随机的,而且加入了一个dirichlet先验随机确定;但是PLSA中主题分布和词分布是唯一确定的,用EM极大似然估计算法去推断两未知的固定参数,这也是它俩之间最大的区别。

3.sklearn实现LDA主题模型(实战)
 

3.1数据集介绍

首先介绍一下本次实验的数据集,数据集通过爬虫采集新闻网中的数据,主要有两个字段,一个的文章内容,一个的内容所属分类,每个分类各有100条数据,如下所示: 

3.2导入数据

首先还是导入数据,

import pandas as pd
import warnings
warnings.filterwarnings('ignore')
data = pd.read_excel('data.xlsx')
data.head()

3.3分词处理

接着对内容content进行分词处理,对于中文分词可以使用jieba库

import re
import jieba

def chinese_word_cut(mytext):
    jieba.load_userdict('dic.txt')  # 这里你可以添加jieba库识别不了的网络新词,避免将一些新词拆开
    jieba.initialize()
    # 文本预处理 :去除一些无用的字符只提取出中文出来
    new_data = re.findall('[\u4e00-\u9fa5]+', mytext, re.S)
    new_data = " ".join(new_data)

    # 文本分词
    seg_list_exact = jieba.cut(new_data, cut_all=True)
    result_list = []
    with open('停用词库.txt', encoding='utf-8') as f: # 可根据需要打开停用词库,然后加上不想显示的词语
        con = f.readlines()
        stop_words = set()
        for i in con:
            i = i.replace("\n", "")   # 去掉读取每一行数据的\n
            stop_words.add(i)

    for word in seg_list_exact:
        if word not in stop_words and len(word) > 1:
            result_list.append(word)      
    return " ".join(result_list)
data["content_cutted"] = data.content.apply(chinese_word_cut)
data.head()

 3.4文本向量化

from sklearn.feature_extraction.text import CountVectorizer

n_features = 1000 #提取1000个特征词语
tf_vectorizer = CountVectorizer(strip_accents = 'unicode',
                                max_features=n_features,
                                stop_words='english',
                                max_df = 0.5,
                                min_df = 10)
tf = tf_vectorizer.fit_transform(data.content_cutted)

3.5构建LDA模型

因为在这里我们已经有内容所属分类这个特征,共有8个分类,所有这里我们构建8个主题模型。如果我们没有提前没有主题标签,那可以使用困惑度分析来得出这里的主题数,这个我后面再讲。

from sklearn.decomposition import LatentDirichletAllocation
n_topics = 8  # 这里是设置LDA分类的主题个数,因为这里我们已经知道了每个内容的标签共有8个类型
lda = LatentDirichletAllocation(n_components=n_topics, max_iter=50,
                                learning_method='batch',
                                learning_offset=50,
                                doc_topic_prior=0.1,
                                topic_word_prior=0.01,
                               random_state=666)  # 关于模型的参数,可查看官方文档
lda.fit(tf)

构建模型好了后,我们来输出每个主题对应的词语,

def print_top_words(model, feature_names, n_top_words):
    tword = []
    for topic_idx, topic in enumerate(model.components_):
        print(f"Topic #{topic_idx}:" )
        topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
        tword.append(topic_w)
        print(topic_w)
    return tword
# 输出每个主题对应词语
n_top_words = 25
tf_feature_names = tf_vectorizer.get_feature_names()
topic_word = print_top_words(lda, tf_feature_names, n_top_words)

 我们来分析一下输出的结果,第一个0主题对应的应该是....好像还看不出来,先看后面的,第二个1主题对应的应该是股票,2主题对应的应该是教育,3主题对应的应该是科技,4主题对应的应该是体育,5主题对应的是房地产,6主题对应的是娱乐,7主题对应的应该是游戏,最后还剩一个彩票,那应该就是主题0,但是效果好像不是很好,为了提高准确率,可在数据处理和参数选择的时候多下点功夫多研究研究,得到最优的模型。

接着,我们利用训练好的模型得出每篇文章对应的主题

import numpy as np
topics=lda.transform(tf)
topics[0] # 查看第一篇文章的主题概率
topic = []
for t in topics:
    topic.append(list(t).index(np.max(t)))
data['topic']=topic
data.to_excel("data_topic.xlsx",index=False)  # 将结果保存为Excel文件

 我们可以看出第一篇文章在八个主题中的概率,其中是4主题的概率最大,说明这是一篇体育类的文章。最后保存的excel文件如下:

大部分都是预测正确的,也有少部分误差,这主要还是跟文章质量、数据预处理、模型参数选择有较强的关系。

3.6LDA模型可视化 

import pyLDAvis
import pyLDAvis.sklearn

pyLDAvis.enable_notebook()
pic = pyLDAvis.sklearn.prepare(lda, tf, tf_vectorizer)
pyLDAvis.save_html(pic, 'lda_pass'+str(n_topics)+'.html') # 将可视化结果打包为html文件
pyLDAvis.show(pic,local=False)

这里在保存为html的时候会花费大量的时间,可忽略这一步,运行后会跳出如下界面:

在上图我们可以看出我们模型各主题的分布,模型最好的结果就是每个主题都是互相隔开的,所有在前期不确定要分多个主题的时候不妨不断通过测试可视化来确定,当鼠标滑到每个主题上时,会在看见右边该主题中频次最高的前30个词语。

3.7困惑度 

最后来讲讲如何利用困惑度在未知主题个数的时候通过可视化来确定。

import matplotlib.pyplot as plt

plexs = []
scores = []
n_max_topics = 16  # 这里值可自行设置
for i in range(1,n_max_topics):
    lda = LatentDirichletAllocation(n_components=i, max_iter=50,
                                    learning_method='batch',
                                    learning_offset=50,random_state=666)
    lda.fit(tf)
    plexs.append(lda.perplexity(tf))
    scores.append(lda.score(tf))

n_t=15 # 区间最右侧的值。注意:不能大于n_max_topics
x=list(range(1,n_t))
plt.plot(x,plexs[1:n_t])
plt.xlabel("number of topics")
plt.ylabel("perplexity")
plt.show()

如何根据图形来选取呢,原则上是看图形的最低点,因为最低点意味着主题数会很大,这样就造成了模型过拟合,所以我们只要发现在小区间内有转折点,像图中的8就是最适合的主题数。 

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

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

相关文章

web前端大一实训 HTML+CSS+JavaScript王者荣耀(60页) web课程设计网页规划与设计 HTML期末大作业 HTML网页设计结课作业

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

【附源码】计算机毕业设计JAVA房产客户信息管理系统

【附源码】计算机毕业设计JAVA房产客户信息管理系统【附源码】 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术&#x…

新唐(nuvoton)MCU软件开发指南—环境搭建设置

新唐MCU软件开发指南—环境搭建设置 1. 下载并安装Arm Keil MDK https://www.nuvoton.com/tool-and-software/ide-and-compiler/keil-download/ 2. 申请免费版的Keil License,并激活 https://www.nuvoton.com/tool-and-software/ide-and-compiler/get-keil-mdk-…

Tableau安装详解及密钥申请

文章目录Tableau介绍下载软件申请密钥安装软件❤️ 作者简介:大家好我是小鱼干儿♛是一个热爱编程、热爱算法的大三学生,蓝桥杯国赛二等奖获得者🐟 个人主页 :https://blog.csdn.net/qq_52007481⭐ 个人社区:【小鱼干爱…

Linux系统了解 Samba服务器配置的工作流程

了解 Samba服务器配置的工作流程 当Samba 服务安装完毕,并不是直接可以使用 Windows 或 Linux的客户端访问Samba服务器,还必须对服务器进行设置:告诉 Samba 服务器将哪些目录共享出来给客户端进行访问,并根据需要设置其他选项&…

微服务架构陷阱与挑战

六大陷阱 粒度太细 服务关系复杂 需求分析、方案设计、测试、部署。。。难度都会增加 例如: 分布式服务如何保证数据一致性分析设计的时候需要考虑的影响点变多 团队效率低下 需求分析、方案设计、测试、部署。。。工作量都会增加 例如: 接口设计…

Xintell——全生命周期的模型建设+智能数据中台

在业务反欺诈、运营及数据分析上,经常会涉及到模型。模型就是基于目标群体的大规模采样数据,挖掘出某个实际问题或客观事物的现象本质及运行规律,利用抽象的概念分析存在问题或风险,计算推演出减轻、防范问题或风险的对策过程&…

怎么用手机压缩图片?教给大家三种手机压缩图片方法

如何使用手机把图片的内存进行压缩呢?大家在使用照片的时候,如果照片的内存太大,不仅会占用手机的内存,也会影响一些网站上传图片的操作,因为图片内存太大很多都是上传不了的,为了解决这一问题我们可以将图…

【设计模式】适配器模式:攻敌三分,自留七分,以超兽武装的例子来谈谈适配器模式

文章目录1 适配器模式1.1 定义1.2 结构1.3 类图1.3.1 类适配器模式1.3.2 对象适配器模式2 例子2.1 类适配器模式2.1.1 代码2.1.2 效果图2.2 对象适配器模式2.2.1 代码2.2.2 效果通3 优缺点及适用环境3.1 优点3.2 缺点3.3 适用环境1 适配器模式 1.1 定义 将一个类的接口转换成客…

【深入理解C++】RTTI、dynamic_cast、typeid()

文章目录1.RTTI2.dynamic_cast运算符3.typeid运算符4.RTTI与虚函数表1.RTTI RTTI(Run Time Type Identification),即运行时类型识别,通过 RTTI,程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。 RTTI 提供了两…

数据库命名规范

1、mysql 规范 1.1 表名规范 模块_功能点 示例:alllive_log alllive_category。采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线_组成,命名简洁明确,多个单词用下划线_分隔,一个项目一个数据库。全部小写命名&#xff0c…

嵌入式分享合集103

一、EEPROM和Flash 存储器分为两大类:RAM和ROM,本文主要讨论ROM。ROM最初不能编程,出厂什么内容就永远什么内容,不灵活。 后来出现了PROM,可以自己写入一次,要是写错了,只能换一片,自…

React中的生命周期函数

生命周期的三个阶段: 1.创建时(挂载阶段) ①执行时机:组件创建时(页面加载时) ②执行顺序:constructor()->render()->componentDidMount() import React, { Com…

nodejs+vue+elementui共享充电宝管理系统express

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 2 前端技术:nodejsvueelementui 前端:HTML5,CSS3、JavaScript、VUE 功能介绍 管理员:…

H5基本开发2——(HTML文档基本结构)

现实生活中,任何一个文档都是具有一定的格式,不同的文档,基本格式不同,例如:请假条、调休单、剧本、年中总结、十九大报告、等等,而我们所编写等html文档也是具有一定的编写基本格式的 事实上W3C组织一直致…

[附源码]java毕业设计教学辅助系统

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

TwoModalBERT进行角色分类

你是否遇到过数据集中有多个文本特性的情况?例如,根据消息的上下文正确地对消息进行分类,即理解前面的消息。比如说我们有下面的数据集,需要对其进行分类。 当只考虑message时,你可以看到它的情绪是积极的,因为“incr…

关于电影的HTML网页设计—— 电影小黄人6页 HTML+CSS+JavaScript

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

【Pytorch with fastai】第 10 章 :NLP 深入探讨 RNN

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

【JavaScript高级程序设计】重点-第五章笔记:Date、RegExp、原始值包装类、单例内置对象

文章目录基本引用类型1.Date1.1 继承的方法1.2 日期格式化方法1.3 日期/时间组件方法2.RegExp正则表达式2.1 RegExp 实例属性2.2 RegExp 实例方法2.3 RegExp 构造函数属性3.原始值包装类型3.1 Boolean3.2 Number3.3 String3.3.1 JavaScript 字符3.3.2 normalize()方法3.3.3 字符…