Как извлекать ключевые фразы (keyword extraction) из текста без LLM (YAKE, RAKE, TF-IDF)?
Краткий тезис
Классические методы извлечения ключевых фраз — RAKE, YAKE и TF-IDF — позволяют выделить значимые n-граммы без использования LLM, опираясь на статистику и стоп-слова. Они эффективны на RU при скорости обработки в сотни раз выше, чем у генеративных моделей.
2. YAKE: статистические сигналы
YAKE (Yet Another Keyword Extractor) — мультиязычный алгоритм, не требующий стоп-слов. Он вычисляет 5 признаков для каждого токена:
- Casing — доля слов в верхнем регистре (собственные имена).
- Position — нормализованная позиция первого вхождения (чем раньше, тем выше).
- Frequency — обратная нормализованная частота.
- Relatedness — дисперсия расстояний между вхождениями слова.
- Differ — разнообразие контекстов (измеряется через количество уникальных соседей слева/справа).
Эти признаки объединяются в один score: score = (TermFrequency * WeightedPosition) / (Casing * Relatedness * Differ). Фразы строятся из подряд идущих слов, прошедших порог.
YAKE превосходит RAKE на коротких документах и лучше работает с морфологией русского языка благодаря нечувствительности к стоп-словам.
import yake
kw_extractor = yake.KeywordExtractor(lan="ru", top=5, ngram_size=3)
text = "Глубокое обучение революционизирует компьютерное зрение и NLP."
keywords = kw_extractor.extract_keywords(text)
for kw, score in keywords:
print(f"{kw}: {score:.3f}")
# глубокое обучение: 0.021
# компьютерное зрение: 0.033
# революционизирует: 0.047
Нюанс: YAKE использует «сглаживающие» коэффициенты, и score интерпретируется как «чем меньше, тем лучше» (обратная мера).
3. TF-IDF: высокий score
TF‑IDF традиционно применяется в информационном поиске. Для извлечения ключевых фраз его адаптируют так:
- Токенизация и лемматизация spaCy или NLTK.
- Построение n-грамм (обычно 1–3 слова, отсев по минимальной частоте).
- Расчёт TF в одном документе и IDF по корпусу (если корпус один — IDF заменяется 1 или используется коллекция внешних документов).
- Фразы с наибольшим
TF * IDFсчитаются ключевыми.
Проблема: классический TF‑IDF на одном документе не имеет IDF — все токены получают одинаковый вес, поэтому метод требует наличия корпуса.
На практике часто берут корпус случайных новостей или википедийных текстов того же домена.
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
corpus = [
"машинное обучение NLP анализ текстов",
"глубокое обучение нейронные сети",
"NLP обработка естественного языка"
]
vectorizer = TfidfVectorizer(ngram_range=(1,3), analyzer='word')
tfidf = vectorizer.fit_transform(corpus)
scores = np.array(tfidf[0].todense()).flatten()
features = vectorizer.get_feature_names_out()
top_idx = scores.argsort()[-5:][::-1]
for i in top_idx:
if scores[i] > 0:
print(features[i], scores[i])
# анализ текстов 0.54
# машинное обучение nlp 0.48
# nlp 0.41
Преимущество: хорошо масштабируется на большие коллекции. Недостаток: для каждого нового домена нужен свой корпус.
4. Сравнение с LLM (скорость vs качество)
| Характеристика | Классические методы (RAKE/YAKE/TF‑IDF) | LLM (GPT, Llama, YandexGPT) |
|---|---|---|
| Скорость | Мгновенно (10–50 мс на текст 1K токенов) | 0.5–5 сек на текст (с учётом латентности API) |
| Время инференса на 10K документов | ~0.5–2 мин | Часы (или дорого) |
| Качество на русском | Среднее (80–85% совпадений с экспертами) | Высокое (90–95% при правильно написанном prompt) |
| Требуемые ресурсы | CPU, десятки МБ | GPU, десятки ГБ ОЗУ или облачный API |
| Гибкость под домен | Нужен корпус (TF‑IDF) или стоп‑слова (RAKE) | Достаточно 1–2 примеров в запросе |
Когда выбирать без LLM:
- Высокая пропускная способность (реал‑тайм, потоковые данные).
- Ограниченные вычислительные ресурсы (edge‑устройства, мобильные).
- Чувствительность к задержкам (финансовые ленты, мониторинг).
Когда нужна LLM:
- Контекстная или аббревиатурная двусмысленность (например, "Apple" — компания или фрукт?).
- Генерация не только извлечённых фраз, но и названий разделов или суммаризации.
- Редкие или сложные термины в узкой предметной области.
На практике распространён гибрид: YAKE даёт быстрый черновик, LLM ранжирует или фильтрует результат.
Пет-проект для закрепления
Задача: Реализовать пайплайн извлечения ключевых фраз из новостных заголовков без LLM, сравнить RAKE и YAKE на датасете Lenta.ru (100 заголовков).
Инструменты:
- Python 3.10+
- Библиотеки:
pke,yake,scikit-learn,nltk,pandas - Стоп‑слова для русского:
nltk.corpus.stopwords.words('russian')
Шаги:
- Загрузите 100 заголовков новостей (можно взять из Lenta‑Dataset или с помощью RSS).
- Для RAKE: подготовьте стоп‑список, используйте
pke.unsupervised.Rake(). - Для YAKE:
yake.KeywordExtractor(lan="ru", top=5, ngram_size=2). - Для TF‑IDF: сформируйте корпус из тех же заголовков, векторизуйте с
ngram_range=(1,2), извлеките топ‑5 по среднему IDF (для каждого заголовка). - Сравните результаты вручную: отметьте, какие фразы совпали с интуитивно важными, постройте confusion‑матрицу (совпадения между тремя методами).
Ожидаемый результат:
- Вы получите датафрейм вида:
Текст RAKE_top5 YAKE_top5 TFIDF_top5 Комментарий (совпадение) - Увидите, что YAKE чаще выделяет редкие термины (собственные имена), RAKE — шаблонные биграммы, TF‑IDF даёт тематически общие фразы.
- В 70% случаев хотя бы одна фраза совпадает между YAKE и TF‑IDF, RAKE — около 50%.
Совет: попробуйте изменить параметры ngram_size и top — это существенно меняет результат.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 912. Как работают стоп-слова в NLP | Роль стоп-слов в фильтрации токенов — базовое понятие, необходимое для понимания RAKE |
Навигация
- Предыдущий: 946
- Следующий: 948
- Индекс: 00. Индекс разборов