【小实验】“关键字”法完成新闻摘要提取

完成一个相对简单的“关键字提取”算法
思路:拥有关键词最多的句子就是最重要的句子。我们把句子按照关键词数量的多少排序,取前n句,即可汇总成我们的摘要。

步骤:

  1. 给在文章中出现的单词按照算法计算出重要性
  2. 按照句子中单词的重要性算出句子的总分
  3. 按照句子的总分给文章中的每个句子排序
  4. 取出前n个句子作为摘要
from nltk.tokenize import sent_tokenize, word_tokenize 
from nltk.corpus import stopwords
from collections import defaultdict
from string import punctuation
from heapq import nlargest

"""
nltk.tokenize 是NLTK提供的分词工具包。所谓的分词 ﴾tokenize﴿ 实际就是把段落分成句子,把句子分成一个个单词的过程。我们导入的 sent_tokenize() 函数对应的是分段为句。 word_tokenize()函数对应的是分句为词。
stopwords 是一个列表,包含了英文中那些频繁出现的词,如am, is, are。
defaultdict 是一个带有默认值的字典容器。
puctuation 是一个列表,包含了英文中的标点和符号。
nlargest() 函数可以很快地求出一个容器中最大的n个数字。
"""

stopwords = set(stopwords.words('english') + list(punctuation))
#stopwords包含的是我们在日常生活中会遇到的出现频率很高的词,如do, I, am, is, are等等,这种词汇是不应该算是我们的 关键字。同样的标点符号(punctuation)也不能被算作是关键字。

max_cut = 0.9
min_cut = 0.1
#限制了在文本中出现重要性过高过低的词。就像在跳水比赛中会去掉最高分和最低分一样。我们也需要去掉那些重 要性过高和过低的词来提升算法的效果。


def compute_frequencies(word_sent):
    """
    计算出每个词出现的频率
    :param word_sent: 是一个已经分好词的列表
    :return: 一个词典freq[], freq[w]代表了w出现的频率
    """
    freq = defaultdict(int)#defaultdict和普通的dict 的区别是它可以设置default值 参数是int默认值是0
    #统计每个词出现的频率:
    for s in word_sent:
        for word in s:
            if word not in stopwords:
                freq[word] += 1
    #得出最高出现频次m            
    m = float(max(freq.values()))
    #所有单词的频次统除m
    for w in list(freq.keys()):
        freq[w] = freq[w]/m
        if freq[w] >= max_cut or freq[w] <= min_cut:
            del freq[w]
    # 最后返回的是
    # {key:单词, value: 重要性}
    return freq

def summarize(text, n):
    """
    用来总结的主要函数
    text是输入的文本 
    n是摘要的句子个数 
    返回包含摘要的列表
    """

    # 首先先把句子分出来
    sents = sent_tokenize(text)
    assert n <= len(sents)

    # 然后再分词
    word_sent = [word_tokenize(s.lower()) for s in sents]
    # self._freq是一个词和词频率的字典
    freq = compute_frequencies(word_sent)
    #ranking则是句子和句子重要性的词典
    ranking = defaultdict(int)
    for i, word in enumerate(word_sent):
        for w in word:
            if w in freq:
                ranking[i] += freq[w]
    sents_idx = rank(ranking, n)
    return [sents[j] for j in sents_idx]

"""
考虑到句子比较多的情况 
用遍历的方式找最大的n个数比较慢 
我们这里调用heapq中的函数 
创建一个最小堆来完成这个功能 
返回的是最小的n个数所在的位置 
"""
def rank(ranking, n):
    return nlargest(n, ranking, key=ranking.get)

#运行程序
if __name__ == '__main__':
    with open("news.txt", "r") as myfile:
        text = myfile.read().replace('\n','')
    res = summarize(text, 2)
    for i in range(len(res)):
        print("* " + res[i])

分析这篇文章:脸书推出人工智能翻译,谷歌感到压力山大
得到:

  • Rather than analyze a sentence sequentially, one piece at a time, a convolutional neural network can analyze many different pieces at once, before organizing those pieces into a logical hierarchy.Even if the system is only marginally more accurate than systems like the one Google rolled out in the fall, the company says its technique is more efficient that other neural network-based methods.Others may help push the technique forward as well.
  • This past fall, Google unveiled a new translation system driven entirely by neural networks that topped existing models, and many other companies and researchers are pushing in the same direction, most notably Microsoft and Chinese web giant Baidu.But Facebook is taking a slightly different tack from most of the other big players.

疑问:

n=2 为什么这么两大段,不应该是两个句子吗?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • “现在,就是一个健康人也没有能力搬起床走路,所以我一定要劝告一个生病的人放下他的床跑开。”离开床,只有动起来,给身...
    梦到小鱼干的猫阅读 1,234评论 0 0
  • (1)安装pegjs (2)grammer.pegjs (3)main.js 注:如果需要pegjs命令行工具,需...
    何幻阅读 5,261评论 0 0
  • 低苦艾有句歌词,“路的尽头是海的入口”,走的远了,才知道人间喧哗,浩瀚如海。你我都会老,但苍穹不老,星辰永恒,可能...
    箫念念阅读 4,451评论 4 9
  • //宽度不变,动态设置label的高度 - (CGFloat)setLabelHeightWithSizeFont...
    爱码师阅读 3,764评论 0 0

友情链接更多精彩内容