如何自動生成文本摘要

學習資料:
https://www.youtube.com/watch?v=ogrJaOIuBx4&list=PL2-dafEMk2A7YdKv4XfKpfbTH5z6rEEj3&index=19
代碼:
https://github.com/llSourcell/How_to_make_a_text_summarizer/blob/master/vocabulary-embedding.ipynb

今天學習的是自動生成文本摘要。

當我們的身邊的信息越來越多,數據越來越多,鏈接越來越多的時候,用一句簡單的話就能把最重要的信息給表達出來,變得越來越重要。

有了這個技能,我們就可以讓機器為我們提取一篇文章的重要信息,以后甚至是一本書的重要信息。

這個技術最早是在氣象領域應用起來的,就是用一個固定的格式把預測出來的數據套入進去,后來在金融領域,醫療領域也得到廣泛的應用,這樣的工具可以很好的幫助從業人員節省一部分時間。

過去的方法是提取一個子集,而我們的大腦在對一篇文章進行總結的時候,利用的是抽象性思維,現在我們就可以用深度學習來模擬這個過程。


我們要用的數據是BBC新聞數據集。
http://mlg.ucd.ie/datasets/bbc.html

pickle, 可以將python的對象轉化成character stream,我們可以很輕松的重建這個對象:

import cPickle as pickle
FN0 = 'tokens' # this is the name of the data file which I assume you already have
with open('data/%s.pkl'%FN0, 'rb') as fp:
    heads, desc, keywords = pickle.load(fp) # keywords are not used in this project

返回的heads就是標題,desc就是相應的文章。

接著我們需要把整個文章變成一個一個的單詞,并且一個詞一個詞的生成總結。

    from collections import Counter
from itertools import chain
def get_vocab(lst):
    vocabcount = Counter(w for txt in lst for w in txt.split())
    vocab = map(lambda x: x[0], sorted(vocabcount.items(), key=lambda x: -x[1]))
    return vocab, vocabcount

接著我們要用詞向量來表示每個單詞。
word2vec是一個用大量數據提前訓練好的模型,我們可以直接下載。

詞向量的每個維度可以表示一個性質,可以是性別或者是頭銜等,詞向量在每個維度的投影長度可以看作是這個單詞在這個性質上的相關度。

另一種算法叫做GloVe,它屬于 count based的,
每一行代表一個單詞,每一列代表和這個單詞出現在同一語境中的頻數。
GloVe 比 word2vec 稍微快一點,

首先,將提前訓練好的 glove 詞向量下載到本地,然后用它們來初始化embedding matrix,我們先隨機初始化,然后把 training vocabulary 出現的所有單詞的 glove 權重復制一下。對于詞匯表以外的單詞,我們會找到離它最近的一個 glove 向量。

     path = 'glove.6B.zip'
    path = get_file(path, origin="http://nlp.stanford.edu/data/glove.6B.zip")

然后我們要用 seq2seq 模型,我們輸入一句話。

encoder,輸入就是 vocabulay 集,標簽就是相應的一句話標題,embeddings 會在訓練過程中不斷地優化,loss 是 cross entropy。

decoder,和encoder一樣的 lstm 結構,權重矩陣也是用同樣的提前訓練好的 glove embeddings,它用來生成 summary。

    model = Sequential()
model.add(Embedding(vocab_size, embedding_size,
                    input_length=maxlen,
                    W_regularizer=regularizer, dropout=p_emb, weights=[embedding], mask_zero=True,
                    name='embedding_1'))
for i in range(rnn_layers):
    lstm = LSTM(rnn_size, return_sequences=True, # batch_norm=batch_norm,
                W_regularizer=regularizer, U_regularizer=regularizer,
                b_regularizer=regularizer, dropout_W=p_W, dropout_U=p_U,
                name='lstm_%d'%(i+1)
                  )
    model.add(lstm)
    model.add(Dropout(p_dense,name='dropout_%d'%(i+1)))

這里有一個很關鍵的點,就是我們需要記住這段文字中的哪些部分呢?關于記憶的話,我們會選擇用 ltm 模型來做,而在這個問題上另一個重要的理論就是 attention,它可以學到哪些數據是最相關的最需要記憶的。

decoder 會先生成一個單詞,然后把這個單詞投入到下一層中,就會生成下一個單詞,一直到生成一句標題。

我們在 decoder 這里會應用 attention 機制,對于每一個輸出的單詞,會計算每個輸入單詞的權重,來決定應該在這個單詞上投入多少 attention。這些權重會被用來計算最后一個隱藏層的加權平均,然后投入到 softmax中。

可以看一下訓練效果:

    X = "What have you been listening to this year ? If you want to find out using cold , hard evidence , then Spotify 's new Year in Music tool will tell you ."
Y = "Spotify Will Make You Smarter for Your App"
    
    samples = gensamples(X, skips=2, batch_size=batch_size, k=10, temperature=1)
    
    HEADS:
12.9753409925 How To Make A <0>^


推薦閱讀 歷史技術博文鏈接匯總
http://www.lxweimin.com/p/28f02bb59fe5
也許可以找到你想要的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容