TF-IDF,textRank,LSI_LDA 关键词提取

目录

任务

代码

keywordExtract.py

TF_IDF.py

LSI_LDA.py

结果


任务

用这三种方法提取关键词,代码目录如下,

keywordExtract.py 为运行主程序

corpus.txt 为现有数据文档

其他文件,停用词,方法文件

corpus.txt 可以自己搞一个,大概张这样,没一行为一条数据

stopword.txt 停用词表网上随便找

代码

keywordExtract.py

import jieba
import jieba.posseg as psg
from TF_IDF import tfidf_extract
from TextRank import textrank_extract
from LSI_LDA import topic_extract# 停用词表加载方法
def get_stopword_list():# 停用词表存储路径,每一行为一个词,按行读取进行加载# 进行编码转换确保匹配准确率stop_word_path = './stopword.txt'stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path,encoding='utf-8').readlines()]return stopword_list# 分词方法,调用结巴接口
def seg_to_list(sentence, pos=False):if not pos:# 不进行词性标注的分词方法seg_list = jieba.cut(sentence)else:# 进行词性标注的分词方法seg_list = psg.cut(sentence)return seg_list# 去除干扰词
def word_filter(seg_list, pos=False):'''根据分词结果对干扰词进行过滤:param seg_list::param pos: 判断是否过滤除名词外的其他词性:return:'''stopword_list = get_stopword_list()filter_list = []# 根据POS参数选择是否词性过滤## 不进行词性过滤,则将词性都标记为n,表示全部保留for seg in seg_list:if not pos:word = segflag = 'n'else:word = seg.wordflag = seg.flagif not flag.startswith('n'):continue# 过滤停用词表中的词,以及长度为<2的词if not word in stopword_list and len(word) > 1:filter_list.append(word)return filter_listif __name__ == '__main__':text = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \'中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \'办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \'重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \'领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \'市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \'、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \'这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \'的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \'事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \'常委会主任陈健倩介绍了大会的筹备情况。'pos = Trueseg_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)

 

TF_IDF.py

用现有数据文档 corpus.txt 训练后,再调用的,看代码注释

'''
词频-逆文档频次算法
提取对文档重要的关键词,由 TF 及 IDF 构成
TF:一个词在此文档中的词频
IDF:一个词在所有文档中出现的词频
两个相乘
1.训练语料库生成数据集对应的 idf 值字典,后续对新文档每个词计算 TF-IDF 时,直接从字典中读取
2.可依赖于训练语料库,也可对每次新的文档集直接计算
'''
import math
import functools
import jieba
import jieba.posseg as psg
from jieba import analyse# TF-IDF类
class TfIdf(object):# 四个参数分别是:训练好的idf字典,默认idf值,处理后的待提取文本,关键词数量def __init__(self, idf_dic, default_idf, word_list, keyword_num):self.word_list = word_listself.idf_dic, self.default_idf = idf_dic, default_idfself.tf_dic = self.get_tf_dic()self.keyword_num = keyword_num# 统计tf值def get_tf_dic(self):tf_dic = {}for word in self.word_list:tf_dic[word] = tf_dic.get(word, 0.0) + 1.0tt_count = len(self.word_list)for k, v in tf_dic.items():tf_dic[k] = float(v) / tt_countreturn tf_dic# 按公式计算tf-idfdef get_tfidf(self):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 * idftfidf_dic[word] = tfidftfidf_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()#  排序函数,用于topK关键词的按值排序,得分相同,再根据关键词排序
def cmp(e1, e2):import numpy as npres = np.sign(e1[1] - e2[1])if res != 0:return reselse:a = e1[0] + e2[0]b = e2[0] + e1[0]if a > b:return 1elif a == b:return 0else:return -1# 停用词表加载方法
def get_stopword_list():# 停用词表存储路径,每一行为一个词,按行读取进行加载# 进行编码转换确保匹配准确率stop_word_path = './stopword.txt'stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path,encoding='utf-8').readlines()]return stopword_list# 分词方法,调用结巴接口
def seg_to_list(sentence, pos=False):if not pos:# 不进行词性标注的分词方法seg_list = jieba.cut(sentence)else:# 进行词性标注的分词方法seg_list = psg.cut(sentence)return seg_list# 去除干扰词
def word_filter(seg_list, pos=False):'''根据分词结果对干扰词进行过滤:param seg_list::param pos: 判断是否过滤除名词外的其他词性:return:'''stopword_list = get_stopword_list()filter_list = []# 根据POS参数选择是否词性过滤## 不进行词性过滤,则将词性都标记为n,表示全部保留for seg in seg_list:if not pos:word = segflag = 'n'else:word = seg.wordflag = seg.flagif not flag.startswith('n'):continue# 过滤停用词表中的词,以及长度为<2的词if not word in stopword_list and len(word) > 1:filter_list.append(word)return filter_list# 数据加载,pos为是否词性标注的参数,corpus_path为数据集路径
def load_data(pos=False, corpus_path='./corpus.txt'):# 调用上面方式对数据集进行处理,处理后的每条数据仅保留非干扰词doc_list = []for line in open(corpus_path, 'r',encoding='utf-8'):content = line.strip()seg_list = seg_to_list(content, pos)filter_list = word_filter(seg_list, pos)doc_list.append(filter_list)return doc_list# idf值统计方法
def train_idf(doc_list):'''训练数据集生成对应的 IDF 值字典:param doc_list::return:'''idf_dic = {}# 总文档数,可以理解为几个文档,或者几条评论等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_idfdef tfidf_extract(word_list, pos=False, keyword_num=10):# 训练 idf 值,根据已有文档doc_list = load_data(pos)idf_dic, default_idf = train_idf(doc_list)# 调用训练好的 idf 值对新文档计算 TF-IDF 值,选出排名靠前的词语tfidf_model = TfIdf(idf_dic, default_idf, word_list, keyword_num)tfidf_model.get_tfidf()

LSI_LDA.py

同样也是用现有数据文档 corpus.txt 训练后,再调用的

'''
LDA 为 LSI 的升级版
主题数,是需要先确定的
参考:https://mp.weixin.qq.com/s/xLLirpYs8QfyjQOrDkkg5A
'''
import math
import functools
import jieba
import jieba.posseg as psg
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_numself.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 lsidef train_lda(self):lda = models.LdaModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)return ldadef 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] = wordtopicreturn 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.0for t1, t2 in zip(l1, l2):x1 = t1[1]x2 = t2[1]a += x1 * x1b += x1 * x1c += x2 * x2sim = a / math.sqrt(b * c) if not (b * c) == 0.0 else 0.0return sim# 计算输入文本和每个词的主题分布相似度sim_dic = {}for k, v in self.wordtopic_dic.items():if k not in word_list:continuesim = calsim(v, senttopic)sim_dic[k] = simfor k, v in sorted(sim_dic.items(), key=functools.cmp_to_key(cmp), reverse=True)[:self.keyword_num]:print(k + "/ ", end='')print()# 词空间构建方法和向量化方法,在没有gensim接口时的一般处理方法def word_dictionary(self, doc_list):dictionary = []for doc in doc_list:dictionary.extend(doc)dictionary = list(set(dictionary))return dictionarydef doc2bowvec(self, word_list):vec_list = [1 if word in word_list else 0 for word in self.dictionary]return vec_list#  排序函数,用于topK关键词的按值排序
def cmp(e1, e2):import numpy as npres = np.sign(e1[1] - e2[1])if res != 0:return reselse:a = e1[0] + e2[0]b = e2[0] + e1[0]if a > b:return 1elif a == b:return 0else:return -1# 停用词表加载方法
def get_stopword_list():# 停用词表存储路径,每一行为一个词,按行读取进行加载# 进行编码转换确保匹配准确率stop_word_path = './stopword.txt'stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path,encoding='utf-8').readlines()]return stopword_list# 分词方法,调用结巴接口
def seg_to_list(sentence, pos=False):if not pos:# 不进行词性标注的分词方法seg_list = jieba.cut(sentence)else:# 进行词性标注的分词方法seg_list = psg.cut(sentence)return seg_list# 去除干扰词
def word_filter(seg_list, pos=False):'''根据分词结果对干扰词进行过滤:param seg_list::param pos: 判断是否过滤除名词外的其他词性:return:'''stopword_list = get_stopword_list()filter_list = []# 根据POS参数选择是否词性过滤## 不进行词性过滤,则将词性都标记为n,表示全部保留for seg in seg_list:if not pos:word = segflag = 'n'else:word = seg.wordflag = seg.flagif not flag.startswith('n'):continue# 过滤停用词表中的词,以及长度为<2的词if not word in stopword_list and len(word) > 1:filter_list.append(word)return filter_list# 数据加载,pos为是否词性标注的参数,corpus_path为数据集路径
def load_data(pos=False, corpus_path='./corpus.txt'):# 调用上面方式对数据集进行处理,处理后的每条数据仅保留非干扰词doc_list = []for line in open(corpus_path, 'r',encoding='utf-8'):content = line.strip()seg_list = seg_to_list(content, pos)filter_list = word_filter(seg_list, pos)doc_list.append(filter_list)return doc_listdef 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)

结果

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

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

相关文章

DP读书:《半导体物理学(第八版)》(一)绪论 3min速通

DP读书&#xff1a;《半导体物理学&#xff08;第八版&#xff09;》刘恩科 3min速通半导体物理之绪论 DP读书&#xff1a;《半导体物理学&#xff08;第八版&#xff09;》刘恩科绪论第一章 半导体中的电子状态1.1 半导体的晶格结构和结合性质1.1.1 金刚石型结构和共价键1.1.2…

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制 文章目录 前言一、脉振高频电压注入法简介&#xff08;注入在旋转坐标系的d轴&#xff09;1.旋转高频电压&#xff08;电流&#xff09;注入法2.脉振高频电压注入法 二、高频注入理论1.永磁同步电机的高频模型2…

Pyglet控件的批处理参数batch和分组参数group简析

先来复习一下之前写的两个例程&#xff1a; 1. 绘制网格线 import pygletwindow pyglet.window.Window(800, 600) color (255, 255, 255, 255) # 白色 lines []for y in range(0, window.height, 40):lines.append(pyglet.shapes.Line(0, y, window.width, y, colorcolo…

LeetCode704. 二分查找(C++)

LeetCode704. 二分查找 题目链接代码 题目链接 https://leetcode.cn/problems/binary-search/description/ 代码 class Solution { public:int search(vector<int>& nums, int target) {int left 0;int right nums.size() - 1;while(left < right){int midd…

外包工作两个月,技术退步让我决心改变

大家好&#xff0c;我是一名大专生&#xff0c;2019年通过校招进入了湖南的一家软件公司。在这里&#xff0c;我从事了接近4年的功能测试工作。然而&#xff0c;今年8月份&#xff0c;我深刻地意识到&#xff0c;我不能继续这样下去了。 长时间在一个舒适的环境里&#xff0c;…

数据库系统概论(超详解!!!) 第一节 绪论

1.四个基本概念 1.数据&#xff08;Data&#xff09; 数据&#xff08;Data&#xff09;是数据库中存储的基本对象 数据的定义&#xff1a;描述事物的符号记录 数据的种类&#xff1a;数字、文字、图形、图像、音频、视频、学生的档案记录等 数据的含义称为数据的语义&…

记生产OOM的故障分析

一、引言 生产上告警&#xff0c;交易堵塞&#xff0c;服务无响应&#xff0c;使用jstack、jmap、jhat命令进行故障分析。 Java虚拟机&#xff08;Java Virtual Machine&#xff0c;简称JVM&#xff09;作为Java语言的核心组件&#xff0c;为Java程序提供了运行环境和内存管理…

docker存储驱动

目录 一、写时复制和用时分配 二、联合文件系统 2.1、aufs ​编辑 2.2、分层的问题 2.3、overlay 2.4 文件系统区别 三、容器跑httpd案例 3.1、案例1&#xff1a;端口映射 3.2、案例2&#xff1a;制作httpd应用镜像 3.3、案例3&#xff1a;docker数据卷挂载 3.4、案…

【hot100】跟着小王一起刷leetcode -- 49. 字母异位词分组

【【hot100】跟着小王一起刷leetcode -- 49. 字母异位词分组 49. 字母异位词分组题目解读解题思路代码实现 总结 49. 字母异位词分组 题目解读 49. 字母异位词分组 ok&#xff0c;兄弟们&#xff0c;咱们来看看这道题&#xff0c;很明显哈&#xff0c;这里的关键词是字母异位…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-27-处理单选和多选按钮-番外篇

1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo&#xff0c;然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何使用playwright来处理单选按钮和多选按钮进行自动化测试&#xff0c;想必大家都已经掌握的八九不离十了吧。这一篇其实也很简单&#xff1a…

浅谈 TCP 三次握手

文章目录 三次握手 三次握手 首先我们需要明确&#xff0c;三次握手的目的是什么&#xff1f; 是为了通信双方之间建立连接&#xff0c;然后传输数据。 那么建立连接的条件是什么呢&#xff1f; 需要确保通信的双方都确认彼此的接收和发送能力正常&#xff0c;满足这个条件&a…

今天面了个字节拿 38K 出来的测试,让我见识到了基础的天花板

最近内卷严重&#xff0c;各种跳槽裁员&#xff0c;相信很多小伙伴也在准备金九银十的面试计划。 作为一个入职5年的老人家&#xff0c;目前工资比较乐观&#xff0c;但是我还是会选择跳槽&#xff0c;因为感觉在一个舒适圈待久了&#xff0c;人过得太过安逸&#xff0c;晋升涨…

Jeecg项目部署

说明&#xff1a;Jeecg是一款低代码开发平台&#xff0c;简单说是一款现成的项目&#xff0c;该项目集成了许多功能&#xff0c;我们可以在这个项目之上开发自己的业务代码。 本文介绍Jeecg项目的部署&#xff0c;包括后端jeecg-boot项目、前端vue3项目。前端项目在本地Window…

Java的编程之旅19——使用idea对面相对象编程项目的创建

在介绍面向对象编程之前先说一下我们在idea中如何创建项目文件 使用快捷键CtrlshiftaltS新建一个模块&#xff0c;点击“”&#xff0c;再点New Module 点击Next 我这里给Module起名叫OOP,就是面向对象编程的英文缩写&#xff0c;再点击下面的Finish 点Apply或OK均可 右键src…

2024Python自动化测试面试必备知识点!

在准备 Python 自动化测试面试时&#xff0c;以下是一些必备的知识点&#xff0c;可以帮助您在面试中展现实力&#xff1a; 软件测试基础&#xff1a; 熟悉软件测试的基本概念&#xff0c;包括测试类型&#xff08;功能测试、性能测试、安全测试等&#xff09;、测试方法&#…

数据安全治理实践路线(中)

数据安全建设阶段主要对数据安全规划进行落地实施&#xff0c;建成与组织相适应的数据安全治理能力&#xff0c;包括组织架构的建设、制度体系的完善、技术工具的建立和人员能力的培养等。通过数据安全规划&#xff0c;组织对如何从零开始建设数据安全治理体系有了一定认知&…

微服务篇之任务调度

一、xxl-job的作用 1. 解决集群任务的重复执行问题。 2. cron表达式定义灵活。 3. 定时任务失败了&#xff0c;重试和统计。 4. 任务量大&#xff0c;分片执行。 二、xxl-job路由策略 1. FIRST&#xff08;第一个&#xff09;&#xff1a;固定选择第一个机器。 2. LAST&#x…

西门子S7-1500作为智能设备共享功能

本章节介绍了共享设备的功能&#xff0c;优势&#xff0c;使用要求&#xff0c;使用规则&#xff0c;如何将智能设备作为共享设备&#xff0c;实现一个智能设备同时与2个IO控制器进行通信的示例&#xff0c;以及常见问题。 一、共享设备功能概述 信号模块可以被不同的IO控制器…

【MIT-PHP-推荐】imi-ai 是一个 ChatGPT 开源项目

mi-ai 是一个 ChatGPT 开源项目&#xff0c;支持聊天、问答、写代码、写文章、做作业等功能。 项目架构合理&#xff0c;代码编写优雅&#xff0c;简单快速部署。前后端代码完全开源&#xff0c;不管是学习自用还是商用二开都很适合。 本项目现已支持 ChatGPT 聊天 AI 和 Emb…

都说了别用BeanUtils.copyProperties,这不翻车了吧

分享是最有效的学习方式。 博客&#xff1a;https://blog.ktdaddy.com/ 故事 新年新气象&#xff0c;小猫也是踏上了新年新征程&#xff0c;自从小猫按照老猫给的建议【系统梳理大法】完完整整地梳理完毕系统之后&#xff0c;小猫对整个系统的把控可谓又是上到可一个新的高度。…