Всем привет! Меня зовут Максим. Я NLP‑инженер в red_mad_robot и автор Telegram‑канала Максим Максимов // IT, AI. Это вторая часть серии статей про метрики задач NLP, в которой я затрону тему оценки качества в задачах генерации текста. Мы рассмотрим следующие метрики:
Начнем!
Генерация текста
Оценка качества генерации текста не является тривиальной задачей. Сложность заключается в том, что текст на естественном языке имеет определенную последовательность, состоит из различных слов, одну и ту же мысль можно описать по‑разному и так далее. Справиться с этой задачей помогают специальные метрики оценки, которые созданы для того, чтобы сравнивать сгенерированный текст (кандидатов) с эталонным (референсом).
Данные метрики могут использоваться в различных задачах NLP. Например: генерация ответа на вопрос, суммаризация, перевод с одного языка на другой и другие.
Для дальнейшего повествования я буду использовать небольшую часть датасета gazeta с Hugging Face. Этот набор данных содержит новостные посты с сайта Газета и их краткие обзоры (саммари). Его мы будем использоваться для оценки задачи суммаризации текста.

Возьмем оттуда 10 примеров данных в формате: исходных текст, краткое содержание.
Один пример данных:
«text»: «Американское аэрокосмическое агентство NASA огласило названия четырех космических миссий, которые в скором времени могут быть выбраны для реализации и запуск которых может состояться уже в конце этого десятилетия. Эти четыре проекта стали полуфиналистами конкурса, объявленного среди американских научных команд, в котором участвовало более десяти миссий. Все они были отобраны по критериям потенциальной пользы для науки и технической осуществимости проекта. В рамках программы Discovery NASA занимается планированием миссий, которые призваны дать ответы на фундаментальные вопросы о происхождении тел Солнечной системы и возможному наличию жизни на них. „Эти выбранные миссии могут трансформировать наше восприятие некоторых из наиболее активных и сложных миров в Солнечной системе, — заявил Томас Зурбучен, помощник директора NASA по науке. — Исследование каждого из этих небесных тел поможет раскрыть секреты о том, как они и им подобные объекты образовались в космосе“. Каждый проект из выбранных полуфиналистов получит $3 млн на проработку концепции. Из четырех выбранных проектов NASA планирует отобрать две в 2021 году, чтобы профинансировать работу по их реализации в рамках программы Discovery. Два из четырех проектов посвящены исследованию Венеры, куда аппараты NASA не отправлялись уже свыше тридцати лет — с 1989 года, когда к этой планете был запущен зонд Magellan. Миссия VERITAS ( Venus Emissivity, Radio Science, InSAR, Topography, and Spectroscopy) призвана картировать поверхность Венеры для лучшего понимания геологической истории планеты и получения ответа на вопрос о причинах ее кардинальных отличий от Земли. Карта будет построена при помощи радара, установленного на орбитальном аппарате. В ходе миссии планируется узнать, продолжаются ли в наши дни на Венере тектонические и вулканические процессы. Кроме того, планируется картировать поверхность планеты в инфракрасном диапазоне. Миссия DAVINCI+ (Deep Atmosphere Venus Investigation of Noble gases, Chemistry and Imaging Plus) задумана для того, чтобы исследовать состав атмосферы Венеры, понять, как она формировалась и эволюционировала в прошлом, и ответить на вопрос о существовании когда‑либо на планете жидкого океана. Сделать это планируется при помощи спускаемого аппарата, который будет проводить измерения от верхних слоев атмосферы до самой поверхности. Научные инструменты аппарата будут размещены внутри герметичного сферического корпуса, который должен защитить их от разрушительного воздействия высокой температуры атмосферы. + в названии миссии говорит о наличии в ее составе камер, которые будут присутствовать на борту орбитального и спускаемого аппаратов. „Проект DAVINCI+ пересекается по целям с российской миссией „Венера‑Д“, обе нацелены на посадку, поэтому в будущем возможно их совмещение в одном совместном проекте“, — сказал „Газете.Ru“ основатель проекта „Открытый космос“ Виталий Егоров. Миссия TRIDENT должна исследовать Тритон — ледяной спутник Нептуна, известный ученым своей активностью. Данные, полученные американским зондом Voyager 2, показали, что поверхность Тритона активно обновляется. Ученые считают, что Тритон, на котором выпадает „снег“ из органических веществ, может оказаться отличной целью для понимания вопросов происхождения аналогичных тел в Солнечной системе. Пролетев мимо Тритона, аппарат попытается картировать его поверхность, изучить активные процессы на его поверхности и определить, есть ли под его поверхностью жидкий океан. Миссия IVO (Io Volcano Observer) должна направиться к одному из самых интересных спутников Юпитера — Ио. Это тело с наиболее мощной вулканической активностью в Солнечной системе, которая поддерживается за счет мощного приливного воздействия со стороны Юпитера. Во время нескольких близких пролетов аппарат выяснит, как формируется лава на поверхности спутника.», «title»: «Венера, Ио или Тритон: куда полетит NASA»,
«summary»:«В NASA назвали четыре миссии в дальний космос, которые в этом десятилетии могут быть запущены американцами. Среди них — две миссии по изучению Венеры, полет к спутнику Юпитера и экспедиция к Тритону, спутнику Нептуна.»
Далее я сгенерирую с помощью LLM краткие выжимки для исходных текстов, чтобы затем посчитать на их основе метрики. В качестве LLM я буду использовать GigaChat.
Начнем с загрузки данных: отберем 10 примеров из датасета
import json with open('./gazeta_test.jsonl', 'r', encoding='utf-8') as f: data = [json.loads(line) for line in f if line.strip()] # Для демонстрации берем 10 строк данных data = data[:10]
Напишем простенький промпт для суммаризации и функцию для этого
import os from gigachat import GigaChat giga = GigaChat(credentials=os.getenv("GIGA_API_KEY"), verify_ssl_certs=False, model="GigaChat-Max") def summarize_text(text): prompt = """Проанализируй предоставленный текст новостной статьи и создай краткое суммаризированное описание в 1-2 предложения. Исходный текст: {text} Краткое описание:""" response = giga.chat(prompt.format(text=text)) return response.choices[0].message.content
Далее прогоним наши 10 примеров и получим сгенерированную выжимку
test_data = [] for i, el in enumerate(data): print(f"{i + 1}/{len(data)}") text = el["text"] target_summary = el["summary"] generate_summary = summarize_text(text) test_data.append({"text": text, "target_summary": target_summary, "generate_summary": generate_summary})
На выходе получаем данные в формате:
text — исходный текст новости
target_summary — исходный бриф
generate_summary — сгенерированный бриф
Отлично, мы получили результат работы LLM для генерации краткой выжимки. Теперь необходимо каким‑то образом оценить качество генерации. Для этого мы рассмотрим несколько популярных метрик. Для каждой из них мы сначала погрузимся в небольшую теорию, а после на практике произведем оценку.
BLEU
Bilingual Evaluation Understudy (BLEU) — это одна из первых метрик для оценки генерации текста. На данный момент эта метрика остается одной из самых популярных в использовании для автоматической и недорогой оценки генерации текста.
Ниже будет описан процесс подсчета BLUE для простого примера.
Для понимания этой метрики вспомним, что такое N‑граммы. N‑грамма — это последовательность букв, слогов или слов из N‑элементов. В данном случае мы рассмотрим N‑граммы слов. Рассмотрим наиболее популярные разновидности N‑грамм на примере предложения: «Кот сел на стол».

N‑грамма — основная составляющая метрики BLEU.
Представим, что мы сгенерировали следующий текст: «Кот сел». Посчитаем метрику BLEU между этим сгенерированным текстом (кандидатом) и исходным текстом (референсом), приведенным выше («Кот сел на стол»).
Для этого необходимо получить N‑граммы для кандидата и референса. Для исходного текста мы уже получили N‑граммы выше. Теперь получим N‑граммы для сгенерированного текста:

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

Для униграмм пересечение между кандидатом и референсом равно 2. Посмотрим на биграммы

Для биграмм пересечение между сгенерированным и исходным текстов равно 1. Глянем на триграммы

Для триграмм пересечение между сгенерированным и исходным текстом равно 0.
Далее для каждого пересечения получим коэффициент pn — долю N‑грамм из сгенерированного текста, которые встречаются в исходном тексте. Для этого необходимо поделить количество n‑грамм в пересечении на общее количество n‑грамм в кандидате:
Далее посчитаем среднее гармоническое
На этом можно было остановиться и указать, что BLEU равно 0. Но для этой метрики при подсчёте можно использовать не все три n‑граммы, а только две. Тогда получаем:
При учёте только униграмм и биграмм получаем идеальный результат. Но, как можно было заметить, «кот сел» и «кот сел на стол» — не идентичные тексты.
Для борьбы с такими ситуациями в BLEU имеется так называемый штраф за краткость, который мы рассмотрим ниже.
Назовем часть, которую мы вычислили выше — BLEU*.
Перейдем еще к одной составляющей метрики BLEU — штрафу за краткость. Сгенерированный текст может неоправданно завышать оценку BLEU, потому что может содержать все N‑граммы эталонного текста.
Для закрепления понимания попробуйте рассчитать BLEU* по алгоритму выше для метрики между референсом: «собака громко лает» и текстом‑кандидатом: «громко лает». Для униграмм и биграмм.
Примечание:
Также стоит отметить момент, касающийся ситуаций, когда в тексте‑кандидате имеется несколько одинаковых N‑грамм, которые присутствуют в эталонном тексте. Например текст‑кандидат: «кот кот кот» эталонный текст: «кот пьет молоко». В таком случае при подсчете униграмм пересечение будет равно 1, а не 3, потому что при подсчете пересечения в BLEU учитываются только уникальные N‑граммы.
Для наказания слишком коротких строк‑кандидатов определите штраф за краткость следующим образом:
В нашем примере кандидат имеет длину 2 («Кот сел»), а референс — 4. Соответственно, применяя формулу выше, получаем:
Объединив все воедино, получаем следующую формулу BLEU:
Для нашего примера при учете униграмм, биграмм и триграмм получаем:
если мы учитываем только униграммы и биграммы, то получаем
В интернете чаще всего приводят формулу BLEU в следующем виде:
Мне же удобнее ее воспринимать в таком виде:
Теперь произведем те же расчеты на Python. Дополнительно продемонстрируем расчет метрики с использованием библиотеки nltk.
from nltk.translate.bleu_score import sentence_bleu import math generate_text = "Кот сел" target_text = "Кот сел на стол" # ��окенизация candidate = ['кот', 'сел'] reference = ['кот', 'сел', 'на', 'стол'] # unigram p1 = 2/2 # bigram p2 = 1/1 # Штраф за краткость c = 2 r = 4 BP = math.exp(1 - r/c) # BLEU-2 BLEU = BP * math.exp(0.5*math.log(p1) + 0.5*math.log(p2)) print(BLEU) print(sentence_bleu([reference], candidate, weights=(0.5, 0.5, 0, 0))) # 0.36787944117144233 # 0.36787944117144233
Получаем такой же результат.
Отлично, мы разобрались в метрике BLEU, теперь давайте произведем расчеты этой метрики для нашего датасета новостей. Рассчитаем BLEU-1, BLEU-2, BLEU-3, BLEU-4 (для соответствующих N‑грамм).
from nltk.translate.bleu_score import corpus_bleu, SmoothingFunction def calculate_corpus_bleu(targets, predictions): # Токенизация tokenized_targets = [[t.lower().split()] for t in targets] tokenized_predictions = [p.lower().split() for p in predictions] # Веса для разных BLEU weights_list = [ (1.0, 0, 0, 0), # BLEU-1 (0.5, 0.5, 0, 0), # BLEU-2 (0.333, 0.333, 0.333, 0), # BLEU-3 (0.25, 0.25, 0.25, 0.25) # BLEU-4 ] for i, weights in enumerate(weights_list, 1): score = corpus_bleu( tokenized_targets, tokenized_predictions, weights=weights ) print(f"BLEU-{i}: {score:.4f}") target_summaries = [el["target_summary"] for el in test_data] generate_summaries = [el["generate_summary"] for el in test_data] calculate_corpus_bleu(target_summaries, generate_summaries) # BLEU-1: 0.1614 # BLEU-2: 0.0878 # BLEU-3: 0.0591 # BLEU-4: 0.0425
Как мы помним, BLEU рассчитывается в диапазоне от 0 до 1, где 1 — это наилучшее совпадение. В данном случае видим достаточно низкий показатель генерации. Но здесь стоит повториться, что это не значит, что брифы составлены практически неверно — вполне возможно, что текст написан другими словами.
Думаю, на этом моменте вы начинаете понимать, в чем проблема этой метрики. Поясню: один и тот же текст может быть описан разными словами. Это значит, что не всегда низкий показатель метрики BLEU означает плохой результат. Возможно, просто текст написан по‑другому (а может и правда всё плохо).
Также стоит учесть, что BLEU не так часто используется для оценки суммаризации текста — для этого чаще всего применяют метрику ROUGE, которую мы рассмотрим далее.
ROUGE
Метрика ROUGE — это еще одна метрика для оценки качества генерации текста. Эта метрика лучше подходит для задач суммаризации текста (а также может использоваться и в других задачах, связанных с генерацией). Это связано с некоторыми особенностями ее подсчета, которые мы рассмотрим ниже.
Существует несколько видов метрик ROUGE. Давайте рассмотрим наиболее популярные из них.
ROUGE-N
Это доля перекрытия N‑грамм между сгенерированным и эталонным текстами. В какой‑то степени она может напоминать подсчет BLEU, но здесь не вычисляется среднее гармоническое и не применяются штрафы, а просто вычисляется количество совпавших N‑грамм между сгенерированным и эталонным текстами и делится на общее количество N‑грамм в эталонном тексте.
Таким образом, формула ROUGE‑N выглядит следующим образом:
Наиболее часто используют ROUGE-1 (униграммы) и ROUGE-2 (биграммы). Рассмотрим небольшой пример.
Подсчитаем ROUGE-1 для следующей пары текстов:
Сгенерированный текст: The cat sat on the mat.
Эталонный текст: The cat is on the mat.

Количество униграмм в пересечении = 5. Общее количество униграмм в эталонном текста = 6
Таким образом, ROUGE-1 = 5/6 = 0.83 (83%)
Примечание:
Также эту метрику можно посчитать через Precision и Recall.
Для того же примера:
Precision (точность) = Число совпавших униграмм / Общее число униграмм в сгенерированном тексте = 5 / 6 ≈ 0,83.
Recall (полнота) = Число совпавших униграмм / Общее число униграмм в эталонном тексте = 5 / 6 ≈ 0,83.
F1-score (ROUGE-1) = 2 × (Precision × Recall) / (Precision + Recall) = 2 × (0,83 × 0,83) / (0,83 + 0,83) = 0,83.
Такой подход позволяет оценить не только то, насколько полно результат покрывает эталон (Recall), но и насколько он точен (Precision), исключая лишнюю информацию.
Давайте проведем те же расчеты на языке Python. Для удобства существует готовая библиотека rouge, которая позволяет рассчитывать метрику ROUGE.
from rouge import Rouge hypothesis = "The cat is on the mat." reference = "The cat sat on the mat." rouge = Rouge() scores = rouge.get_scores(hypothesis, reference) print(scores[0]['rouge-1']['f']) # 0.83333332
В качестве практики попробуйте рассчитать ROUGE-2 для этого же примера собственноручно, а после на Python с использованием библиотеки rouge.
ROUGE-L
ROUGE‑L измеряет самую длинную последовательность слов, которые встречаются в обоих текстах в одном и том же порядке (L в названии происходит от LCS — наибольшей общей подпоследовательности). На основе этого происходит оценка — чем больше такая последовательность, тем выше метрика.
Формула выглядит следующим образом:
Рассмотрим пример. Рассчитаем ROUGE‑L для следующих примеров:
Сгенерированный текст: A quick brown animal jumps over a lazy dog.
Эталонный текст: The quick brown fox jumps over the lazy dog.

LCS для данного примера: «brown fox over the dog» (совпадение 6 слов).
Общее количество слов в эталонном примере — 9
Таким образом:
Произведем те же расчеты на Python:
from rouge import Rouge hypothesis = "A quick brown animal jumps over a lazy dog" reference = "The quick brown fox jumps over the lazy dog" rouge = Rouge() scores = rouge.get_scores(hypothesis, reference) print(scores[0]['rouge-l']['f']) # 0.66
В качестве практики рассчитайте ROUGE‑L вручную и на Python для примера:
Сгенерированный текст: Собака играет с мячом в саду.
Эталонные текст: В саду большая собака играет.
Отлично, мы рассмотрели наиболее популярные виды метрики ROUGE, попробуем рассчитать данную метрику для нашего прим��ра с суммаризацией текста. Сделаем это также, используя библиотеку rouge:
import json from rouge import Rouge rouge = Rouge() scores = rouge.get_scores(generate_summaries, target_summaries, avg=True) print(f"rouge-1 = {scores["rouge-1"]["f"]}") print(f"rouge-2 = {scores["rouge-2"]["f"]}") print(f"rouge-l = {scores["rouge-l"]["f"]}") # rouge-1 = 0.1551326321274879 # rouge-2 = 0.041712278818910056 # rouge-l = 0.14058738325870962
Нельзя однозначно сказать, плохой это результат или хороший. Возможно, ниже среднего. Но было бы правильнее, если бы мы сравнивали его с другими моделями или подходами. Соответственно, на основе сравнения этих метрик у обоих подходов можно было бы сказать, какая модель лучше, а какая хуже с точки зрения этой метрики.
METEOR
METEOR (Metric for Evaluation of Translation with Explicit ORdering) — это ещё одна метрика для оценки генерации текста, которая позиционируется как улучшенная версия BLEU. Помимо учёта точных совпадений N‑грамм, метрика METEOR использует корни слов и синонимы, что позволяет ей лучше коррелировать с человеческой оценкой.
Рассмотрим пример подсчёта метрики METEOR.
Перед этим скажу следующее: как говорилось выше, эта метрика использует не только точное сравнение N‑грамм, но также сравнение их корней (после стемминга) и синонимов. То есть выделяются три модуля обработки N‑грамм:

точное совпадение;
стемминг (выделение корней слов и поиск совпадений);
синонимы (в качестве базы слов чаще всего используется WordNet).
Возьмем тестовый пример:
Эталонный текст: «A fast brown fox leaps over a lazy dog»
Сгенерированный текст: «The quick brown fox jumps over the lazy dog»
После токенизации получаем:
Эталонный текст: a, fast, brown, fox, leaps, over, a, lazy, dog (9 слов)
Сгенерированный текст: the, quick, brown, fox, jumps, over, the, lazy, dog (9 слов)
Далее проведем сравнения по каждому из вышеперечисленных модулей:
Точное сравнение. Здесь имеется точное пересечение слов: brown, fox, over, lazy, dog (5 слов)
Стемминг. Если извлечь корни из всех слов в предложениях и найти пересечение, совпадений не будет (например jumps → jump, или leaps → leap).
Синонимы (используя WordNet). quick и fast — синонимы, jumps и leaps — синонимы. В данном случае получаем 2 совпадения.
Итого получает mathes = 2 + 5 =7 (из 9 возможных).
Теперь вычисляются Precision и Recall
Используя Precision и Recall подсчитывается среднее гармонической (F1 с параметром alpha)
Но это ещё не всё: метрика METEOR также использует так называемый штраф за неверный порядок слов. То есть штрафуются моменты, когда модель подобрала правильные слова, но расставила их в неправильном порядке.
В нашем примере:
Совпавшие слова в кандидате (с их позициями):
позиция 2: quick (совпало с fast как синоним)
позиция 3: brown (точное)
позиция 4: fox (точное)
позиция 5: jumps (синоним к leaps)
позиция 6: over (точное)
позиция 8: lazy (точное)
позиция 9: dog (точное)
В эталоне эти же слова (в том же порядке смысловых соответствий) занимают позиции:
2: fast
3: brown
4: fox
5: leaps
6: over
8: lazy
9: dog
Теперь смотрим на кандидата: слова с 2 по 6 идут подряд (нет пропусков между ними) — это один chunk. Затем после позиции 6 идёт позиция 7 (слово the, которое не совпало), а потом снова совпавшие слова на позициях 8–9 — это второй chunk. Таким образом, у нас два непрерывных блока. Далее вычисляем штраф по формуле:
γ=0.5 (коэффициент, определяющий максимальный штраф);
β=3 (степень, регулирующая «жёсткость» штрафа);
chunks — количество непрерывных блоков;
matches — общее количество совпавших униграмм.
Теперь у нас есть все необходимые элементы для вычисления метрики METEOR. Итоговая формула выглядит следующим образом:
Для вычисления этой метрики на Python можно также воспользоваться библиотекой nltk
import nltk from nltk.translate.meteor_score import meteor_score # Ensure required resources are downloaded nltk.download('wordnet', quiet=True) nltk.download('omw-1.4', quiet=True) # Define reference and hypothesis texts reference = "A fast brown fox leaps over a lazy dog" candidate = "The quick brown fox jumps over the lazy dog" # Calculate METEOR scores score = meteor_score([reference.split()], candidate.split()) print(f"METEOR Score: {score:.4f}") # METEOR Score: 0.7687
Примечание:
Так как наш датасет новостей состоит из примеров на русском языке, я не смог найти готовых решений и словарей, чтобы рассчитать эту метрику для русского языка. Это не означает, что данную метрику невозможно вычислить для любого языка — если вы создадите словарь синонимов, который можно будет использовать для этой метрики, то её вполне можно применить.
BERTScore
Последняя на сегодня метрика, которую мы рассмотрим — это BERTScore.
Эта метрика отличается от предыдущих тем, что она использует эмбеддинги для подсчёта косинусной близости пар предложений вместо N‑грамм, как это делалось в BLEU или ROUGE.
Давайте шаг за шагом пройдёмся по этапам расчёта BERTScore (пример из официальной статьи).
Представим, что мы имеем пару:
Эталонный текст — the weather is cold today.
Сгенерированный текст — it is freezing today.
Первым делом происходит вычисление эмбеддингов для каждого токена в предложениях (о том, что такое эмбеддинги, я подробно рассказывал в своей статье здесь). Для этого используется предобученная нейросетевая модель BERT.

После получения эмбеддингов вычисляется попарное косинусное сходство между каждым вектором эталонного текста и каждым вектором кандидата (то есть получаем попарную косинусную близость каждого вектора друг с другом). На основе этого строится матрица (рисунок ниже).
Помимо матрицы происходит подсчет IDF (вспоминаем TF‑IDF), который показывает, насколько слово редко встречается в корпусе: чем реже слово, тем выше его вес:
Используя эту матрицу, мы пытаемся найти для каждого токена из эталонного текста максимально близкий токен среди векторов кандидата.

После построения матрицы косинусных сходств мы для каждого токена референса находим максимальную похожесть с токенами кандидата.
Recall — это взвешенное среднее этих максимумов с учётом IDF, где деление идёт на сумму весов, чтобы учесть важность редких слов.
Precision считается аналогично, но для каждого токена кандидата ищется максимум среди токенов референса, после чего берётся обычное среднее арифметическое (без IDF), делённое на длину кандидата.
Формулы следующие:
После этого происходит расчет итогового BERTScore — обычно используется F₁‑мера, которая объединяет точность и полноту, чтобы сбалансировать обе оценки:
Это финальное значение и есть оценка качества сгенерированного текста: чем ближе к единице, тем лучше кандидат соответствует эталону и по смыслу, и по полноте передачи важных слов.
Резюмируя, получаем следующие шаги для подсчёта BERTScore:
Получаем эмбеддинги для каждого токена из референса и кандидата, используя BERT.
Производим попарное перемножение всех векторов кандидата с векторами референса, получаем матрицу. Подсчитываем IDF.
Для каждого токена референса находим максимально близкий (по косинусной близости) токен кандидата.
Каждое полученное на шаге 3 значение используем для подсчёта Precision и Recall. После вычисляем F1 — наш BERTScore.

Отлично, теперь произведем расчеты BERTScore на python. Для этого существует библиотека bert_score, которая предоставляет удобный интерфейс для работы.
# Установите библиотеку: pip install bert-score from bert_score import score reference = ["the weather is cold today"] candidates = ["it is freezing today"] P, R, F1 = score(candidates, reference, lang='en', rescale_with_baseline=True) print(f" Precision = {P[i].item():.4f}") print(f" Recall = {R[i].item():.4f}") print(f" F1 = {F1[i].item():.4f}") # Precision = 0.7019 # Recall = 0.5586 # F1 = 0.6299
Отлично, далее подсчитаем BERTScore для нашего датасета с новостями. К счастью, в библиотеке имеется мультиязычная модель, с помощью которой мы можем произвести расчеты с текстом на русском языке.
from bert_score import score # Оптимальная модель для русского языка model_path = 'bert-base-multilingual-cased' # Расчет P, R, F1 = score( generate_summaries, target_summaries, lang="ru", model_type=model_path, rescale_with_baseline=True # Делает оценку более наглядной (от 0 до 1) ) # Получаем среднее значение F1 mean_f1 = F1.mean().item() print(f"BERTScore F1: {mean_f1:.4f}") # BERTScore F1: 0.6925
В сравнении с BLEU, ROUGE и METEOR — BERTScore показал достаточно высокий результат суммаризации новостей.
Заключение
В этой статье мы рассмотрели одни из популярных метрик оценки генерации текста: BLEU, ROUGE, METEOR, BERTScore. Этот список метрик не исчерпывающий, но чаще всего именно они встречаются в популярных научных статьях по NLP.
Подписывайтесь на мой Telegram‑канал, в котором я также рассказываю интересные вещи об IT и AI технологиях.
