数据分析-深度学习 NLP Day2关键词提取案例

news2025/3/1 4:39:23

训练一个关键词提取算法需要以下几个步骤:

1)加载已有的文档数据集;

2)加载停用词表;

3)对数据集中的文档进行分词;

4)根据停用词表,过滤干扰词;

5)根据数据集训练算法;

根据训练好的关键词提取算法对新文档进行关键词提取要经过以下环节:

1)对新文档进行分词;

2)根据停用词表,过滤干扰词;

3)根据训练好的算法提取关键词;

1 加载模块

import math
import jieba
import jieba.posseg as psg
from gensim import corpora, models
from jieba import analyse
import functools

2 定义好停用词表的加载方法

def get_stopword_list():
    # 停用词表存储路径,每一行为一个词,按行读取进行加载
    # 进行编码转换确保匹配准确率
    stop_word_path = './stopword.txt'
    stopword_list = [sw.replace('/n', '') for sw in open(stop_word_path).readlines()]
    return stopword_list

3 定义一个分词方法

def seg_to_list(sentence, pos=False):
    ''' 分词方法,调用结巴接口。pos为判断是否采用词性标注 '''
    if not pos:
        # 不进行词性标注的分词方法
        seg_list = jieba.cut(sentence)
    else:
        # 进行词性标注的分词方法
        seg_list = psg.cut(sentence)
    return seg_list

4 定义干扰词过滤方法

def word_filter(seg_list, pos=False):
    ''' 
        1. 根据分词结果对干扰词进行过滤;
        2. 根据pos判断是否过滤除名词外的其他词性;
        3. 再判断是否在停用词表中,长度是否大于等于2等;
    '''
    stopword_list = get_stopword_list() # 获取停用词表
    filter_list = [] # 保存过滤后的结果
    #  下面代码: 根据pos参数选择是否词性过滤
    ## 下面代码: 如果不进行词性过滤,则将词性都标记为n,表示全部保留
    for seg in seg_list:
        if not pos:
            word = seg
            flag = 'n'
        else:
            word = seg.word # 单词
            flag = seg.flag # 词性
        if not flag.startswith('n'):
            continue
        # 过滤停用词表中的词,以及长度为<2的词
        if not word in stopword_list and len(word)>1:
            filter_list.append(word)
            
    return filter_list

5 加载数据集,并对数据集中的数据分词和过滤干扰词

def load_data(pos=False, corpus_path = './corpus.txt'):
    '''
        目的:
            调用上面方法对数据集进行处理,处理后的每条数据仅保留非干扰词
        参数:
            1. 数据加载
            2. pos: 是否词性标注的参数
            3. corpus_path: 数据集路径
    '''
    doc_list = [] # 结果
    for line in open(corpus_path, 'r'):
        content = line.strip() # 每行的数据
        seg_list = seg_to_list(content, pos) # 分词
        filter_list = word_filter(seg_list, pos) # 过滤停用词
        doc_list.append(filter_list) # 将处理后的结果保存到doc_list
    return doc_list

6 IDF 训练

# TF-IDF的训练主要是根据数据集生成对应的IDF值字典,后续计算每个词的TF-IDF时,直接从字典中读取。

def train_idf(doc_list):
    idf_dic = {} # idf对应的字典
    tt_count = len(doc_list) # 总文档数
    # 每个词出现的文档数
    for doc in doc_list: 
        for word in set(doc):
            idf_dic[word] = idf_dic.get(word, 0.0) + 1.0
    # 按公式转换为idf值,分母加1进行平滑处理
    for k, v in idf_dic.items():
        idf_dic[k] = math.log(tt_count/(1.0 + v))
    # 对于没有在字典中的词,默认其尽在一个文档出现,得到默认idf值
    default_idf = math.log(tt_count/(1.0))
    return idf_dic, default_idf

7 LSI 训练

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

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

8 LDA训练

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

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

9 cmp函数

# 为了输出top关键词时,先按照关键词的计算分值排序,在得分相同时,根据关键词进行排序

def cmp(e1, e2):
    ''' 排序函数,用于topK关键词的按值排序 '''
    import numpy as np
    res = np.sign(e1[1] - e2[1])
    if res != 0:
        return res
    else:
        a = e1[0] + e2[0]
        b = e2[0] + e1[0]
        if a > b:
            return 1
        elif a == b:
            return 0
        else:
            return -1

10 TF-IDF实现方法

根据具体要处理的文本,计算每个词的TF值,并获取前面训练好的IDF数据,直接获取每个词的IDF值,综合计算每个词的TF-IDF。

class TfIdf(object):
    # 四个参数分别是:训练好的idf字典,默认idf字典,处理后的待提取文本, 关键词数量
    def __init__(self, idf_dic, default_idf, word_list, keyword_num):
        self.idf_dic, self.default_idf = idf_dic, default_idf
        self.word_list = word_list
        self.tf_dic = self.get_tf_dic() # 统计tf值
        self.keyword_num = keyword_num
    
    def get_tf_dic(self):
        # 统计tf值
        tf_dic = {}
        for word in self.word_list:
            tf_dic[word] = tf_dic.get(word, 0.0) + 1.0
        tt_count = len(self.word_list)
        for k, v in tf_dic.items():
            tf_dic[k] = float(v) / tt_count # 根据tf求值公式
        
        return tf_dic

    def get_tfidf(self):
        # 计算tf-idf值
        tfidf_dic = {}
        for word in self.word_list:
            idf = self.idf_dic.get(word, self.default_idf)
            tf  = self.tf_dic.get(word, 0)
            
            tfidf = tf * idf
            tfidf_dic[word] = tfidf
        
        tfidf_dic.items()
        # 根据tf-idf排序,去排名前keyword_num的词作为关键词
        for k, v in sorted(tfidf_dic.items(), key=functools.cmp_to_key(cmp), reverse=True)[:self.keyword_num]:
            print(k + '/', end='')
        print()

11 完整的主题模型实现方法

分别实现了LSI,LDA算法,根据传入参数model进行选择,几个参数如下:

doc_list 是前面数据集加载方法的返回结果

keyword_num同上,为关键词数量

model为本主题模型的具体算法,分别可以传入LSI,LDA,默认为LSI

num_topics为主题模型的主题数量

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)
        
    
    # LSI的训练时根据现有的数据集生成文档-主题分布矩阵和主题-词分布矩阵,Gensim中有实现好的方法,可以直接调用。
    def train_lsi(self):
        lsi = models.LsiModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)
        return lsi
    
    # LDA的训练时根据现有的数据集生成文档-主题分布矩阵和主题-词分布矩阵,Gensim中有实现好的方法,可以直接调用。
    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
    
    def get_simword(self, word_list):
        # 计算词的分布和文档的分布的相似度,去相似度最高的keyword_num个词作为关键词
        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()
        
    def word_dictionary(self, doc_list):
        # 词空间构建方法和向量化方法,在没有gensim接口时的一般处理方法
        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

12 对上面的各个方法进行封装,统一算法调用接口

def tfidf_extract(word_list, pos=False, keyword_num=10):
    doc_list = load_data(pos)
    idf_dic, default_idf = train_idf(doc_list)
    tfidf_model = TfIdf(idf_dic, default_idf, word_list, keyword_num)
    tfidf_model.get_tfidf()
    
def textrank_extract(text, pos=False, keyword_num=10):
    textrank = analyse.textrank
    keywords = textrank(text, keyword_num)
    # 输出抽取出的关键词
    for keyword in keywords:
        print(keyword + "/", end='')
    print()
    
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)

13 主函数调用

if __name__ == "__main__":
    
    text = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \
           '中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \
           '办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \
           '重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \
           '领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \
           '市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \
           '、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \
           '这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \
           '的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \
           '事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \
           '常委会主任陈健倩介绍了大会的筹备情况。'
    pos = False
    seg_list = seg_to_list(text, pos)
    filter_list = word_filter(seg_list, pos)
    
    print("TF-IDF模型结果:")
    tfidf_extract(filter_list)
    print("TextRank模型结果:")
    textrank_extract(text)
    print("LSI模型结果:")
    topic_extract(filter_list, 'LSI', pos)
    print("LDA模型结果:")
    topic_extract(filter_list, 'LDA', pos)

14 输出结果:

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

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

相关文章

C语言学习_DAY_5_循环结构while和for语句【C语言学习笔记】

高质量博主&#xff0c;点个关注不迷路&#x1f338;&#x1f338;&#x1f338;&#xff01; 目录 I. 案例引入 II. while语句 III. do while语句 IV. for语句 前言: 书接上回&#xff0c;判断结构已经解决&#xff0c;接下来是另一种很重要的结构&#xff1a;循环结构的实…

深入Spring底层透析后置处理器之豁然开朗篇

目录前言Spring的后置处理器Bean工厂后置处理器Bean后置处理器自定义Component实现注解开发前言 看这篇文章之前&#xff0c;需要了解Bean创建的过程&#xff0c;本篇文章是接着bean创建的基本流程的续写 Bean创建的基本过程&#xff1a;http://t.csdn.cn/1lK2d Spring的后置处…

Python3 命名空间和作用域实例及演示

命名空间 先看看官方文档的一段话&#xff1a; 命名空间(Namespace)是从名称到对象的映射&#xff0c;大部分的命名空间都是通过 Python 字典来实现的。 A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries…

凌恩生物经典文章:孟德尔诞辰200周年,Nature Genetics礼献豌豆高质量精细图谱

本期为大家分享的文章是2022年发表在《Nature Genetics》上的一篇文章“Improved pea reference genome and pan-genome highlight genomic features and evolutionary characteristics”&#xff0c;作者通过结合三代pacbio测序、染色体构象捕获&#xff08;Hi-C&#xff09;测…

Meta分析在生态环境领域里的应用

Meta分析&#xff08;Meta Analysis&#xff09;是当今比较流行的综合具有同一主题的多个独立研究的统计学方法&#xff0c;是较高一级逻辑形式上的定量文献综述。20世纪90年代后&#xff0c;Meta分析被引入生态环境领域的研究&#xff0c;并得到高度的重视和长足的发展&#x…

企业什么要建设自有即时通讯软件系统

随着科技的不断发展&#xff0c;各种即时通讯软件也不断发展进步&#xff0c;而这也与企业的发展息息相关&#xff0c;因为每个人&#xff0c;每个企业都有属于自己的机密&#xff0c;属于自己的隐私。 钉钉&#xff0c;企业微信&#xff0c;等公有的即时通讯软件给企业带来便利…

微信社区小程序/h5/圈子论坛贴吧交友/博客/社交/陌生人社交/宠物/话题/私域/同城交友

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 小程序/app/H5多端圈子社区论坛系统,交友/博客/社交/陌生人社交,即时聊天,私域话题,社区论坛圈子,信息引流小程序源码,广场/微校园/微小区/微同城/ 圈子论坛社区系统&#xff0c;含完整…

扬帆优配|3300点半日游!上证指数冲高回落;再迎重磅利好!

今天早盘&#xff0c;A股冲高回落&#xff0c;上证指数3300点得而复失&#xff0c;深证成指也于12000点无功而返。 盘面上&#xff0c;煤炭、钢铁、房地产、才智政务等板块涨幅居前&#xff0c;酿酒、酒店餐饮、日用化工、IT设备等板块跌幅居前。北上资金净流入7.77亿元。 房地…

UML中常见的9种图

UML是Unified Model Language的缩写&#xff0c;中文是统一建模语言&#xff0c;是由一整套图表组成的标准化建模语言。UML用于帮助系统开发人员阐明&#xff0c;展示&#xff0c;构建和记录软件系统的产出。通过使用UML使得在软件开发之前&#xff0c; 对整个软件设计有更好的…

【数据库】Redis数据类型

目录 一&#xff0c; Key操作 1&#xff0c; 相关命令 2&#xff0c; 示例演示 二&#xff0c;字符串 String 1&#xff0c; 结构图 2&#xff0c;相关命令 3&#xff0c;示例演示 三&#xff0c; 列表 List 1&#xff0c; 结构图 2&#xff0c; 相关命令 3&#xf…

VO、DTO、BO、PO、DO区别

VO、DTO、BO、PO、DO区别 VO&#xff1a;&#xff08;View Object&#xff09;视图对象&#xff0c;一般位于Controller层&#xff0c;用于展示视图。DTO&#xff1a;&#xff08;Data Transfer Object&#xff09;数据传输对象&#xff0c; 即RPC 接口请求或传输出去的对象&a…

PMP值得考吗?含金量如何?

关于哪些证书可以考&#xff0c;这里我也不说其他的证书因为术业有专攻&#xff0c;其他证书的含金量估计我也没有更加专业的人士懂&#xff0c;我就推荐一下关于项目管理pmp证书的一些含金量吧&#xff01;对于想备考PMP的朋友或许有一些帮助。 一&#xff0c;PMP证书的价值体…

简易高并发内存池

文章目录从零实现一个高并发的内存池定长内存池定长内存池设计申请内存池用户申请用户归还&#xff08;释放&#xff09;总体代码测试对比&#xff08;malloc&#xff09;高并发内存池框架简介thread cache的设计申请部分释放部分第一层的测试central cache的设计申请部分释放部…

【Kubernetes】【十九】安全认证

第九章 安全认证 本章节主要介绍Kubernetes的安全认证机制。 访问控制概述 ​ Kubernetes作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对Kubernetes的各种客户端进行认证和鉴权操作。 客户端 在Kubernetes集群…

【Kubernetes】【十七】数据存储 基本存储 EmptyDir HostPath NFS

第八章 数据存储 ​ 在前面已经提到&#xff0c;容器的生命周期可能很短&#xff0c;会被频繁地创建和销毁。那么容器在销毁时&#xff0c;保存在容器中的数据也会被清除。这种结果对用户来说&#xff0c;在某些情况下是不乐意看到的。为了持久化保存容器的数据&#xff0c;ku…

2023只会“点点点”,被裁只是时间问题,高薪的自动化测试需要掌握那些技能?

互联网已然是存量市场了&#xff0c;对人员规模的需求正在放缓。在存量市场里&#xff0c;冗余人员和低效人员会被淘汰、被外包。而优秀的人才也会一直受到招聘方的青睐。所以我们就看到了近期行业里冰火两重天的一幕&#xff0c;一边是大量的低端测试工程师被淘汰、求职屡屡碰…

ssh设置:免密登入、修改默认端口、禁止root登入、限制错误登入次数

服务器&#xff1a; 客户端&#xff1a; 在下面不再说明服务器和客户端。 1.修改ssh默认端口 是在服务器中设置。 该设置涉及三部分&#xff1a;sshd配置文件修改/增加新端口、Selinux添加新端口、Firewall开放新端口。 vim /etc/ssh/sshd.config&#xff0c;找到#Port行&…

使用PHP+yii2调用asmx服务接口

一.创建服务端 1&#xff1a;创建一个ASP.NET web应用程序 2:选择空的模板 3&#xff1a;系统生成项目目录 4&#xff1a;右键项目-添加项-新建项 5&#xff1a;选择Web 服务&#xff08;ASMX&#xff09; 6&#xff1a;选择之后项目中会有一个Test.asmx服务程序&#xff0c;…

【闲聊杂谈】深入剖析SpringCloud Alibaba之Nacos源码

Nacos核心功能点 服务注册 Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务&#xff0c;提供自身的元数据&#xff0c;比如ip地址、端口等信息。Nacos Server接收到注册请求后&#xff0c;就会把这些元数据信息存储在一个双层的内存Map中&#xff1b; 服…

(十八)、首页点赞高亮显示的功能实现【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1&#xff0c;首页点赞高亮显示的逻辑 思路&#xff1a;首先&#xff0c;查询所有在首页index页面中展示的文章id&#xff0c;存为一个id数组&#xff1b;然后利用dbcloud command命令和文章id数组&#xff0c;统一查询文章点赞表&#xff1b;其中加上两个筛选条件&#xff08…