1.介绍
1.本文文本自动摘要实现的依据为词频统计。
2.文章是由句子组成的,文章的信息都包含在句子中,有些句子包含的信息多,有些句子包含的信息少。
3.句子的信息量用"关键词"来衡量。如果包含的关键词越多,就说明这个句子越重要。
4."自动摘要"就是要找出那些包含信息最多的句子,也就是包含关键字最多的句子
5.而通过统计句子中关键字的频率的大小,进而进行排序,通过对排序的词频列表对文档中句子逐个进行打分,进而把打分高的句子找出来,就是我们要的摘要。
2.实现步骤
1.加载停用词
2.将文档拆分成句子列表
3.将句子列表分词
4.统计词频,去除100个最高关键字
5.根据此词频对句子列表进行打分
6.取出打分较高的前五个句子
3.原理
这种方法最早出自1958年的IBM公司科学家H.P. Luhn的论文《The Automatic Creation of Literature Abstracts》。Luhn提出用"簇"(cluster)表示关键词的聚集。所谓"簇"就是包含多个关键词的句子片段。
上图就是Luhn原始论文的插图,被框起来的部分就是一个"簇"。只要关键词之间的距离小于"门槛值",它们就被认为处于同一个簇之中。Luhn建议的门槛值是4或5。
也就是说,如果两个关键词之间有5个以上的其他词,就可以把这两个关键词分在两个簇。
簇重要性分值计算公式:
以前图为例,其中的簇一共有7个词,其中4个是关键词。因此,它的重要性分值等于 ( 4 x 4 ) / 7 = 2.3。
然后,找出包含分值最高的簇的句子(比如前5句),把它们合在一起,就构成了这篇文章的自动摘要
4.相关代码如下:
# -*- coding:utf8 -*-
import nltk
import numpy
import jieba
import codecs
import os
class SummaryTxt:
def __init__(self,stopwordspath):
# 单词数量
self.N = 100
# 单词间的距离
self.CLUSTER_THRESHOLD = 5
# 返回的top n句子
self.TOP_SENTENCES = 10
self.stopwrods = {}
#加载停用词
if os.path.exists(stopwordspath):
stoplist = [line.strip() for line in codecs.open(stopwordspath, 'r', encoding='utf8').readlines()]
self.stopwrods = {}.fromkeys(stoplist)
def _split_sentences(self,texts):
'''
把texts拆分成单个句子,保存在列表里面,以(.!?。!?)这些标点作为拆分的意见,
:param texts: 文本信息
:return:
'''
splitstr = '.!?。!?'.encode('utf8').decode('utf8')
start = 0
index = 0 # 每个字符的位置
sentences = []
for text in texts:
if text in splitstr: # 检查标点符号下一个字符是否还是标点
sentences.append(texts[start:index + 1]) # 当前标点符号位置
start = index + 1 # start标记到下一句的开头
index += 1
if start < len(texts):
sentences.append(texts[start:]) # 这是为了处理文本末尾没有标
return sentences
def _score_sentences(self,sentences, topn_words):
'''
利用前N个关键字给句子打分
:param sentences: 句子列表
:param topn_words: 关键字列表
:return:
'''
scores = []
sentence_idx = -1
for s in [list(jieba.cut(s)) for s in sentences]:
sentence_idx += 1
word_idx = []
for w in topn_words:
try:
word_idx.append(s.index(w)) # 关键词出现在该句子中的索引位置
except ValueError: # w不在句子中
pass
word_idx.sort()
if len(word_idx) == 0:
continue
# 对于两个连续的单词,利用单词位置索引,通过距离阀值计算族
clusters = []
cluster = [word_idx[0]]
i = 1
while i < len(word_idx):
if word_idx[i] - word_idx[i - 1] < self.CLUSTER_THRESHOLD:
cluster.append(word_idx[i])
else:
clusters.append(cluster[:])
cluster = [word_idx[i]]
i += 1
clusters.append(cluster)
print(cluster,'对于两个连续的单词,利用单词位置索引,通过距离阀值计算族')
# 对每个族打分,每个族类的最大分数是对句子的打分
max_cluster_score = 0
for c in clusters:
significant_words_in_cluster = len(c)
# print(significant_words_in_cluster,'*******************///////////////')
total_words_in_cluster = c[-1] - c[0] + 1
score = 1.0 * significant_words_in_cluster * significant_words_in_cluster / total_words_in_cluster
if score > max_cluster_score:
max_cluster_score = score
scores.append((sentence_idx, max_cluster_score))
# print(sentence_idx,'《123》',max_cluster_score,'对每个族打分,每个族类的最大分数是对句子的打分')
return scores
def summaryScoredtxt(self,text):
# 将文章分成句子
sentences = self._split_sentences(text)
# 生成分词
words = [w for sentence in sentences for w in jieba.cut(sentence) if w not in self.stopwrods if
len(w) > 1 and w != '\t']
print(words,'生成分词')
# 统计词频
wordfre = nltk.FreqDist(words)
# 获取词频最高的前N个词
topn_words = [w[0] for w in sorted(wordfre.items(), key=lambda d: d[1], reverse=True)][:self.N]
# 根据最高的n个关键词,给句子打分
scored_sentences = self._score_sentences(sentences, topn_words)
# 利用均值和标准差过滤非重要句子
avg = numpy.mean([s[1] for s in scored_sentences]) # 均值
std = numpy.std([s[1] for s in scored_sentences]) # 标准差
summarySentences = []
for (sent_idx, score) in scored_sentences:
if score > (avg + 0.5 * std):
summarySentences.append(sentences[sent_idx])
# print (sentences[sent_idx])
return summarySentences
def summaryTopNtxt(self,text):
# 将文章分成句子
sentences = self._split_sentences(text)
# 根据句子列表生成分词列表
words = [w for sentence in sentences for w in jieba.cut(sentence) if w not in self.stopwrods if
len(w) > 1 and w != '\t']
print(words)
# 统计词频
wordfre = nltk.FreqDist(words)
print(wordfre)
# 获取词频最高的前100个词
topn_words = [w[0] for w in sorted(wordfre.items(), key=lambda d: d[1], reverse=True)][:self.N]
# print(topn_words,'+++++++++-----------*************')
# 根据最高的100个关键词,给句子打分
scored_sentences = self._score_sentences(sentences, topn_words)
top_n_scored = sorted(scored_sentences, key=lambda s: s[1])[-self.TOP_SENTENCES:]
top_n_scored = sorted(top_n_scored, key=lambda s: s[0])
summarySentences = []
for (idx, score) in top_n_scored:
print (sentences[idx])
summarySentences.append(sentences[idx])
return sentences
if __name__=='__main__':
obj =SummaryTxt('D:\work\Solr\solr-python\CNstopwords.txt')
texts = open("sing.txt", 'r', encoding='utf8')
# for i in texts:
txt = """随着关于听证会的临近,“”在公众视野范围外的“手机漫游费”成舆论关注焦点。手机漫游是怎样的技术过程?其成本怎样?记者近日采访了有关专家,请他们细解“手机漫游”之谜。手机漫游是“低科技”手机是如何漫游的?同济大学通信工程教研室主任薛小平副教授说,目前我国普遍使用的系统由手机(MS)、(BS)、业务交换中心(MSC)及与市话网()相连的线路等组成。为支持移动功能,移动通信系统内建立数据库,属地位置寄存器(HLR)和访问位置寄存器(VLR),分别用于存储每台本地和外地手机的用户资料、服务信息等,他们相当于手机的“户口簿”。薛小平说,比如一部在上海注册的手机“漫游”进北京时,手机向北京的移动通信提出服务要求,北京看到这是一“外来手机”,就会向它的老家上海方面询问,后者迅速将该手机的相关信息传给北京,北京的移动通信网络就会在VLR中为外来手机建立临时“户口簿”,并为漫游手机分配临时识别码,这样手机就可以使用北京地区移动通信网的服务。“这样,漫游到北京的上海手机,在拨打北京本地电话时,与在上海使用时没有任何区别,”薛小平说,“也就是说,除了需要在北京的VLR和上海的HLR之间交换少量用户和服务信息外,上海的手机在北京打电话就同当地电话一样,移动不需要再承担本地移动电话以外的其他成本。”手机漫游成本低记者使用的“”一款“套餐”,漫游费是0.6元/分钟。目前,我国手机国内漫游通话费上限标准是0.8元/分钟,用户普遍认为过高。人们“不清楚”的一点是:手机漫游的成本是多少?漫游的关键在于手机的身份和服务信息在HLR和VLR之间的交换和存储。薛小平说,漫游手机在漫游地和注册地之间,需要交换和存储的信息量少。一家移动服务设备提供商的内部人士告诉记者,设备提供商向运营商提供设备时,HRL和VLR在全套设备中的费用所占比例小。北京邮电大学教授等专家指出,对运营商来讲,手机漫游的成本低。在一些专家看来,手机漫游是移动通信与生俱来的功能,漫游是一个基本功能而不是特许功能,漫游的手机已经向提供服务的当地运营商支付了本地通话费。手机漫游费待“破冰”1月7日,记者的手机收到上海移动发来的,称每月付1元功能费,即可申请“国内漫游包”,漫游时打国内电话是0.49元/分钟,接听是0.3元/分钟。服务台工作人员介绍,这是该公司首次推出拨打、接听都有优惠的“漫游套餐”。2007年5月,信息产业部曾就手机漫游费问题进行用户调查,在收到的近3万份有效问卷中,64%手机用户认为,“异地漫游通信费应与本地相同,即应取消手机漫游费”。新华网在今年1月3日推出关于“如何看待部门收取手机漫游费”的调查,一天之内投票的2600多名网友中92.2%的人认为应该取消手机国内漫游费。双向收费、手机漫游费以及名目繁多的各种资费套餐曾被消费者称为电信业最不合理的三大收费。为此,从2007年4月起,信息产业部开始将工作重点放在对上述问题的调整上。据公布的数据,到2007年末,国内已有超过一半的用户享受,资费套餐减少80%以上,唯有手机漫游费这块坚冰迟迟不能融化。“手机漫游在技术上无壁垒可言,在移动通信中是一项基本的功能,从这个角度来说,手机漫游费应大幅降低。”薛小平说。64%64%手机用户认为,“异地漫游通信费应与本地相同,即应取消手机漫游费"""
# txt=u'十八大以来的五年,是党和国家发展进程中极不平凡的五年。面对世界经济复苏乏力、局部冲突和动荡频发、全球性问题加剧的外部环境,面对我国经济发展进入新常态等一系列深刻变化,我们坚持稳中求进工作总基调,迎难而上,开拓进取,取得了改革开放和社会主义现代化建设的历史性成就。' \
# u'为贯彻十八大精神,党中央召开七次全会,分别就政府机构改革和职能转变、全面深化改革、全面推进依法治国、制定“十三五”规划、全面从严治党等重大问题作出决定和部署。五年来,我们统筹推进“五位一体”总体布局、协调推进“四个全面”战略布局,“十二五”规划胜利完成,“十三五”规划顺利实施,党和国家事业全面开创新局面。' \
# u'经济建设取得重大成就。坚定不移贯彻新发展理念,坚决端正发展观念、转变发展方式,发展质量和效益不断提升。经济保持中高速增长,在世界主要国家中名列前茅,国内生产总值从五十四万亿元增长到八十万亿元,稳居世界第二,对世界经济增长贡献率超过百分之三十。供给侧结构性改革深入推进,经济结构不断优化,数字经济等新兴产业蓬勃发展,高铁、公路、桥梁、港口、机场等基础设施建设快速推进。农业现代化稳步推进,粮食生产能力达到一万二千亿斤。城镇化率年均提高一点二个百分点,八千多万农业转移人口成为城镇居民。区域发展协调性增强,“一带一路”建设、京津冀协同发展、长江经济带发展成效显著。创新驱动发展战略大力实施,创新型国家建设成果丰硕,天宫、蛟龙、天眼、悟空、墨子、大飞机等重大科技成果相继问世。南海岛礁建设积极推进。开放型经济新体制逐步健全,对外贸易、对外投资、外汇储备稳居世界前列。' \
# u'全面深化改革取得重大突破。蹄疾步稳推进全面深化改革,坚决破除各方面体制机制弊端。改革全面发力、多点突破、纵深推进,着力增强改革系统性、整体性、协同性,压茬拓展改革广度和深度,推出一千五百多项改革举措,重要领域和关键环节改革取得突破性进展,主要领域改革主体框架基本确立。中国特色社会主义制度更加完善,国家治理体系和治理能力现代化水平明显提高,全社会发展活力和创新活力明显增强。'
# txt ='The information disclosed by the Film Funds Office of the State Administration of Press, Publication, Radio, Film and Television shows that, the total box office in China amounted to nearly 3 billion yuan during the first six days of the lunar year (February 8 - 13), an increase of 67% compared to the 1.797 billion yuan in the Chinese Spring Festival period in 2015, becoming the "Best Chinese Spring Festival Period in History".' \
# 'During the Chinese Spring Festival period, "The Mermaid" contributed to a box office of 1.46 billion yuan. "The Man From Macau III" reached a box office of 680 million yuan. "The Journey to the West: The Monkey King 2" had a box office of 650 million yuan. "Kung Fu Panda 3" also had a box office of exceeding 130 million. These four blockbusters together contributed more than 95% of the total box office during the Chinese Spring Festival period.' \
# 'There were many factors contributing to the popularity during the Chinese Spring Festival period. Apparently, the overall popular film market with good box office was driven by the emergence of a few blockbusters. In fact, apart from the appeal of the films, other factors like film ticket subsidy of online seat-selection companies, cinema channel sinking and the film-viewing heat in the middle and small cities driven by the home-returning wave were all main factors contributing to this blowout. A management of Shanghai Film Group told the 21st Century Business Herald.'
print (txt)
print ("--")
obj.summaryScoredtxt(txt)
print ("----")
obj.summaryTopNtxt(txt)