1. 程式人生 > >Python 實現英文新聞摘要自動提取 1

Python 實現英文新聞摘要自動提取 1

               

“關鍵字”法完成新聞摘要提取

我們現在瀏覽新聞,一般都會看標題 ( title ) 和新聞簡介 ( summary ) 來判斷我們是否對這則新聞感興趣。之前的新聞簡介都是由編輯手動提取的,現在自然語言處理 (Natural Language Processing, NLP) 技術發展日益成熟,我們發現計算機提取的摘要也可圈可點。

一、實驗簡介

1.1 實驗內容

主要完成一個相對簡單的“關鍵字提取”演算法,關注的是實現的過程,讓同學們對自然語言處理有個大致的瞭解。

1.2 實驗知識點

  • Python基礎知識
  • “關鍵字提取”演算法

1.3 實驗環境

  • Xfce終端
  • python3

1.4 實驗效果

原文標題: 'Middle age Health Crisis' Warning

原文連結

這是我們的演算法提取的摘要。

"Modern life is dramatically different to even 30 years ago," Prof Gray told Radio 4's Today programme, "people now drive to work and sit at work."

"The How Are You Quiz will help anyone who wants to take a few minutes to take stock and find out quickly where they can take a little action to make a big difference to their health."

我們的演算法為我們選出了最具代表性的兩句句子。

二、實驗步驟

2.1 準備工作

我們這次實驗都是在python3中進行。首先我們需要安裝NLTK (Natural Language ToolKit) . 我們開啟終端,在命令列中輸入

sudo pip3 install nltk

然後進入python3的互動介面,在命令列中輸入

python3

應該就有python的提示符出現。

此處輸入圖片的描述

請注意一定是要在python3環境下。

NLTK 是建設一個Python程式與人類語言資料工作平臺。它提供了易於使用的介面,超過50的語料庫和詞彙資源,如WordNet,連同一套文字處理庫的分類、標記、標註、句法分析、語義推理的NLP庫,和一個活躍的論壇。

要注意的是我們這次使用的一些詞彙資源並不在原生的 NLTK 庫中,需要我們另行下載。

在python 互動環境中,我們輸入如下的程式碼來下載我們本次實現需要的資源。

>>> import nltk>>> nltk.download('stopwords')>>> nltk.download('punkt')

**注意:此步操作需要訪問外部網路**非會員使用者使用線上環境無法完成操作。如果download函式長時間不響應的話,按ctrl+z退出python3互動環境,重新下載。

之後我們在桌面上新建一個資料夾NewsSummary

mkdir NewsSummary

在NewsSummary中用vim建立NewsSummary1.py檔案

先匯入我們需要的包

from nltk.tokenize import sent_tokenize, word_tokenizefrom nltk.corpus import stopwordsfrom collections import defaultdictfrom string import punctuationfrom heapq import nlargest

nltk.tokenize 是NLTK提供的分詞工具包。所謂的分詞 (tokenize) 實際就是把段落分成句子,把句子分成一個個單詞的過程。我們匯入的 sent_tokenize() 函式對應的是分段為句。 word_tokenize()函式對應的是分句為詞。

stopwords 是一個列表,包含了英文中那些頻繁出現的詞,如am, is, are。

defaultdict 是一個帶有預設值的字典容器。

puctuation 是一個列表,包含了英文中的標點和符號。

nlargest() 函式可以很快地求出一個容器中最大的n個數字。

至此我們完成了我們的準備工作。

2.2 思路解析

我們的基本思想很簡單:擁有關鍵詞最多的句子就是最重要的句子。我們把句子按照關鍵詞數量的多少排序,取前n句,即可彙總成我們的摘要。

所以我們的工作可以分為如下步驟:

  • 給在文章中出現的單詞按照演算法計算出重要性
  • 按照句子中單詞的重要性算出句子的總分
  • 按照句子的總分給文章中的每個句子排序
  • 取出前n個句子作為摘要

我們就按照這這個思路寫我們的模組。

2.3 詞頻統計

首先我們先要統計出每個詞在文章中出現的次數,在統計出次數之後,我們可以知道出現次數最多的詞的出現次數 m 。我們把每個詞 wi 出現的次數 mi 除以 m ,算出每個詞的“重要係數”。

我們舉個例子。 "I am a fool, big fool." 這句句子中

I am a fool big
1 1 1 2 1

出現最多的是 'fool' 這個單詞,所以 m 是2。所有單詞的頻率都除以m,可以獲得新的表

I am a fool big
0.5 0.5 0.5 1 0.5

這張表顯示的就是每個詞的重要性。重要性高的詞就是我們的關鍵詞。

我們先定一些我們需要的常量

stopwords = set(stopwords.words('english') + list(punctuation))max_cut = 0.9min_cut = 0.1

首先是我們的stopwords

stopwords包含的是我們在日常生活中會遇到的出現頻率很高的詞,如do, I, am, is, are等等,這種詞彙是不應該算是我們的關鍵字。同樣的標點符號(punctuation)也不能被算作是關鍵字。

max_cut 變數限制了在文字中出現重要性過高的詞。就像在跳水比賽中會去掉最高分和最低分一樣。我們也需要去掉那些重要性過高和過低的詞來提升演算法的效果。

同理,min_cut 限制了出現頻率過低的詞。

"""計算出每個詞出現的頻率word_sent 是一個已經分好詞的列表返回一個詞典freq[],freq[w]代表了w出現的頻率"""def compute_frequencies(word_sent):    """    defaultdict和普通的dict    的區別是它可以設定default值    引數是int預設值是0    """    freq = defaultdict(int)    #統計每個詞出現的頻率    for s in word_sent:        for word in s:            #注意stopwords            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

2.4 獲得摘要

現在每個單詞(stopwords和出現頻率異常的單詞除外)都有了“重要性”這樣一個量化描述的值。我們現在需要統計的是一個句子中單詞的重要性。只需要把句子中每個單詞的重要性疊加就行了。

def summarize(text, n):    """    用來總結的主要函式    text是輸入的文字    n是摘要的句子個數    返回包含摘要的列表    """    # 首先先把句子分出來    sents = sent_tokenize(text)    assert n <= len(sents)    # 然後再分詞    word_sent = [word_tokenize(s.lower()) for s in sents]    # 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)

2.5 執行程式

最後加入我們的main()

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])

這裡我們提供了一個樣本news.txt。可以在命令列中輸入

wget http://labfile.oss.aliyuncs.com/courses/741/news.txt

來獲取

我們先看一看我們的原文

此處輸入圖片的描述此處輸入圖片的描述此處輸入圖片的描述此處輸入圖片的描述

我們在來看一下我們獲取的摘要:

"Modern life is dramatically different to even 30 years ago," Prof Gray told Radio 4's Today programme, "people now drive to work and sit at work."

"The How Are You Quiz will help anyone who wants to take a few minutes to take stock and find out quickly where they can take a little action to make a big difference to their health."

三、實驗總結

我們的方法只是單純的疊加重要性,導致長句子佔有優勢。下一個實驗我們需要重新制定演算法來計算我們的摘要句子。

四、實驗程式碼

在命令列中輸入

wget http://labfile.oss.aliyuncs.com/courses/741/NewsSummary1.py
           

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!https://blog.csdn.net/jiangjunshow