基于句子嵌入的无监督文本摘要(附代码实现)
?PaperWeekly·?作者|高開遠
學校|上海交通大學
研究方向|自然語言處理
本文主要介紹的是一個對多種語言的郵件進行無監督摘要抽取的項目,非常詳細。文本摘要也是非常有意思的 NLP 任務之一。
A Glance at Text Summarization
文本摘要是從一個或多個源中提取最重要信息,并為特定用戶(或多個用戶)和任務(或多個任務)生成簡短版本的過程。?
-- Advances in Automatic Text Summarization, 1999.?
文本摘要對于人類來說是非常簡單的,因為人類天生地具有理解自然語言的能力,并可以提取顯著特征以使用自己的文字來總結文檔的重點。但是,在當今世界中數據爆炸增長,缺乏人力和時間來解析數據,因此自動文本摘要方法至關重要,主要有以下幾個原因:?
自動摘要可以縮短文本閱讀時間,提高效率;?
當搜索我們所需要的文本時,有摘要可以更為容易查找到;
?
自動摘要提高了索引的效率;?
相比于人力摘要,自動摘要更無偏;?
個性化的摘要在問答系統中非常有用,因為它們提供了個性化的信息;?
使用自動或半自動摘要系統使商業抽象服務能夠增加它們處理的文本文檔的數量。?
文本摘要的分類
文本摘要方法可以被總結為以下不同的類別:
Based on input type?
1. 單文檔:輸入長度較短,許多早期的摘要系統主要處理單個文檔摘要;?
2. 多文檔:輸入可以是任意長的。?
Based on the purpose?
1. 通用模型:模型對摘要的文本的領域或內容不做任何假設,并將所有輸入視為同類輸入。目前大部分已經完成的工作都是圍繞著通用的總結;?
2. 領域適應模型:模型使用領域特定的知識來形成更準確的摘要。例如,總結某一特定領域的研究論文、生物醫學文獻等;?
3. 基于 query 模型:摘要只包含回答有關輸入文本的自然語言問題的信息。?
Based on output type?
1. 抽取式模型:從輸入文本中選擇重要的句子形成摘要,當今大多數的總結方法本質上都是抽取式的。?
2. 生成式模型:模型形成自己的短語和句子,提供更連貫的總結,就像人類在面對文本摘要時會做的那樣。這種方法肯定更有吸引力,但比提取摘要困難得多。
文本摘要流程
文本摘要實現主要是參考 Unsupervised Text Summarization Using Sentence Embeddings [1] 這篇論文,可以分解成以下過程:
以英文郵件為例,看看是怎么得到最終的摘要的。
Step-1:數據清洗
常規操作,永遠沒有干凈的數據,自己動手豐衣足食。下面以常見的英文郵件為例:
Hi?Jane,Thank?you?for?keeping?me?updated?on?this?issue.?I'm?happy?to?hear?that?the?issue?got?resolved?after?all?and?you?can?now?use?the?app?in?its?full?functionality?again.? Also?many?thanks?for?your?suggestions.?We?hope?to?improve?this?feature?in?the?future.?In?case?you?experience?any?further?problems?with?the?app,?please?don't?hesitate?to?contact?me?again.Best?regards,John?Doe Customer?Support1600?Amphitheatre?Parkway Mountain?View,?CA United?States可以看出,郵件起始的問候與末尾的署名對我們的文本摘要任務是毫無作用的,所以我們需要首先去除這些無關因素,否則會使得模型混淆。為此,我們可以借用 Mailgun Talon github 庫 [2] 中的部分代碼,該代碼還可以刪除空行。
#?clean()函數改寫了上面github庫中代碼以清洗郵件 cleaned_email,?_?=?clean(email)lines?=?cleaned_email.split('\n') lines?=?[line?for?line?in?lines?if?line?!=?''] cleaned_email?=?'?'.join(lines)當然,如果不想自己寫 clean() 函數的話,也可以直接調用上面鏈接中的清洗函數:
from?talon.signature.bruteforce?import?extract_signature cleaned_email,?_?=?extract_signature(email)上述原始郵件清洗后得到大概是這樣的:
Step-2:語言檢測
對于不同的語言,處理的方式會有所不同,所以首先需要對郵件的語言類型進行檢測。得益于 python 強大的第三方庫,語言檢測可以很容易實現,比如使用 polyglot,langdetect,textblob 等。
from?langdetect?import?detect lang?=?detect(cleaned_email)?#?lang?=?'en'?for?an?English?emailStep-3:句子分割
由上一步檢測出郵件語言之后,可以針對該語言對郵件全文進行句子分割。以英文為例,可以使用 NLTK 包中的 sen_tokenize() 方法。
from?nltk.tokenize?import?sent_tokenize sentences?=?sent_tokenize(email,?language?=?lang)舉個例子:
Step-4:Skip-Thought編碼?
為了郵件文本表示成機器可以識別的輸入,同時融入文本的語義信息,需要對文本進行編碼,生成特定長度的向量表示,即 Word Embedding。
對于 word embedding,常見的有 word2vec,glove,fasttext 等。對于句子 embedding,一種簡單的思路是對句子中的單詞取其 word embedding 的加權和,認為不同的單詞對整體的貢獻程度不一樣。例如經常出現的單詞(‘and’,‘to’,‘the’等)幾乎對句子信息沒有貢獻,一些很少出現的單詞具有更大的代表性,類似于 tf-idf 的思想,也在這篇論文 [3] 中介紹。?
但是,這些無監督的方法沒有將單詞在句子中的順序考慮進去,因此會造成性能損失。為了改進這一點,采用了 Skip-Thought Vectors 這篇論文 [4] 提供的思路,使用 wikipedia 訓練了一個? Skip-Thoughts 句子嵌入模型:?
1. Encoder Network:Encoder 的結構是典型的 GRU-RNN 框架,對輸入的每一個句子 S(i) 都生成一個固定長度的向量表示 h(i);?
2. Decoder Network:Decoder 使用的也是 GRU-RNN 框架,不過有兩個 decoder,分別用于生成句子 S(i) 的前一句 S(i?1) 和后一句 S(i+1),輸入均為 encoder的輸出 h(i)。?
整體框架如下所示:
感謝 Skip-Thought 的開源,我們通過幾行簡單的代碼就可以得到句子向量表示:
import?skipthoughts#?需要預先下載預訓練模型 model?=?skipthoughts.load_model()encoder?=?skipthoughts.Encoder(model) encoded?=??encoder.encode(sentences)Step-5:聚類
在為郵件文本生成句子表示之后,將這些句子編碼在高維向量空間中進行聚類,聚類的數量為摘要任務所需要的句子數量。可以將最終摘要的句子數設定為初始輸入句子綜述的平方根。我們可以使用 K-means 實現:
import?numpy?as?np from?sklearn.cluster?import?KMeansn_clusters?=?np.ceil(len(encoded)**0.5) kmeans?=?KMeans(n_clusters=n_clusters) kmeans?=?kmeans.fit(encoded)Step-6:摘要?
聚類之后的每一個簇群都可以認為是一組語義相似的句子集合,而我們只需要其中的一句來表示即可。這一句子的選擇為考慮距離聚類中心最接近的句子,然后將每個簇群相對應的候選句子排序,形成最終的文本摘要。摘要中候選句子的順序由原始電子郵件中句子在其相應簇中的位置確定。例如,如果位于其群集中的大多數句子出現在電子郵件的開頭,則將候選句子選擇為摘要中的第一句。?
from?sklearn.metrics?import?pairwise_distances_argmin_minavg?=?[] for?j?in?range(n_clusters):idx?=?np.where(kmeans.labels_?==?j)[0]avg.append(np.mean(idx)) closest,?_?=?pairwise_distances_argmin_min(kmeans.cluster_centers_,?encoded) ordering?=?sorted(range(n_clusters),?key=lambda?k:?avg[k]) summary?=?'?'.join([email[closest[idx]]?for?idx?in?ordering])經過上述幾個步驟,最終得到的摘要如下所示:
總結
上述介紹的是一種抽取式文本摘要的方法,對于所有抽取式摘要而言,一大特點就是不適用與長度較短文本的摘要,對于短文本的摘要可能 Seq2Seq 的模型 [5] 效果會更好。
對于 Sentence Embedding 可以進一步優化,使用更有效的句子編碼模型可能會使得最終效果有所提高。?
Skip-Thought 編碼維度為 4800,如此高維度對后續的聚類可能效果有所影響(Curse of Dimensionality)。可以考慮在聚類之前使用自動編碼器或 LSTM-Autoencoder 在壓縮表示中傳遞進一步的序列信息;?
完整的代碼實現參考:
https://github.com/jatana-research/email-summarization
參考文獻
[1]?https://www.cs.utexas.edu/~asaran/reports/summarization.pdf
[2]?https://github.com/mailgun/talon/blob/master/talon/signature/bruteforce.py
[3]?https://openreview.net/pdf?id=SyK00v5xx
[4]?https://arxiv.org/abs/1506.06726
[5]?https://machinelearningmastery.com/encoder-decoder-models-text-summarization-keras/
點擊以下標題查看更多往期內容:?
基于預訓練自然語言生成的文本摘要方法
淺談 Knowledge-Injected BERTs
細粒度情感分析任務(ABSA)的最新進展
自然語言處理中的語言模型預訓練方法
BERT+知識圖譜:知識賦能的K-BERT模型
從三大頂會論文看百變Self-Attention
#投 稿 通 道#
?讓你的論文被更多人看到?
如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。
總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。?
PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得或技術干貨。我們的目的只有一個,讓知識真正流動起來。
?????來稿標準:
? 稿件確系個人原創作品,來稿需注明作者個人信息(姓名+學校/工作單位+學歷/職位+研究方向)?
? 如果文章并非首發,請在投稿時提醒并附上所有已發布鏈接?
? PaperWeekly 默認每篇文章都是首發,均會添加“原創”標志
???? 投稿郵箱:
? 投稿郵箱:hr@paperweekly.site?
? 所有文章配圖,請單獨在附件中發送?
? 請留下即時聯系方式(微信或手機),以便我們在編輯發布時和作者溝通
????
現在,在「知乎」也能找到我們了
進入知乎首頁搜索「PaperWeekly」
點擊「關注」訂閱我們的專欄吧
關于PaperWeekly
PaperWeekly 是一個推薦、解讀、討論、報道人工智能前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號后臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
▽ 點擊 |?閱讀原文?| 獲取最新論文推薦
總結
以上是生活随笔為你收集整理的基于句子嵌入的无监督文本摘要(附代码实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 收藏!这 10 篇硬核论文,让你宅家也能
- 下一篇: 平板系统安装u盘启动不了怎么办啊 加载不