終於有人把機器學習中的文字摘要解釋清楚了!
你曾有沒有把冗長的檔案歸納成一個簡短的段落的工作?你花了多長時間?這樣的手動生成摘要可能既費時又乏味。自動文字摘要有望克服這些困難,並且可以一鍵提取出文章中重要的關鍵資訊。
文字摘要是一種生成簡明而精確的大量文字摘要的技術,同時可以傳達有用資訊的那一部分,但不會改變原文的整體意義。
自動文字摘要旨在將冗長的文件轉換為縮短的版本,如果手動完成,可能是困難且成本高昂。
機器學習演算法可以經過訓練,在生成所需的摘要文字之前,理解文件並識別傳達重要事實和資訊的部分。例如,下面的圖片是一篇新聞文章,它被輸入機器學習演算法來生成摘要。
進行文字摘要的需求
隨著目前資料空間的大量湧現(主要是非結構化的文字資料),我們很有必要開發自動文字摘要工具,使人們能夠輕鬆地從中獲得關鍵資訊。目前,我們可以快速訪問大量資訊。但是,大多數此類資訊都是多餘的、無關緊要,並且可能無法傳達預期的含義。例如,如果您正在尋找線上新聞文章中的特定資訊,您可能需要深入瞭解其內容,並在獲取所需資訊之前花費大量時間清除不必要的內容。因此,使用能夠提取有用資訊的自動文字摘要器,這些資訊會篩選出不必要且無關緊要的資料。實現摘要可以增強文件的可讀性,減少研究資訊所花費的時間,並允許在特定區域中包含更多資訊。
文字摘要的主要型別
從廣義上講,有兩種方法可以總結NLP中的文字:提取和抽象。
基於提取的摘要
在基於提取的摘要中,會從一段文字中提取一組表示最重要的單詞子集,並將其組合形成摘要。可以把它看作是一個熒光筆,它從源文字中選擇出了主要資訊。
在機器學習中,提取摘要通常涉及權衡句子的基本部分並使用結果生成摘要。
可以使用不同型別的演算法和方法來測量句子的權重,然後根據它們的相關性和相似性對它們進行排序——然後將它們連線起來生成摘要。舉個例子:
如您所見,提取的摘要由以粗體突出顯示的單片語成,當然結果可能在語法上不準確。
基於抽象的摘要
在基於抽象的總結中,高階深度學習技術被應用於解釋和縮短原始文件。把它想象成一支筆,它能寫出不屬於原始文件的新句子。
由於抽象機器學習演算法可以生成表示源文字中最重要資訊的新短語和句子,因此它們可以幫助克服提取技術的語法錯誤。舉個例子:
儘管抽象摘要得形式表現更好,但開發其演算法需要複雜的深度學習技術和複雜的語言建模。
為了生成合理的輸出,基於抽象的摘要方法必須解決各種NLP問題,例如自然語言生成、語義表示和推理置換。
因此,提取文字摘要方法仍然廣泛流行。在本文中,我們將專注於基於提取的方法。
如何執行文字摘要
讓我們用一小段話來說明如何執行提取文字摘要。
段落內容:
“彼得和伊麗莎白乘計程車去城市的晚會。在聚會期間,伊麗莎白垮了,被送往醫院。自從她被診斷出患有腦損傷後,醫生告訴彼得要留在她身邊直到她康復。因此,彼得在醫院住了3天而沒有離開。”
以下是總結上段的步驟,同時儘可能地保持其本意。
步驟1:將段落轉換為句子
首先,讓我們將段落分成相應的句子。進行轉換的最佳方法是在句點出現時提取一個句子。
- 彼得和伊麗莎白乘計程車參加了這個城市的晚會
- 在聚會上,伊麗莎白暈倒了,然後被送往醫院
- 由於她被診斷出患有腦損傷,醫生告訴彼得要留在她身邊直到她康復
- 因此,彼得在醫院住了3天而沒有離開
步驟2:文字處理
接下來,讓我們透過從句子中刪除停用詞(極其常見的詞語,例如“和”和“the”)、數字、標點符號和其他特殊字元來進行文字處理。
執行過濾有助於刪除冗餘和無關緊要的資訊,這些資訊可能無法為文字的含義提供任何附加值。
以下是文字處理的結果:
- 彼得伊麗莎白乘計程車參加晚會
- 伊麗莎白暈倒被送往醫院
- 診斷腦損傷的醫生告訴彼得要留下來等待康復
- 彼得沒有離開就住在醫院
步驟3:標記
對句子進行標記以獲得句子中出現的所有單詞。這是一個單詞列表:
[ '彼得', '伊麗莎白', '花', '計程車', '出席', '夜', '聚會', '城市', '聚會', '伊麗莎白', '崩潰', '搶',”醫院','診斷','大腦','受傷','醫生','告訴','彼得','留','除','得','好','彼得','留' , '醫院', '天', '無', '離開']
步驟4:評估單詞的加權出現頻率
之後,讓我們計算所有單詞的加權出現頻率。為了達到這個目的,我們將每個單詞的出現頻率除以段落中最常用單詞的頻率,即出現三次的“彼得”。
這是一個表格,給出了每個單詞的加權出現頻率。
步驟5:用加權頻率替換單詞
讓我們用他們的加權頻率替換原始句子中的每個單詞。然後,我們將計算它們的總和。
由於在處理階段被刪除的無效字的加權頻率(例如停用詞和特殊字元)為零,因此不必新增它們。
從單詞的加權頻率之和,我們可以推斷出第一句在段落中的權重最大。因此,它可以提供該段落的最佳代表性摘要。
此外,如果第一個句子與第三個句子組合,這是段落中第二個重要的句子,可以產生更好的摘要。
以上示例僅給出瞭如何在機器學習中執行基於提取的文字摘要的基本說明。現在,讓我們看看如何在建立真實世界的摘要生成器時應用上述概念。
維基百科文章的文字摘要
讓我們親自動手,建立一個文字摘要生成器,它可以縮短冗長的Web文章中的資訊。為了簡單起見,除了Python的NLTK工具包之外,我們不會使用任何其他機器學習庫。
以下是摘要生成器的程式碼藍圖:
# Creating a dictionary for the word frequency table
frequency_table = _create_dictionary_table(article)
# Tokenizing the sentences
sentences = sent_tokenize(article)
# Algorithm for scoring a sentence by its words
sentence_scores = _calculate_sentence_scores(sentences, frequency_table)
# Getting the threshold
threshold = _calculate_average_score(sentence_scores)
# Producing the summary
article_summary = _get_article_summary(sentences, sentence_scores, 1.5 * threshold)
print(article_summary)
以下是在Python中建立簡單文字摘要生成器的步驟。
第1步:準備資料
在這個例子中,我們想要總結這篇維基百科文章中的資訊,這篇文章只概述了20世紀的重大事件。
為了使我們能夠獲取文章的文字,我們將使用Beautiful Soup庫。
以下是抓取文章內容的程式碼:
import bs4 as BeautifulSoup
import urllib.request
# Fetching the content from the URL
fetched_data = urllib.request.urlopen(')
article_read = fetched_data.read()
# Parsing the URL content and storing in a variable
article_parsed = BeautifulSoup.BeautifulSoup(article_read,'html.parser')
# Returning <p> tags
paragraphs = article_parsed.find_all('p')
article_content = ''
# Looping through the paragraphs and adding them to the variable
for p in paragraphs:
article_content += p.text
在上面的程式碼中,我們首先匯入用於從網頁獲取資料的基本庫。 BeautifulSoup庫用於解析頁面,而urllib庫用於連線到頁面並檢索HTML。
BeautifulSoup將傳入的文字轉換為Unicode字元,將傳出的文字轉換為UTF-8字元,從而節省了在從Web上抓取文字時管理不同字符集編碼的麻煩。
我們將使用urllib.request實用程式中的urlopen函式開啟網頁。然後,我們將使用read函式來讀取已刪除的資料物件。為了解析資料,我們將呼叫BeautifulSoup物件並將兩個引數傳遞給它;也就是article_read和html.parser。
find_all函式用於返回HTML中存在的所有<p>元素。此外,使用.text使我們只能選擇<p>元素中的文字。
第2步:處理資料
為確保報廢的文字資料儘可能無噪音,我們將執行一些基本的文字清理。為了幫助我們進行處理,我們將從nltk庫匯入一個停用詞列表。
我們還將匯入PorterStemmer,這是一種將單詞縮減為詞根形式的演算法。
此外,我們將建立一個字典表,其中包含文字中每個單詞的出現頻率。我們將遍歷文字和相應的單詞以消除任何停用詞。
然後,我們將檢查單詞是否出現在frequency_table中。如果該單詞以前在字典中可用,則其值將更新為1。否則,如果第一次識別該單詞,則其值將設定為1。
例如,頻率表應如下所示:
程式碼如下:
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
def _create_dictionary_table(text_string) -> dict:
# Removing stop words
stop_words = set(stopwords.words("english"))
words = word_tokenize(text_string)
# Reducing words to their root form
stem = PorterStemmer()
# Creating dictionary for the word frequency table
frequency_table = dict()
for wd in words:
wd = stem.stem(wd)
if wd in stop_words:
continue
if wd in frequency_table:
frequency_table[wd] += 1
else:
frequency_table[wd] = 1
return frequency_table
第3步:將文章標記為句子
要將article_content拆分為一組句子,我們將使用nltk庫中的內建方法。
from nltk.tokenize import word_tokenize, sent_tokenize
sentences = sent_tokenize(article)
第4步:找到句子的加權頻率
為了評估文字中每個句子的分數,我們將分析每個術語的出現頻率。在這種情況下,我們將用它的詞來評分每個句子;也就是說,新增句子中找到的每個重要單詞的頻率。
看看下面的程式碼:
def _calculate_sentence_scores(sentences, frequency_table) -> dict:
# Algorithm for scoring a sentence by its words
sentence_weight = dict()
for sentence in sentences:
sentence_wordcount = (len(word_tokenize(sentence)))
sentence_wordcount_without_stop_words = 0
for word_weight in frequency_table:
if word_weight in sentence.lower():
sentence_wordcount_without_stop_words += 1
if sentence[:7] in sentence_weight:
sentence_weight[sentence[:7]] += frequency_table[word_weight]
else:
sentence_weight[sentence[:7]] = frequency_table[word_weight]
sentence_weight[sentence[:7]] = sentence_weight[sentence[:7]] / sentence_wordcount_without_stop_words
return sentence_weight
重要的是,為了確保長句不會比短句得分高,我們將句子的每個分數除以該句中的單詞數。
另外,為了最佳化字典的記憶體,我們任意新增句子[:7],它指的是每個句子中的前7個字元。但是,對於較長的文件,您可能會遇到具有相同第一個n_chars的句子,最好使用雜湊函式或智慧索引函式來考慮這些邊屆情況並避免衝突。
第5步:計算句子的閾值
為了進一步調整符合摘要條件的句子型別,我們將為這些句子建立平均分。使用此閾值,我們可以避免選擇分數低於平均分數的句子。
程式碼如下:
def _calculate_average_score(sentence_weight) -> int:
# Calculating the average score for the sentences
sum_values = 0
for entry in sentence_weight:
sum_values += sentence_weight[entry]
# Getting sentence average value from source text
average_score = (sum_values / len(sentence_weight))
return average_score
第6步:總結
最後,由於我們擁有所有必需的引數,我們現在可以為文章生成摘要。
程式碼如下:
def _get_article_summary(sentences, sentence_weight, threshold):
sentence_counter = 0
article_summary = ''
for sentence in sentences:
if sentence[:7] in sentence_weight and sentence_weight[sentence[:7]] >= (threshold):
article_summary += " " + sentence
sentence_counter += 1
return article_summary
總結
這是一個影像,展示了建立摘要生成器的工作流程。
以下是機器學習中簡單的提取文字摘要生成器的完整程式碼:
#importing libraries
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenize, sent_tokenize
import bs4 as BeautifulSoup
import urllib.request
#fetching the content from the URL
fetched_data = urllib.request.urlopen(')
article_read = fetched_data.read()
#parsing the URL content and storing in a variable
article_parsed = BeautifulSoup.BeautifulSoup(article_read,'html.parser')
#returning <p> tags
paragraphs = article_parsed.find_all('p')
article_content = ''
#looping through the paragraphs and adding them to the variable
for p in paragraphs:
article_content += p.text
def _create_dictionary_table(text_string) -> dict:
#removing stop words
stop_words = set(stopwords.words("english"))
words = word_tokenize(text_string)
#reducing words to their root form
stem = PorterStemmer()
#creating dictionary for the word frequency table
frequency_table = dict()
for wd in words:
wd = stem.stem(wd)
if wd in stop_words:
continue
if wd in frequency_table:
frequency_table[wd] += 1
else:
frequency_table[wd] = 1
return frequency_table
def _calculate_sentence_scores(sentences, frequency_table) -> dict:
#algorithm for scoring a sentence by its words
sentence_weight = dict()
for sentence in sentences:
sentence_wordcount = (len(word_tokenize(sentence)))
sentence_wordcount_without_stop_words = 0
for word_weight in frequency_table:
if word_weight in sentence.lower():
sentence_wordcount_without_stop_words += 1
if sentence[:7] in sentence_weight:
sentence_weight[sentence[:7]] += frequency_table[word_weight]
else:
sentence_weight[sentence[:7]] = frequency_table[word_weight]
sentence_weight[sentence[:7]] = sentence_weight[sentence[:7]] / sentence_wordcount_without_stop_words
return sentence_weight
def _calculate_average_score(sentence_weight) -> int:
#calculating the average score for the sentences
sum_values = 0
for entry in sentence_weight:
sum_values += sentence_weight[entry]
#getting sentence average value from source text
average_score = (sum_values / len(sentence_weight))
return average_score
def _get_article_summary(sentences, sentence_weight, threshold):
sentence_counter = 0
article_summary = ''
for sentence in sentences:
if sentence[:7] in sentence_weight and sentence_weight[sentence[:7]] >= (threshold):
article_summary += " " + sentence
sentence_counter += 1
return article_summary
def _run_article_summary(article):
#creating a dictionary for the word frequency table
frequency_table = _create_dictionary_table(article)
#tokenizing the sentences
sentences = sent_tokenize(article)
#algorithm for scoring a sentence by its words
sentence_scores = _calculate_sentence_scores(sentences, frequency_table)
#getting the threshold
threshold = _calculate_average_score(sentence_scores)
#producing the summary
article_summary = _get_article_summary(sentences, sentence_scores, 1.5 * threshold)
return article_summary
if __name__ == '__main__':
summary_results = _run_article_summary(article_content)
print(summary_results)
你可以點選下面的按鈕,在FloydHub筆記本上執行程式碼:
在本例中,我們應用的閾值是平均分的1.5倍。這是超引數值,經過幾次試驗,我們得到了很好的結果。當然,您可以根據自己的偏好對值進行微調,並改進摘要結果。
這是維基百科文章摘要版本的圖片。
正如您所看到的,執行程式碼總結了冗長的維基百科文章,並簡要概述了20世紀的主要事件。
儘管如此,可以改進摘要生成器,以便更好地生成大量文字的簡明和精確的摘要。
把事情提高一個檔次......
當然,本文只是簡單介紹了機器學習中使用文字摘要演算法可以實現的功能。
要了解有關該主題的更多資訊,尤其是有關抽象文字摘要的更多資訊,可以使用以下一些有用的資源:
- 是否有可能將兩種方法(抽象和提取)結合起來?指標生成器網路背後的主要思想是透過結合提取(指向)和抽象(生成)來獲得兩全其美。
- 如何使用WikiHow,一個大規模的文字摘要資料集 - 本文介紹了WikiHow,這是一個新的大型文字摘要資料集,包含從WikiHow線上知識庫中提取的230,000多篇文章。大多數目前可用的資料集不足以訓練序列到序列模型,它們可能僅提供有限的摘要,並且它們更適合於執行提取摘要。但是,WikiHow資料集是大規模、高質量的,並且能夠在抽象摘要中實現最佳結果。
- 如何在文字摘要中使用基於預訓練的編碼器 - 解碼器框架 - 本文介紹了一種基於序列到序列範例的獨特的兩階段模型。該模型在編碼器和解碼器方面使用BERT,並在學習過程中重點關注強化目標。當在一些基準資料集上評估模型時,結果表明該方法在文字摘要中表現更好,特別是與其他傳統系統相比時。
原文來源:https://blog.floydhub.com/gentle-introduction-to-text-summarization-in-machine-learning/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29829936/viewspace-2641920/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 終於有人把MYSQL索引講清楚了MySql索引
- 終於有人把Java記憶體模型說清楚了Java記憶體模型
- C#:終於有人把 ValueTask、IValueTaskSource、ManualResetValueTaskSourceCore 說清楚了!C#
- 終於有人把ERP和OA的區別講清楚了!
- 【教程】終於有人把Java記憶體模型說清楚了!Java記憶體模型
- 終於有人把雲端計算、邊緣計算、霧計算說清楚了
- 五險一金終於有人給講清楚了
- 終於有人把網路爬蟲講明白了爬蟲
- 終於有人把隱私計算講明白了
- 終於有人把Java記憶體區域說清楚了!(不是記憶體模型,不要再混淆了)Java記憶體模型
- 終於有人把工業資料採集講明白了
- 終於有人把Web 3.0和元宇宙講明白了Web元宇宙
- 終於有人把能把資料採集給講明白了
- 終於有人將資料中臺講清楚了,原來根本不算啥
- 終於有人把BungeeCord群組服搭建教程方法講明白了
- 終於有人講清楚了什麼是雲端計算的業務永續和多活
- BI和報表等於資料分析?終於有人講清楚了它們的區別
- Kafka Network層解析,還是有人把它說清楚了Kafka
- 瞧!終於有人把智慧製造與工業4.0講明白了
- 終於有人把雲端計算、大資料和 AI 講明白了大資料AI
- 終於有人把安全知識圖譜技術講明白了(上篇)
- 終於有人把15個JavaScript的重要陣列方法給講出來了JavaScript陣列
- 數棧技術分享:到底什麼是資料中臺?終於有人說清楚了!
- 這一次終於有人把MySQL主從複製講全面了!!!MySql
- 終於有人講清楚什麼是分析即服務(AaaS)
- 機器學習的文字摘要方法概述 - kdnuggets機器學習
- 終於有人把雲端計算、大資料和人工智慧講明白了大資料人工智慧
- ClickHouse與Hive的區別,終於有人講明白了Hive
- 太難了,我終於把JDBC的程式碼終於優化了!JDBC優化
- 終於把網站搭建起來了網站
- 索引失效底層原理分析,這麼多年終於有人講清楚了索引
- 終於有人把不同標籤的加工內容與落庫講明白了丨DTVision分析洞察篇
- 機器學習快速落地, Amazon SageMaker終於來了!機器學習
- 終於有人把tcp、http、rpc和grpc總結完整了TCPHTTPRPC
- 資料視覺化的設計技巧,終於有人講明白了!視覺化
- 分散式檔案系統如何做?終於有個人把分散式檔案上傳講清楚了分散式
- 日本偶像遊戲,終於把核心玩法「卷」沒了遊戲
- MPP大資料系統架構,終於有人講明白了大資料架構