当前位置:   article > 正文

提取文本关键字

提取文本关键字
  1. 实验代码:
  2. # -*- coding: utf-8 -*-
  3. import math
  4. import jieba
  5. import jieba.posseg as psg
  6. from gensim import corpora, models
  7. from jieba import analyse
  8. import functools
  9.  
  10.  
  11. def get_stopword_list():
  12.     stop_word_path = 'stop_words.utf8'
  13.     stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path, encoding='utf-8').readlines()]
  14.     return stopword_list
  15.  
  16.  
  17. # 分词方法
  18. def seg_to_list(sentence, pos=False):
  19.     if not pos:
  20.         # 不进行词性标注的分词方法
  21.         seg_list = jieba.cut(sentence)
  22.     else:
  23.         # 进行词性标注的分词方法
  24.         seg_list = psg.cut(sentence)
  25.     return seg_list
  26.  
  27.  
  28. # 去除干扰词,根据pos判断是否过滤除名词外的其他词性,再判断词是否在停用词表中,长度是否大于等于2等。
  29. def word_filter(seg_list, pos=False):
  30.     stopword_list = get_stopword_list()
  31.     filter_list = []
  32.     # 根据pos参数选择是否词性过滤
  33.     # 不进行词性过滤,则将词性都标记为n,表示全部保留
  34.     for seg in seg_list:
  35.         if not pos:
  36.             word = seg
  37.             flag = 'n'
  38.         else:
  39.             word = seg.word
  40.             flag = seg.flag
  41.         if not flag.startswith('n'):
  42.             continue
  43.         # 过滤高停用词表中的词,以及长度为<2的词
  44.         if word not in stopword_list and len(word) > 1:
  45.             filter_list.append(word)
  46.     return filter_list
  47.  
  48.  
  49. # 数据加载
  50. def load_data(pos=False, corpus_path='corpus.txt'):
  51.     doc_list = []
  52.     for line in open(corpus_path, 'r', encoding='utf-8'):
  53.         content = line.strip()
  54.         seg_list = seg_to_list(content, pos)
  55.         filter_list = word_filter(seg_list, pos)
  56.         doc_list.append(filter_list)
  57.     return doc_list
  58.  
  59.  
  60. # topK
  61. def cmp(e1, e2):
  62.     import numpy as np
  63.     res = np.sign(e1[1] - e2[1])
  64.     if res != 0:
  65.         return res
  66.     else:
  67.         a = e1[0] + e2[0]
  68.         b = e2[0] + e1[0]
  69.         if a > b:
  70.             return 1
  71.         elif a == b:
  72.             return 0
  73.         else:
  74.             return -1
  75.  
  76.  
  77. # 主题模型
  78. class TopicModel(object):
  79.     def __init__(self, doc_list, keyword_num, model="LSI", num_topics=4):
  80.         # 使用gensim接口,将文本转为向量化表示
  81.         self.dictionary = corpora.Dictionary(doc_list)
  82.         # 使用BOW模型向量化
  83.         corpus = [self.dictionary.doc2bow(doc) for doc in doc_list]
  84.         # 对每个词,根据tf-idf进行加权,得到加权后的向量表示
  85.         self.tfidf_model = models.TfidfModel(corpus)
  86.         self.corpus_tfidf = self.tfidf_model[corpus]
  87.  
  88.         self.keyword_num = keyword_num
  89.         self.num_topics = num_topics
  90.         # 选择加载的模型
  91.         if model == 'LSI':
  92.             self.model = self.train_lsi()
  93.         else:
  94.             self.model = self.train_lda()
  95.         # 得到数据集的主题-词分布
  96.         word_dic = self.word_dictionary(doc_list)
  97.         self.wordtopic_dic = self.get_wordtopic(word_dic)
  98.  
  99.     def train_lsi(self):
  100.         lsi = models.LsiModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)
  101.         return lsi
  102.  
  103.     def train_lda(self):
  104.         lda = models.LdaModel(self.corpus_tfidf, id2word=self.dictionary, num_topics=self.num_topics)
  105.         return lda
  106.  
  107.     def get_wordtopic(self, word_dic):
  108.         wordtopic_dic = {}
  109.         for word in word_dic:
  110.             single_list = [word]
  111.             wordcorpus = self.tfidf_model[self.dictionary.doc2bow(single_list)]
  112.             wordtopic = self.model[wordcorpus]
  113.             wordtopic_dic[word] = wordtopic
  114.         return wordtopic_dic
  115.  
  116.     # 词空间构建方法和向量化方法,在没有gensim接口时的一般处理方法
  117.     def word_dictionary(self, doc_list):
  118.         dictionary = []
  119.         for doc in doc_list:
  120.             dictionary.extend(doc)
  121.  
  122.         dictionary = list(set(dictionary))
  123.  
  124.         return dictionary
  125.  
  126.     def doc2bowvec(self, word_list):
  127.         vec_list = [1 if word in word_list else 0 for word in self.dictionary]
  128.         return vec_list
  129.  
  130.     # 计算词的分布和文档的分布的相似度,取相似度最高的keyword_num个词作为关键词
  131.     def get_simword(self, word_list):
  132.         sentcorpus = self.tfidf_model[self.dictionary.doc2bow(word_list)]
  133.         senttopic = self.model[sentcorpus]
  134.  
  135.         # 余弦相似度计算
  136.         def calsim(l1, l2):
  137.             a, b, c = 0.0, 0.0, 0.0
  138.             for t1, t2 in zip(l1, l2):
  139.                 x1 = t1[1]
  140.                 x2 = t2[1]
  141.                 a += x1 * x1
  142.                 b += x1 * x1
  143.                 c += x2 * x2
  144.             sim = a / math.sqrt(b * c) if not (b * c) == 0.0 else 0.0
  145.             return sim
  146.  
  147.         # 计算输入文本和每个词的主题分布相似度
  148.         sim_dic = {}
  149.         for k, v in self.wordtopic_dic.items():
  150.             if k not in word_list:
  151.                 continue
  152.             sim = calsim(v, senttopic)
  153.             sim_dic[k] = sim
  154.  
  155.         for k, v in sorted(sim_dic.items(), key=functools.cmp_to_key(cmp), reverse=True)[:self.keyword_num]:
  156.             print(k + "/ ", end='')
  157.         print()
  158.  
  159.  
  160. def topic_extract(word_list, model, pos=False, keyword_num=10):
  161.     doc_list = load_data(pos)
  162.     topic_model = TopicModel(doc_list, keyword_num, model=model)
  163.     topic_model.get_simword(word_list)
  164.  
  165.  
  166. if __name__ == '__main__':
  167.     text = '''记者从国家文物局获悉,截至3月15日,19个省(区、市) 180多家博物馆在做好夜情防控工
  168.     作的前提下恢复对外开放,其中19家为一级博物馆。
  169. 另外,沈阳故宫博物院、新四军江南指挥部纪念馆、金沙遗址博物馆等将于3月17日陆续恢复开放。
  170. 随着疫情防控形势好转,各地博物馆、纪念馆等陆续恢复开放。记者从各恢复开放博物馆发布的公告获悉,
  171. 各恢复开放博物馆对疫情防控期间参观观众在提前预约、测量体温等提出了明确要求,并提醒观众做好个人防护。
  172. 2月27日,国家文物局发布《关于新冠肺炎疫情防控期间有序推进文博单位恢复开放和复工的指导意见》
  173. 强调,有序恢复开放文物、博物馆单位,各文物、博物馆开放单位可采取网上实名预约、总量控制、分时
  174. 分流、语音讲解、数字导览等措施,减少人员聚集。'''
  175.  
  176.     pos = True
  177.     seg_list = seg_to_list(text, pos)
  178.     filter_list = word_filter(seg_list, pos)    # 返回的是一个没有停用词 并且长度>2的词的list
  179.  
  180.     print('LSI模型结果:')
  181.     topic_extract(filter_list, 'LSI', pos)
  182.     print('LDA模型结果:')
  183.     topic_extract(filter_list, 'LDA', pos)
  184.  

实验结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/753475
推荐阅读
相关标签
  

闽ICP备14008679号