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.hqwc.cn/news/492760.html

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

相关文章

【IDEA】java 项目启动偶现Kotlin 版本问题 error:Kotlin:module was

一、问题描述&#xff1a; error:Kotlin:module was compiled with an incompatible version of kotlin the binary version of its metadata is二、问题原因&#xff1a; jar包版本冲突 三、解决方式&#xff1a; 1、Rebuild Project&#xff08;推荐☆&#xff09; 重新构…

【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(下)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

openGauss学习笔记-228 openGauss性能调优-系统调优-LLVM使用建议

文章目录 openGauss学习笔记-228 openGauss性能调优-系统调优-LLVM使用建议 openGauss学习笔记-228 openGauss性能调优-系统调优-LLVM使用建议 目前LLVM在数据库内核侧已默认打开&#xff0c;用户可结合上述的分析进行配置&#xff0c;总体建议如下&#xff1a; 设置合理的wor…

【论文精读】OS-Copilot: Towards Generalist Computer Agents with Self-Improvement

OS-Copilot: Towards Generalist Computer Agents with Self-Improvement 前言ABSTRACT1 INTRODUCTION2 THE OS-COPILOT FRAMEWORK2.1 PLANNER2.2 CONFIGURATOR2.2.1 DECLARATIVE MEMORY2.2.2 PROCEDURAL MEMORY2.2.3 WORKING MEMORY 2.3 ACTOR 3 THE FRIDAY AGENT3.1 A RUNNIN…

深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(上)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

《高考》期刊杂志投稿邮箱知网教育类期刊发表

《高考》杂志是由国家新闻出版总署批准的正规教育类期刊。主要宣传高中新课程改革的专业性&#xff0c;是教育管理工作者、高中一线教师交流经验、探讨问题的重要平台&#xff0c;期刊突出政策性、针对性、指导性&#xff0c;是一本以教育科研成果展示为主&#xff0c;兼具教育…

Sora 提示词每日分享 | 中英文对照

每日分享一个 sora 创意视频提示词之《冲浪者在历史大厅的巨浪中展现技艺》 sora提示词视频 prompt: In an ornate, historical hall, a massive tidal wave peaks and begins to crash. Two surfers, seizing the moment, skillfully navigate the face of the wave. 提示词…

变革中的容器技术

容器化技术的优点 容器化是一种将应用程序和其所需的依赖项&#xff0c;封装在一个可在任何基础架构上一致运行的轻量级可执行文件&#xff08;即容器&#xff09;的技术。容器化技术可以大大简化应用程序的部署、管理和维护&#xff0c;提高运维效率和可靠性。 容器化技术有…

如何实现多账户管理?海外代理IP推荐

伴随着互联网的发展&#xff0c;目前越来越多的用户开始拥有不止一个社交媒体或者电商平台等类型的账号&#xff0c;但实际上不论是社交平台还是电商平台对于用户的多账号使用行为都十分的抵制。如果用户不采取任何措施直接长时间进行多账户操作的话&#xff0c;可能会遇到以下…

有那种试卷还原软件吗?分享3款一键还原空白的工具!

在数字化学习的浪潮中&#xff0c;试卷还原软件作为一种新型的学习工具&#xff0c;正逐渐受到广大学生和教育工作者的青睐。这类软件不仅能够帮助我们快速整理、分析试卷&#xff0c;还能通过智能识别技术&#xff0c;将纸质试卷转化为电子文档&#xff0c;极大地提高了学习效…

微信小程序简单输入框布局(合并忘记密码和修改页面)

微信小程序简单入门级输入框布局&#xff0c;将忘记密码和修改页面合并到一个页面&#xff0c;根据传入的参数自动切换显示的界面信息。 上代码 1、js代码&#xff1a; Page({/*** 页面的初始数据*/data: {current: 0,},/*** 生命周期函数--监听页面加载*/onLoad(options) {//…

springboot集成quartz定时任务并接入后台管理系统(copy即用)

说明:项目启动后会根据设置的时间进行执行,业务代码根据自己的需求更改,数据库文件在最后(记得清空数据库哦~)这里需要注意的一点就是className字段表示的是下面的对应的DynamicTask的路径如:com.example.demo.quartz.task.DynamicTask,如有多个定时任务copy并更改Dynam…