【NLP】主题模型文本分类

2023-05-16

自然语言处理之主题模型文本分类

LDA主题模型

1.主题模型(Topic Model)

主题模型是以非监督学习的方式对文集的隐含语义结构进行聚类的统计模型。主题模型主要被用于自然语言处理中的语义分析和文本挖掘问题,例如按主题对文本进行收集、分类和降维。隐含狄利克雷分布是常见的主题模型。

2.隐含狄利克雷分布LDA(Latent Dirichlet Allocation)

1)贝叶斯模型

LDA模型基于贝叶斯模型,
在这里插入图片描述

2)多项式分布

多项分布,是二项分布扩展到多维的情况。 多项分布是指单次试验中的随机变量的取值不再是0-1的,而是有多种离散值可能。概率密度函数为:
在这里插入图片描述

3)狄利克雷分布

Dirichlet的概率密度函数为:

在这里插入图片描述

其中,
在这里插入图片描述

4)共轭分布

在贝叶斯概率理论中,如果后验概率 P ( θ ∣ x ) P(θ|x) P(θx)和先验概率 p ( θ ) p(θ) p(θ)满足同样的分布律,那么,先验分布和后验分布被叫做共轭分布,同时,先验分布叫做似然函数的共轭先验分布。狄利克雷(Dirichlet)分布是多项式分布的共轭分布。

5)LDA主题模型

假设有 M M M篇文档,对应第d个文档中有有 N d N_d Nd个词。

在这里插入图片描述

目标是找到每一篇文档的主题分布和每一个主题中词的分布。在LDA模型中,我们需要先假定一个主题数目 K K K,这样所有的分布就都基于 K K K个主题展开。
在这里插入图片描述

LDA假设文档主题的先验分布是Dirichlet分布,即对于任一文档 d d d, 其主题分布 θ d \theta_d θd为:
θ d = D i r i c h l e t ( α ⃗ ) \theta_d = Dirichlet(\vec \alpha) θd=Dirichlet(α )
其中, α \alpha α为分布的超参数,是一个 K K K维向量。

LDA假设主题中词的先验分布是Dirichlet分布,即对于任一主题 k k k, 其词分布 β k \beta_k βk为:
β k = D i r i c h l e t ( η ⃗ ) \beta_k=Dirichlet(\vec \eta) βk=Dirichlet(η )

其中, η \eta η为分布的超参数,是一个 V V V维向量。 V V V代表词汇表里所有词的个数。

对于数据中任一一篇文档 d d d中的第 n n n个词,我们可以从主题分布 θ d \theta_d θd中得到它的主题编号 z d n z_{dn} zdn的分布为:
z d n = m u l t i ( θ d ) z_{dn} = multi(\theta_d) zdn=multi(θd)

而对于该主题编号,得到我们看到的词 w d n w_{dn} wdn的概率分布为:
w d n = m u l t i ( β z d n ) w_{dn} = multi(\beta_{z_{dn}}) wdn=multi(βzdn)
理解LDA主题模型的主要任务就是理解上面的这个模型。这个模型里,我们有 M M M个文档主题的Dirichlet分布,而对应的数据有 M M M个主题编号的多项分布,这样( α → θ d → z ⃗ d \alpha \to \theta_d \to \vec z_{d} αθdz d)就组成了Dirichlet-multi共轭,可以使用前面提到的贝叶斯推断的方法得到基于Dirichlet分布的文档主题后验分布。

如果在第d个文档中,第k个主题的词的个数为: n d ( k ) n_d^{(k)} nd(k), 则对应的多项分布的计数可以表示为
n ⃗ d = ( n d ( 1 ) , n d ( 2 ) , . . . n d ( K ) ) \vec n_d = (n_d^{(1)}, n_d^{(2)},...n_d^{(K)}) n d=(nd(1),nd(2),...nd(K))
利用Dirichlet-multi共轭,得到 θ d \theta_d θd的后验分布为:
D i r i c h l e t ( θ d ∣ α ⃗ + n ⃗ d ) Dirichlet(\theta_d | \vec \alpha +\vec n_d) Dirichlet(θdα +n d)
同样的道理,对于主题与词的分布,我们有 K K K个主题与词的Dirichlet分布,而对应的数据有 K K K个主题编号的多项分布,这样( η → β k → w ⃗ ( k ) \eta \to \beta_k \to \vec w_{(k)} ηβkw (k))就组成了Dirichlet-multi共轭,可以使用前面提到的贝叶斯推断的方法得到基于Dirichlet分布的主题词的后验分布。

如果在第k个主题中,第v个词的个数为: n k ( v ) n_k^{(v)} nk(v), 则对应的多项分布的计数可以表示为
n ⃗ k = ( n k ( 1 ) , n k ( 2 ) , . . . n k ( V ) ) \vec n_k = (n_k^{(1)}, n_k^{(2)},...n_k^{(V)}) n k=(nk(1),nk(2),...nk(V))
利用Dirichlet-multi共轭,得到 β k \beta_k βk的后验分布为:
D i r i c h l e t ( β k ∣ η ⃗ + n ⃗ k ) Dirichlet(\beta_k | \vec \eta+\vec n_k) Dirichlet(βkη +n k)
由于主题产生词不依赖具体某一个文档,因此文档主题分布和主题词分布是独立的。

程序实现

运行环境:Anaconda 4.9.2

1.生成段落数据库

在16篇小说中选取了7篇小说在DatabaseChinese中,随机选取三篇,每篇随机抽取不小于500字的段落150段,存到DataExcel中。

def txt_convert_2_excel(file_path, data_path, K=3):
    logging.info('Converting txt to excel...')
    files = []
    for x in os.listdir(file_path):
        files.append(x)
    selected_files = random.sample(files, k=3)

    txt = []
    txtname = []
    n = 150

    for file in selected_files:
        filename = os.path.join(file_path, file)
        with open(filename, 'r', encoding='ANSI') as f:
            full_txt = f.readlines()
            lenth_lines = len(full_txt)
            i = 200
            for j in range(n):
                txt_j = ''
                while(len(txt_j) < 500):
                    txt_j += full_txt[i]
                    i += 1
                txt.append(txt_j)
                txtname.append(file.split('.')[0])
                i += int(lenth_lines / (3 * n))

    dic = {'Content': txt, 'Txtname': txtname}
    df = pd.DataFrame(dic)
    out_path = data_path+'\\data.xlsx'
    df.to_excel(out_path, index=False)
    logging.info('Convert done!')
    return out_path

选取的数据形式如下,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGknKLBE-1621347180920)(pic/image-20210428204530774.png)]

2.分词

创建Paragraph类,断句分词。

class Paragraph:
    def __init__(self, txtname='', content='', sentences=[], words=''):
        self.fromtxt = txtname
        self.content = content
        self.sentences = sentences
        self.words = words
        global punctuation
        self.punctuation = punctuation
        global stopwords
        self.stopwords = stopwords

    def sepSentences(self):
        line = ''
        sentences = []
        for w in self.content:
            if w in self.punctuation and line != '\n':
                if line.strip() != '':
                    sentences.append(line.strip())
                    line = ''
            elif w not in self.punctuation:
                line += w
        self.sentences = sentences

    def sepWords(self):
        words = []
        dete_stopwords = 1
        if dete_stopwords:
            for i in range(len(self.sentences)):
                words.extend([x for x in jieba.cut(
                    self.sentences[i]) if x not in self.stopwords])
        else:
            for i in range(len(self.sentences)):
                words.extend([x for x in jieba.cut(self.sentences[i])])
        reswords = ' '.join(words)
        self.words = reswords

3.词频模型

主要参数:特征词数40个。

    cntVector = CountVectorizer(max_features=40)
    cntTf = cntVector.fit_transform(corpus)

4.LDA模型求解

主要参数:主题3个,迭代次数1000次。

    lda = LatentDirichletAllocation(
        n_components=3, learning_offset=50., max_iter=1000, random_state=0)
    docres = lda.fit_transform(cntTf)

5.SVM分类

主要参数:训练集150*0.2=30个段落。

    X = docres
    y = [data_list[i].fromtxt for i in range(len(data_list))]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
    svm_model = LinearSVC()  # model = SVC()
    svm_model.fit(X_train, y_train)
    y_pred = svm_model.predict(X_test)

6.输出结果

输出:测试集真值与分类估计对比,输出每个主题主要词10个,绘制SVM三维三分类图片结果。

    # show test result
    print('Topic real:', '\t', 'Topic predict:', '\n')
    for i in range(len(y_test)):
        print(y_test[i], '\t', y_pred[i], '\n')

    # show LDA result
    feature_names = cntVector.get_feature_names()
    print_top_words(lda, feature_names, 10)

    # show SVM result
    draw_svm_result(X, y, svm_model)

运行结果

1.笑傲江湖/神雕侠侣/ 射雕英雄传

结果评估:

P r e c i s i o n : 0.962 Precision:0.962 Precision:0.962

R e c a l l : 0.953 Recall:0.953 Recall:0.953

F 1 : 0.956 F1:0.956 F1:0.956

SVM依据LDA降频后特征的分类结果:

主题关键字:

Topic #0:
令狐冲 师父 剑法 岳不群 弟子 田伯光 仪琳 师妹 长剑 便是
Topic #1:
杨过 小龙女 李莫愁 陆无双 师父 武功 当下 心中 功夫 弟子
Topic #2:
郭靖 黄蓉 欧阳锋 丘处机 师父 心中 两人 黄药师 武功 心想

完整代码

https://github.com/AngeloG98/TopicModelLda

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

【NLP】主题模型文本分类 的相关文章

随机推荐

  • 作为一个普通的程序员,到底应不应该转型AI工程师?

    动不动就是50万的毕业生年薪 xff0c 动不动就是100万起步价的海归AI高级人才 xff0c 普通员到底应不应该转型AI工程师 xff0c 普通程序员到底应该如何转型AI工程师 xff1f 下面就分享几个特别典型的普通程序员成功转型AI
  • 树莓派Odroid等卡片式电脑上搭建NAS教程系列1-Ubuntu系统安装

    我用的是韩国hardkernel公司做的Odroid XU板子 xff0c 类似于树莓派香蕉派 xff0c 看下它的真面目 相关参数点他 gt Odroid XU 搭建NAS之前先来安装好Ubuntu系统 下载安装文件 在Odroid里安装
  • 立创eda学习笔记一:pcb板基础知识

    整理了一下零基础学习pcb板画图需要了解的一些基础知识 xff0c 否则后面画图很困扰 什么是pcb板 xff1f PCB xff08 Printed Circuit Board xff09 xff0c 中文名称为印制电路板 xff0c 又
  • 立创eda学习笔记二:画pcb板流程(极简入门版)

    一般PCB基本设计流程如下 xff1a 前期准备 gt PCB结构设计 gt PCB布局 gt 布线 gt 布线优化和丝印 gt 网络和DRC检查和结构检查 gt 制版 一 画原理图 完成后检查元件的封装 连线是否正确 核实电路结构 xff
  • 立创eda学习笔记十一:立创eda、立创商城、嘉立创的区别

    简单来说 xff1a 立创eda是一个画原理图和pcb的eda软件 xff0c 类似于ad 立创商城是一个卖元器件网上平台 xff0c 类似于淘宝 嘉立创是一个生产pcb板 给pcb板贴片的生产厂家 一般情况下 xff0c 你可以在立创ed
  • 立创eda学习笔记十七:铺铜

    铺铜是pcb设计很常用的指令 xff0c 或者是必然用到的指令 xff0c 很多时候布线的时候不去画gnd的线 xff0c 把其他线画好了之后 xff0c 再统一铺铜作为gnd xff0c 这样方便很多 铺铜这个概念可以理解为大面积的布线
  • 立创eda学习笔记二十六:手把手教你使用立创eda的官方教程

    可以通过以下办法找到教程 xff1a 1 xff0c 在软件界面点帮助 使用教程 2 xff0c 在网站首页 帮助 教程进入 如何使用教程 xff1a 这里是一级目录 xff0c 其实对新手最有用的是前面3个部分 xff0c 后面的仿真先不
  • 立创eda学习笔记二十四:拼板

    这里主要是两部分 xff1a 自带拼板和手动拼板 xff0c 软件自带拼板功能 xff0c 那么手动拼板当然就是自己重新画图拼板了 一般用自带拼板功能就可以了 xff0c 把单板画好之后很容易就拼好了 xff0c 完全不用动任何器件和丝印编
  • Prometheus实战教程:监控mysql数据库

    今天我们使用prometheus 43 Grafana 43 mysql exporter实现监控mysql数据库各项指标数据 mysql exporter xff1a 采集mysql数据库各项指标数据 prometheus xff1a 获
  • prometheus常用exporter下载地址大全

    1 node exporter下载 https github com prometheus node exporter releases 2 blackbox exporter下载 https github com prometheus b
  • 论文润色 ‖ 一分钟教你如何写好SCI论文里的主题句,事半功倍

    今天 xff0c 小编来分享一下论文润色 xff0c SCI论文的主题句 xff08 Topic Sentences xff09 怎么写 xff1a 01什么是主题句 xff1f 主题句通常是段落开头的一句话 xff0c 是整个段落的小主题
  • Go xml文件处理

    在开发中会常遇到xml数据序列化和反序列化 xff0c 这里我们介绍go语言处理xml数据 encoding xml 包实现了一个简单的xml 1 0解析器 xff0c 可以理解xml名称空间 读取xml 示例 xff1a package
  • UC/OS-III 消息队列

    消息队列 一 消息队列基本概念讲解1 消息队列基本概念2 消息池2 1 消息池概念2 2 消息池初始化2 3 消息队列的运作机制2 4 消息队列的阻塞机制2 5 消息队列的应用场景 二 消息队列创建步骤1 定义消息队列2 创建消息队列 三
  • Altium Designer绘制stm32f103c8t6最小系统原理图

    文章目录 前言芯片封装自定义封装原理图绘制总结 前言 本文提供了初学者绘制stm32最小系统 xff0c 同时初学者的同学可以跟着小白学习绘制原理图哦 芯片封装 提示 xff1a 下载安装好Altium Designer之后才能进行以下操作
  • Jetson Xavier NX安装opencv3.x以及踩过的坑

    Jetson Xavier NX默认安装的是opencv4 x xff0c 在很多项目中其与opencv3 x xff0c 其中opencv3与opencv4中有部分函数是完全不同的 xff08 例如点一些Point的定义 xff0c Cv
  • 【导航算法】无人机路径跟踪L1导航算法

    L1导航算法是非常经典的非线性无人机路径跟随算法 xff0c 最早由MIT于2004年提出 xff0c 论文为 A New Nonlinear Guidance Logic for Trajectory Tracking xff0c 其导航
  • 【人工智能】1.问题求解:状态空间图和盲目搜索

    什么是问题求解 xff1f 问题求解可以理解为利用知识 xff0c 尽可能有效的找到问题的解 xff0c 或者最优解的过程 xff0c 主要包括 xff1a 1 xff09 问题描述方法 xff1a 状态空间法 xff0c 与或树表示法 x
  • 【路径规划】A*三维全局路径规划(附Python实现源码)

    1 A 启发式搜索 A 算法介绍 xff1a 启发式搜索算法 xff0c 除了wiki之外比较全的一个参考资料 xff1a A 启发式搜索算法详解 人工智能 这里是用Python写了一个简单的路径规划例子供参考 2 Matplotlib库
  • 【数据结构】3.图、最小生成树

    一 图的基本概念 1 什么是图 图表示一种多对多的关系 图包括 xff1a 1 xff09 一组顶点 xff1a 通常用 V Vertex 表示顶点集合 2 xff09 一组边 xff1a 通常用 E Edge 表示边的集合 3 xff09
  • 【NLP】主题模型文本分类

    自然语言处理之主题模型文本分类 LDA主题模型 1 主题模型 xff08 Topic Model xff09 主题模型是以非监督学习的方式对文集的隐含语义结构进行聚类的统计模型 主题模型主要被用于自然语言处理中的语义分析和文本挖掘问题 xf