Введение в суммирование текста с использованием машинного обучения

искусственный интеллект NLP
Введение в суммирование текста с использованием машинного обучения
Have you ever summarized a lengthy document into a short paragraph? How long did you take? Manually generating a summary can be time consuming and tedious. Automatic text summarization promises to overcome such difficulties and allow you to generate the key ideas in a piece of writing easily.

Text summarization is the technique for generating a concise and precise summary of voluminous texts while focusing on the sections that convey useful information, and without losing the overall meaning.
Automatic text summarization aims to transform lengthy documents into shortened versions, something which could be difficult and costly to undertake if done manually.
Machine learning algorithms can be trained to comprehend documents and identify the sections that convey important facts and information before producing the required summarized texts. For example, the image below is of this news article that has been fed into a machine learning algorithm to generate a summary.

An online news article that has been summarized using a text summarization machine learning algorithm

The need for text summarization

With the present explosion of data circulating the digital space, which is mostly non-structured textual data, there is a need to develop automatic text summarization tools that allow people to get insights from them easily. Currently, we enjoy quick access to enormous amounts of information. However, most of this information is redundant, insignificant, and may not convey the intended meaning. For example, if you are looking for specific information from an online news article, you may have to dig through its content and spend a lot of time weeding out the unnecessary stuff before getting the information you want. Therefore, using automatic text summarizers capable of extracting useful information that leaves out inessential and insignificant data is becoming vital. Implementing summarization can enhance the readability of documents, reduce the time spent in researching for information, and allow for more information to be fitted in a particular area.

The main types of text summarization

Broadly, there are two approaches to summarizing texts in NLP: extraction and abstraction.

Extraction-based summarization

При обобщении на основе извлечения подмножество слов, представляющих наиболее важные моменты, извлекается из фрагмента текста и объединяется для создания резюме.Думайте об этом как о маркере, который выбирает основную информацию из исходного текста.

Highlighter = обобщение на основе извлечения

In machine learning, extractive summarization usually involves weighing the essential sections of sentences and using the results to generate summaries.

Можно использовать различные типы алгоритмов и методов для оценки веса предложений, а затем ранжировать их в соответствии с их релевантностью и сходством друг с другом, а затем объединять их для создания сводки. Вот пример:

Extractive-based summarization in action.

As you can see above, the extracted summary is composed of the words highlighted in bold, although the results may not be grammatically accurate.

Abstraction-based summarization

При обобщении на основе абстракций применяются передовые методы глубокого обучения, чтобы перефразировать и сокращать исходный документ, как это делают люди.Думайте об этом как о ручке, которая создает новые предложения, которые могут не быть частью исходного документа.

Pen = обобщение на основе абстракций

Since abstractive machine learning algorithms can generate new phrases and sentences that represent the most important information from the source text, they can assist in overcoming the grammatical inaccuracies of the extraction techniques. Here is an example:

Abstraction-based summary in action.

Although abstraction performs better at text summarization, developing its algorithms requires complicated deep learning techniques and sophisticated language modeling.

To generate plausible outputs, abstraction-based summarization approaches must address a wide variety of NLP problems, such as natural language generation, semantic representation, and inference permutation.

Таким образом, подходы к резюмированию текста с извлечением по-прежнему широко популярны, и в этой статье мы сосредоточимся на методе, основанном на извлечении.

How to perform text summarization

Давайте воспользуемся коротким абзацем, чтобы проиллюстрировать, как можно выполнить экстрактивное суммирование текста.

Here is the paragraph:

"Питер и Элизабет взяли такси, чтобы посетить ночную вечеринку в городе. Во время вечеринки Элизабет потеряла сознание и была доставлена ​​в больницу. Поскольку у нее диагностировали черепно-мозговую травму, врач сказал Питеру оставаться рядом с ней, пока она не поправится. Поэтому Петр пробыл с ней в больнице 3 дня, не выезжая».

Here are the steps to follow to summarize the above paragraph, while trying to maintain its intended meaning, as much as possible.

Step 1: Convert the paragraph into sentences

Во-первых, давайте разделим абзац на соответствующие предложения.Лучший способ сделать преобразование — извлечь предложение всякий раз, когда появляется точка.

1. Peter and Elizabeth took a taxi to attend the night party in the city

2. While in the party, Elizabeth collapsed and was rushed to the hospital

3. Since she was diagnosed with a brain injury, the doctor told Peter to stay besides her until she gets well

4. Therefore, Peter stayed with her at the hospital for 3 days without leaving

Step 2: Text processing

Затем давайте обработаем текст, удалив стоп-слова (чрезвычайно распространенные слова с небольшим значением, такие как «и» и «то»), цифры, знаки препинания и другие специальные символы из предложений.

Выполнение фильтрации помогает удалить избыточную и незначительную информацию, которая может не придавать никакой дополнительной ценности тексту.

Here is the result of the text processing:

1. Peter Elizabeth took taxi attend night party city

2. Party Elizabeth collapse rush hospital

3. Diagnose brain injury doctor told Peter stay besides get well

4. Peter stay hospital days without leaving

Step 3: Tokenization

Tokenizing the sentences is done to get all the words present in the sentences. Here is a list of the words:

['peter','elizabeth','took','taxi','attend','night','party','city','party','elizabeth','collapse','rush','hospital', 'diagnose','brain', 'injury', 'doctor','told','peter','stay','besides','get','well','peter', 'stayed','hospital','days','without','leaving']

Step 4: Evaluate the weighted occurrence frequency of the words

Далее посчитаем взвешенную частоту встречаемости всех слов, для этого разделим частоту встречаемости каждого из слов на частоту наиболее повторяющегося слова в абзаце, а именно «Питер», встречающегося три раза. раз.

Here is a table that gives the weighted occurrence frequency of each of the words.

Word Frequency Weighted Frequency
peter 3 1
elizabeth 2 0.67
took 1 0.33
taxi 1 0.33
attend 1 0.33
night 1 0.33
party 2 0.67
city 1 0.33
collapse 1 0.33
rush 1 0.33
hospital 2 0.67
diagnose 1 0.33
brain 1 0.33
injury 1 0.33
doctor 1 0.33
told 1 0.33
stay 2 0.67
besides 1 0.33
get 1 0.33
well 1 0.33
days 1 0.33
without 1 0.33
leaving 1 0.33

Step 5: Substitute words with their weighted frequencies

Заменим каждое из слов, найденных в исходных предложениях, их взвешенными частотами, а затем вычислим их сумму.

Так как взвешенные частоты несущественных слов, таких как стоп-слова и спецсимволы, которые были удалены на этапе обработки, равны нулю, добавлять их не нужно.

Sentence Add weighted frequencies Sum
1 Peter and Elizabeth took a taxi to attend the night party in the city 1 + 0.67 + 0.33 + 0.33 + 0.33 + 0.33 + 0.67 + 0.33 3.99
2 While in the party, Elizabeth collapsed and was rushed to the hospital 0.67 + 0.67 + 0.33 + 0.33 + 0.67 2.67
3 Since she was diagnosed with a brain injury, the doctor told Peter to stay besides her until she gets well. 0.33 + 0.33 + 0.33 + 0.33 + 1 + 0.33 + 0.33 + 0.33 + 0.33 +0.33 3.97
4 Therefore, Peter stayed with her at the hospital for 3 days without leaving 1 + 0.67 + 0.67 + 0.33 + 0.33 + 0.33 3.33

From the sum of the weighted frequencies of the words, we can deduce that the first sentence carries the most weight in the paragraph. Therefore, it can give the best representative summary of what the paragraph is about.

Furthermore, if the first sentence is combined with the third sentence, which is the second-most weighty sentence in the paragraph, a better summary can be generated.

Приведенный выше пример просто дает базовую иллюстрацию того, как выполнять обобщение текста на основе извлечения в машинном обучении Теперь давайте посмотрим, как мы можем применить описанную выше концепцию при создании генератора сводок в реальном мире.

Text summarization of a Wikipedia article

Давайте запачкаем руки и создадим средство суммирования текста, которое может сократить информацию, содержащуюся в длинной веб-статье.NLTK toolkit, мы не будем использовать какое-либо другое машинное обучение библиотека.

Here is the code blueprint of the summarizer:

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

Here are the steps for creating a simple text summarizer in Python.

Step 1: Preparing the data

In this example, we want to summarize the information found on this Wikipedia article, which just gives an overview of the major happenings during the 20th century.

Чтобы мы могли получить текст статьи, мы будем использоватьBeautiful Soup library.

Вот код для очистки содержимого статьи:

import bs4 as BeautifulSoup
import urllib.request  

# Fetching the content from the URL
fetched_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/20th_century')

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

In the above code, we begin by importing the essential libraries for fetching data from the web page. The BeautifulSoup library is used for parsing the page while the urllib library is used for connecting to the page and retrieving the HTML.

BeautifulSoup converts the incoming text to Unicode characters and the outgoing text to UTF-8 characters, saving you the hassle of managing different charset encodings while scraping text from the web.

Мы будем использоватьurlopen function from the urllib.requestутилита, чтобы открыть веб-страницу. Затем мы будем использоватьreadфункция для чтения очищенного объекта данных.Для разбора данных мы вызовем функциюBeautifulSoup object and pass two parameters to it; that is, the article_read and the html.parser.

The find_all function is used to return all the <p> elements present in the HTML. Furthermore, using .text enables us to select only the texts found within the <p> elements.

Step 2: Processing the data

Чтобы убедиться, что удаленные текстовые данные как можно более бесшумны, мы выполним базовую очистку текста.Чтобы помочь нам выполнить обработку, мы импортируем списокstopwords from the nltk library.

Мы также будем импортироватьPorterStemmer, which is an algorithm for reducing words into their root forms. For example, cleaning, cleaned, and cleaner can be reduced to the root clean.

Кроме того, мы создадим словарную таблицу с частотой появления каждого из слов в тексте.Мы пройдемся по тексту и соответствующим словам, чтобы исключить любые стоп-слова.

Затем мы проверим, присутствуют ли слова вfrequency_table. If the word was previously available in the dictionary, its value is updated by 1. Otherwise, if the word is recognized for the first time, its value is set to 1.

For example, the frequency table should look like the following:

Word Frequency
century 7
world 4
United States 3
computer 1

Here is the code:

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: Токенизация статьи в предложения

To split the article_content в набор предложений, мы будем использовать встроенный метод изnltk library.

from nltk.tokenize import word_tokenize, sent_tokenize

sentences = sent_tokenize(article)

Step 4: Finding the weighted frequencies of the sentences

Чтобы оценить количество баллов для каждого предложения в тексте, мы будем анализировать частоту встречаемости каждого термина, в этом случае мы будем оценивать каждое предложение по его словам, то есть складывать частоту каждого найденного важного слова. в предложении.

Take a look at the following code:

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

Importantly, to ensure long sentences do not have unnecessarily high scores over short sentences, we divided each score of a sentence by the number of words found in that sentence.

Также для оптимизации памяти словаря мы произвольно добавилиsentence[:7], which refers to the first 7 characters in each sentence. However, for longer documents, where you are likely to encounter sentences with the same first n_chars, лучше использовать хеш-функции или функции интеллектуального индекса, чтобы учитывать такие крайние случаи и избегать коллизий.

Step 5: Calculating the threshold of the sentences

Чтобы дополнительно настроить тип предложений, подходящих для суммирования, мы создадим средний балл для предложений, С помощью этого порога мы можем избежать выбора предложений с более низким баллом, чем средний балл.

Here is the code:

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

Step 6: Getting the summary

Lastly, since we have all the required parameters, we can now generate a summary for the article.

Here is the code:

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

Wrapping Up

Here is an image that showcases the workflow for creating the summary generator.

A basic workflow of creating a summarization algorithm

Here is the entire code for the simple extractive text summarizer in machine learning:

#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('https://en.wikipedia.org/wiki/20th_century')

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)

You can click the following button to run the code on the FloydHub Notebook:

Run on FloydHub

В этом случае мы применили порог в 1,5 раза от среднего балла.hyperparameter value that generated for us good results after a couple of trials. Of course, you can fine-tune the value according to your preferences and improve the summarization outcomes.

Here is an image of the summarized version of the Wikipedia article.

A Wikipedia article summarized using a summarization algorithm

As you can see, running the code summarizes the lengthy Wikipedia article and gives a simplistic overview of the main happenings in the 20th century.

Nonetheless, the summary generator can be improved to make it better at producing a concise and precise summary of voluminous texts.

Взятие вещей на ступеньку выше…

Of course, this article just brushed the surface of what you can achieve with a text summarization algorithm in machine learning.

To learn more about the subject, especially about abstractive text summarization, here are some useful resources you can use:

  • Is it possible to combine the two approaches (abstractive and extractive)? It is the main idea behind the pointer-generator network that gets the best of both worlds by combining both extraction(pointing) and abstraction(generating).
Image from "Taming Recurrent Neural Networks for Better Summarization"
  • How to use WikiHow, a large-scale text summarization dataset— В этой статье представлен WikiHow, новый крупномасштабный набор данных для обобщения текстов, который включает более 230 000 статей, извлеченных из онлайн-база знаний WikiHow.Большинство доступных в настоящее время наборов данных недостаточно велики для обучения моделей последовательностей, они могут предоставлять только ограниченные сводки и больше подходят для выполнения экстрактивного суммирования. Тем не менее, набор данных WikiHow является крупномасштабным, высококачественным и позволяет достичь оптимальных результатов при абстрактном обобщении.
  • How a pretraining-based encoder-decoder framework can be used in text summarization— В этой статье представлена ​​уникальная двухэтапная модель, основанная на парадигме «последовательность к последовательности». использованиеBERT (you can bet that we will continue to read about BERT in all 2019) on both encoder and decoder sides and focuses on reinforced objective during the learning process. When the model was assessed on some benchmark datasets, the outcome revealed that the approach performed better at text summarization, particularly when compared to other traditional systems.

Special appreciation to the entire team at FloydHub, especially Alessio, за их ценные отзывы и поддержку в улучшении качества и подачи этой статьи. камень!


About Alfrick Opidi

Альфрик — веб-разработчик, глубоко заинтересованный в изучении мира машинного обучения. В настоящее время он участвует в проектах по внедрению концепций машинного обучения в создание гибких и футуристических веб-приложений. В свободное время он занимается в техническом письме, чтобы демистифицировать сложные концепции машинного обучения для людей. Считайте его всесторонним техническим специалистом, который внимательно следит за тем, чтобы последние разработки в отрасли были доступными и увлекательными для изучения. Альфрик такжеFloydHub AI Writer. You can find out more about him here. You can connect with Alfrick on LinkedIn and GitHub.