АВТОРЫ: НИЛП ПАТЕЛЬ, Шри Патель, Друванш Праджапати, Самарт Пури
ОБЗОР
Генерация резюме — это задача обработки естественного языка, которая включает в себя создание краткого и связного резюме более длинного фрагмента текста. Существуют различные способы решения этой задачи, начиная от простых методов, основанных на правилах, и заканчивая более сложными моделями машинного обучения. В этом сообщении блога мы рассмотрим три различных подхода к созданию сводок: использование предварительно обученной языковой модели, использование TfidfVectorizer и использование косинусного расстояния nltk.
Первый подход предполагает использование TfidfVectorizer для создания сводки. Этот подход включает в себя создание векторного представления каждого предложения в тексте, а затем ранжирование предложений на основе их релевантности. Чтобы реализовать этот подход, нам сначала нужно импортировать необходимые библиотеки и создать функцию суммирования, которая принимает фрагмент текста и возвращает сводку. Функция начинается с токенизации текста с помощью spacy, а затем создания объекта TfidfVectorizer. Затем TfidfVectorizer помещается в список предложений и используется для преобразования предложений в векторы. Затем векторы суммируются, и в качестве сводки выбираются первые N предложений, где N — количество предложений, которые мы хотим получить в сводке.
Второй подход включает использование косинусного расстояния nltk для создания сводки. Этот подход включает в себя измерение сходства между предложениями и выбор наиболее похожих предложений в качестве резюме. Чтобы реализовать этот подход, нам сначала нужно импортировать необходимые библиотеки и создать функцию generate_summary, которая принимает имя файла и возвращает сводку. Функция начинается с чтения файла и разметки предложений с использованием стоп-слов nltk. Затем создается матрица сходства путем сравнения каждого предложения с каждым другим предложением в тексте. Затем матрица преобразуется в график с помощью networkx, а алгоритм PageRank используется для ранжирования предложений в зависимости от их важности. Затем в качестве сводки выбираются лучшие N предложений.
Третий подход предполагает использование предварительно обученной языковой модели, такой как T5, для создания сводки. Модель T5 была обучена на большом наборе текстовых данных и способна генерировать человекоподобные сводки, предсказывая следующее слово в последовательности. Чтобы использовать этот подход, нам сначала нужно установить необходимые библиотеки и загрузить данные. Затем мы можем создать NewsSummaryDataset и NewsSummaryDataModule для обработки и загрузки данных. Далее мы можем определить нашу модель, создав модель T5ForConditionalGeneration и указав гиперпараметры. Наконец, мы можем обучить модель, определив оптимизатор AdamW и обратный вызов ModelCheckpoint для сохранения весов модели в каждую эпоху.
НАБОР ДАННЫХ
В этом проекте мы использовали только один набор данных и использовали его при обучении заголовка, а также модели сводки 3.
МОДЕЛИ
› ГЛАВНАЯ МОДЕЛЬ
код модели поезда присутствует по данной ссылке:
код начинается с импорта необходимых библиотек и считывания данных из CSV-файла с помощью pandas. Данные состоят из заголовков и текста для каждой новостной статьи. Затем данные предварительно обрабатываются, чтобы иметь правильный формат для обучения модели T5, которая ожидает фрейм данных со столбцами "source_text" и " target_text”. Исходный текст — это текст, который необходимо обобщить, а целевой текст — это резюме.
Затем данные разделяются на обучающий набор и тестовый набор с помощью функции train_test_split из sci-kit-learn. Класс SimpleT5 импортируется из библиотеки simplet5, а модель T5 создается с помощью метода from_pretrained. Затем модель обучается на тренировочном наборе с использованием метода обучения. Параметр eval_df указывает набор тестов, который будет использоваться для оценки во время обучения. Параметры source_max_token_len и target_max_token_len указывают максимальную длину исходного текста и целевого текста соответственно. Параметр batch_size указывает количество выборок на одно обновление градиента, а параметр max_epochs указывает максимальное количество эпох для поезд для. Параметр use_gpu указывает, использовать ли графический процессор для обучения.
› ОБЗОР 3 МОДЕЛЬ
код модели поезда присутствует по данной ссылке:
В этом блоке кода мы устанавливаем несколько библиотек, которые необходимы для нашей задачи суммирования текста с использованием модели T5. Эти библиотеки включают transformers, pytorch-lightning, torchtext и torchvision.
Затем мы импортируем эти библиотеки, а также некоторые дополнительные библиотеки, такие как pandas, numpy и pyplot. Мы также установили некоторые настройки визуализации, используя seaborn и matplotlib.
Затем мы читаем файл CSV, содержащий текстовые данные, и создаем кадр данных pandas с текстовыми и сводными столбцами. Затем мы разделяем данные на обучающие и тестовые наборы с помощью train_test_split.
Мы определяем класс NewsSummaryDataset, который принимает фрейм данных и объект T5Tokenizer, а также некоторые необязательные параметры для максимальной длины токена. Этот класс позволяет нам получить доступ к данным в фрейме данных как к объекту набора данных, что будет полезно для обучения и оценки нашей модели.
Мы также определяем класс NewsSummaryDataModule, который наследуется от класса pytorch_lightning LightningDataModule. Этот класс отвечает за создание загрузчиков данных для наших обучающих и тестовых наборов данных, а также за указание некоторых необязательных гиперпараметров, таких как размер пакета и текст, а также суммарная максимальная длина токена.
Наконец, мы определяем класс NewsSummaryModel, который наследуется от класса LightningModule pytorch_lightning. Этот класс содержит логику для обучения и оценки нашей модели, а также для создания сводок из входного текста. Он содержит несколько ключевых методов, таких как configure_optimizers, training_step, validation_step. и test_step.
Определив эти классы и функции, мы теперь можем использовать NewsSummaryModel для обучения и оценки модели суммирования текста с использованием модели T5.
ИЗВЛЕКАТЕЛЬНОЕ РЕЗЮМЕ
› ОБЗОР 1
from sklearn.feature_extraction.text import TfidfVectorizer from spacy.lang.en import English import numpy as np nlp = English() nlp.add_pipe('sentencizer') def summarizer(text, tokenizer=nlp, max_sent_in_summary=3): doc = nlp(text.replace("\n", "")) sentences = [sent.text.strip() for sent in doc.sents] sentence_organizer = {k:v for v,k in enumerate(sentences)} vectorizer = TfidfVectorizer(min_df=2, max_features=None, strip_accents='unicode', analyzer='word', token_pattern=r'\w{1,}', ngram_range=(1, 3), use_idf=1,smooth_idf=1, sublinear_tf=1, stop_words = 'english') vectorizer.fit(sentences) vectors = vectorizer.transform(sentences) scores = np.array(vectors.sum(axis=1)).ravel() N = max_sent_in_summary top_n_sentences = [sentences[ind] for ind in np.argsort(scores, axis=0)[::-1][:N]] top_n = [(sentence,sentence_organizer[sentence]) for sentence in top_n_sentences] top_n = sorted(top_n, key = lambda x: x[1]) ordered_scored_sentences = [element[0] for element in top_n] summary = " ".join(ordered_scored_sentences) return summary
функция TfidfVectorizer из библиотеки scikit-learn импортируется и используется для векторизации списка предложений. TfidfVectorizer преобразует список предложений в матрицу числовых значений, представляющих важность каждого слова в каждом предложении.
Объект nlp из английского модуля библиотеки spaCy также импортируется и используется для добавления канала Sentencizer к объекту nlp. Sentencizer используется для разделения текста на отдельные предложения.
Функция суммирования принимает фрагмент текста и токенизатор, которым в данном случае является объект nlp с добавленным каналом Sentencizer. Функция также принимает параметр максимального количества предложений, которые должны быть включены в сводку.
Сначала текст проходит через объект nlp, чтобы разделить его на отдельные предложения, которые затем сохраняются в переменной sentences. Затем создается словарь sentence_organizer, который сопоставляет каждое предложение с соответствующим индексом в исходном списке предложений.
Затем TfidfVectorizer подгоняется к списку предложений и используется для преобразования предложений в векторы. Сумма каждого вектора вычисляется и сохраняется в переменной scores. Затем выбираются первые N предложений с наивысшими оценками и сохраняются в списке top_n_sentences.
Затем создается список top_n, который представляет собой список кортежей, содержащих каждое из первых N предложений и соответствующий ему индекс в исходном списке предложений. Затем список «top_n» сортируется на основе индексов предложений. Окончательное резюме создается путем объединения отсортированного списка предложений и возвращается в качестве вывода.
› ОБЗОР 2
import nltk #Natural Language ToolKit nltk.download('stopwords') from nltk.corpus import stopwords from nltk.cluster.util import cosine_distance import numpy as np import networkx as nx def read_article(file_name): with open(file_name) as f: a = " ".join(line.strip() for line in f) with open(file_name,"r+") as f: f.truncate(0) f.write(a) file = open(file_name,"r") filedata = file.readlines() #print(filedata) article = filedata[0].split(". ") sentances=[] for sentance in article: sentances.append(sentance.replace("[^a-zA-Z]","").split(" ")) #sentances.pop() return sentances def sentance_similarity(sent1,sent2,stopwords=None): if stopwords is None: stopwords=[] sent1 = [w.lower() for w in sent1] sent2 = [w.lower() for w in sent2] all_words = list(set(sent1+sent2)) vector1= [0] * len(all_words) vector2= [0] * len(all_words) for w in sent1: if w in stopwords: continue vector1[all_words.index(w)] += 1 for w in sent2: if w in stopwords: continue vector2[all_words.index(w)] += 1 return 1-cosine_distance(vector1,vector2) def gen_sim_matrix(sentances,stop_words): similarity_matrix=np.zeros((len(sentances),len(sentances))) for idx1 in range(len(sentances)): for idx2 in range(len(sentances)): if idx1 == idx2: continue similarity_matrix[idx1][idx2]=sentance_similarity(sentances[idx1],sentances[idx2],stop_words) return similarity_matrix def generate_summary(file_name,top_n=5): stop_words=stopwords.words('english') summarize_text=[] sentances = read_article(file_name) matrix=gen_sim_matrix(sentances,stop_words) graph=nx.from_numpy_array(matrix) scores = nx.pagerank(graph) ranked_sentance=sorted(((scores[i],s)for i,s in enumerate(sentances)),reverse=True) for i in range(top_n): summarize_text.append(" ".join(ranked_sentance[i][1])) text = ". ".join(summarize_text)
Здесь мы используем алгоритм TextRank для извлечения резюме из фрагмента текста. Алгоритм TextRank — это основанный на графах метод для задач обработки естественного языка, таких как суммирование, извлечение ключевых слов и машинный перевод.
Код начинается с импорта необходимых библиотек, включая Natural Language Toolkit (nltk) и библиотеку networkx для работы с графами в Python. Также загружается и импортируется корпус стоп-слов из nltk, представляющий собой список общеупотребительных английских слов, которые часто удаляются из текстовых данных, поскольку они не имеют большого значения.
Функция read_article читает текстовый файл и разбивает его на отдельные предложения. Функция sentance_similarity вычисляет сходство между двумя предложениями на основе наличия общих слов, исключая стоп-слова. Функция gen_sim_matrix создает матрицу показателей сходства для всех пар предложений в тексте.
Функция generate_summary — это основная функция для создания сводки текста. Сначала он вызывает функцию gen_sim_matrix для создания матрицы показателей сходства, а затем преобразует эту матрицу в график с помощью networkx библиотека. Затем к графику применяется алгоритм PageRank для расчета оценки для каждого предложения. Затем выбираются лучшие N предложений, которые возвращаются в качестве сводки.
РЕЗЮМЕ
› ОБЗОР 3
from models.summary_model.model import SummaryModel,tokenizer trained_model = SummaryModel.load_from_checkpoint("models\\summary_model\\best-checkpoint.ckpt") trained_model.freeze() def summarize(text): text_encoding = tokenizer( text, max_length=512, padding="max_length", truncation=True, return_attention_mask=True, add_special_tokens=True, return_tensors="pt" ) generated_ids = trained_model.model.generate( input_ids=text_encoding["input_ids"], attention_mask=text_encoding["attention_mask"], max_length=150, num_beams=2, repetition_penalty=2.5, length_penalty=1.0, early_stopping=True ) preds = [ tokenizer.decode(gen_id, skip_special_tokens=True, clean_up_tokenization_spaces=True) for gen_id in generated_ids ] return "".join(preds)
Этот код использует предварительно обученную сводную модель для создания сводки заданного фрагмента текста. Класс SummaryModel импортируется из модуля summary_model.model, а также функции токенизатора. Затем обученная_модель загружается из файла контрольной точки с помощью метода load_from_checkpoint и замораживается, чтобы предотвратить дальнейшее обучение.
Функция суммирования принимает фрагмент текста и кодирует его с помощью функции токенизатора. Затем закодированный текст передается методу generate модели, который генерирует сводку текста. Сгенерированная сводка возвращается в качестве вывода.
Метод generate имеет несколько параметров, которые можно настроить для управления поведением генерации сводки. Параметр max_length указывает максимальную длину генерируемой сводки, параметр num_beams управляет количеством лучей, используемых в алгоритм поиска луча, а параметры repetition_penalty и length_penalty управляют компромиссом между повторением и длиной в сгенерированное резюме.
› ЗАГОЛОВКИ
from simplet5 import SimpleT5 def generate_headline(text): model = SimpleT5() model.load_model("t5","models\\headline_model", use_gpu=False) headline = model.predict(text)[0] return headline
предварительно обученная модель T5 для создания заголовка для заданного фрагмента текста. Класс SimpleT5 импортирован из библиотеки simplet5, которая предоставляет простой интерфейс для использования модели T5.
Функция generate_headline принимает фрагмент текста и создает объект SimpleT5. Затем модель загружается из файла контрольной точки с помощью метода load_model, а графический процессор отключается для прогнозирования. Затем текст передается в метод предсказания модели, который генерирует заголовок для текста. Сгенерированный заголовок возвращается в качестве вывода.
Модель T5 — это языковая модель на основе преобразователя, которая достигла самых современных результатов в широком спектре задач обработки естественного языка, включая обобщение и создание заголовков.
PDF-TO-ТЕКСТ
Это одна из функций, с помощью которой пользователь также может загрузить свой PDF-файл, чтобы подвести итоги.
Первый шаг — установить библиотеку PyPDF2 с помощью pip. Вы можете сделать это, выполнив следующую команду:
pip install pypdf2
После установки библиотеки мы можем начать использовать ее для извлечения текста из файла PDF. Ниже приведена простая функция, которая принимает путь к файлу в качестве входных данных и возвращает текст из файла PDF в виде строки:
def pdf_to_text(file): pdffile = open(file,'rb') pdfReader = PyPDF2.PdfFileReader(pdffile) num = pdfReader.numPages for i in range(0,num): pageobj = pdfReader.getPage(i) resulttext = pageobj.extractText() newfile = open(r"content.txt", "w") newfile.writelines(resulttext) demo=open("content.txt","r") str1=demo.read() return str1
Давайте подробнее рассмотрим, что происходит в приведенном выше коде. Сначала мы открываем файл PDF в режиме только для чтения и создаем объект для чтения PDF. Затем мы получаем количество страниц в файле PDF и перебираем каждую страницу, чтобы извлечь текст. Открываем новый текстовый файл и пишем в него текст. Наконец, мы открываем текстовый файл, читаем содержимое и возвращаем его в виде строки.
Чтобы использовать вышеуказанную функцию, все, что вам нужно сделать, это передать путь к файлу PDF в качестве аргумента. Функция вернет текст из файла PDF в виде строки. Затем вы можете использовать текст для дальнейшей обработки или сохранить его в текстовый файл.
В заключение, PyPDF2 — это мощная библиотека, которая позволяет нам легко извлекать текст из файла PDF и сохранять его в виде текстового файла или строки. Это полезный инструмент для всех, кто работает с PDF-файлами и нуждается в извлечении текста для дальнейшей обработки.
ОСНОВНОЙ
import streamlit as st from io import StringIO from pdf_txt import pdf_to_text from headline import generate_headline from summarizer1 import summarizer from summarizer2 import generate_summary from summarizer3 import summarize from pathlib import Path import os st.markdown("<h1 style='text-align: center;'>TEXT SUMMARIZER v2.0</h1>", unsafe_allow_html=True) file = st.file_uploader("Please choose a file", type=['txt', 'pdf']) st.markdown("<h5 style='text-align: center;'>OR</h5>", unsafe_allow_html=True) text = st.text_area("Input Text For Summary (More than 200 words)", height=200) col1, col2, col3 = st.columns(3) if col1.button('SUMMARIZE'): #try: if file is not None: if bool(text)== True: st.error("ERROR: YOU CAN'T ENTER BOTH") st.stop() else: if file.name[-3:] == "pdf": path=Path("uploaded_pdfs/" + file.name) path.write_bytes(file.getvalue()) text = pdf_to_text("uploaded_pdfs/" + file.name) else: stringio = StringIO(file.getvalue().decode("utf-8")) text=stringio.read() textfile = open("content.txt","w") textfile.write(text) textfile.close() headline=generate_headline(text) summary1=summarizer(text) summary2=generate_summary("content.txt") summary3=summarize(text) st.write("") st.subheader(headline) st.markdown("<h4> > Summary 1 : </h4>" , unsafe_allow_html=True) st.write(summary1) st.markdown("<h4> > Summary 2 : </h4>" , unsafe_allow_html=True) st.write(summary2) st.markdown("<h4> > Summary 3 : </h4>" , unsafe_allow_html=True) st.write(summary3)
Приведенный выше код предназначен для приложения Streamlit, которое позволяет пользователям вводить текст или PDF-файл и генерировать сводку ввода.
Первая строка импортирует библиотеку Streamlit. Следующие четыре строки импортируют различные функции из других модулей: pdf_to_text
для извлечения текста из файла PDF, generate_headline
для создания заголовка для введенного текста, summarizer
, generate_summary
и summarize
. для создания резюме введенного текста. Также импортируются библиотеки pathlib
и os
.
Приложение начинается с отображения заголовка и виджета загрузки файлов. Пользователь может либо ввести текстовый файл или файл PDF, либо ввести текст непосредственно в виджет текстовой области. Затем пользователь может нажать кнопку «СУММАРИЗИРОВАТЬ», чтобы сгенерировать сводку ввода.
Если пользователь вводит файл, код проверяет, является ли он PDF-файлом или нет. Если это файл PDF, код использует функцию pdf_to_text
для извлечения текста из файла и сохранения его в переменной с именем text
. Если это не PDF-файл, код считывает текст из файла и сохраняет его в text
. Затем переменная text
записывается в файл с именем 'content.txt'.
Затем код вызывает функции generate_headline
, summarizer
, generate_summary
и summarize
для создания трех сводок входного текста. Заголовок и резюме затем отображаются для пользователя.
ЗАКЛЮЧЕНИЕ
В заключение, существуют различные подходы, которые можно использовать для создания резюме текста. Каждый подход имеет свои сильные и слабые стороны, и лучший подход будет зависеть.
ПОЛНЫЙ ИСХОДНЫЙ КОД ПОСЕТИТЕ: →GitHub