TF-IDF (Term frequency – inverce document frequency) – статистическая мера, которая оценивает важность слова для документа в коллекции документов (корпусе).
Определения
Термин (t) – слово, встречающееся в конкретном документе и (не обязательно) в других документах корпуса.
Документ (d) – единичный текст из большого набора текстов – корпуса.
Корпус (D) – большой набор уникальных текстов, коллекция документов.
Основные идеи метода
Часто встречающиеся в корпусе слова имеют небольшой IDF, так как они не несут важной информации.
Редкие, но характерные для конкретного документа слова получают высокий вес.
Формула TF-IDF
Представляет собой произведение двух величин: TF и IDF
TF(t, d) – частота вхождения термина t в документ d.
TF(t, d) = Количество вхождений термина t в документ d / Общее количество терминов в документе d
IDF(t, D) – обратная частота документа.
IDF(t, D) = log(N / (1 + nt))
На практике часто используется сглаженная версия формулы:
IDF(t, D) = log(1 + N / (1 + nt)) + 1
N – общее число документов
nt – число документов, содержащих термин t.
Область применения
Классификация текстов (спам – не спам, определение темы письма)
Поиск и ранжирование документов (поисковые и рекомендательные системы)
Кластеризация текстов (группировка отзывов)
Извлечение ключевых слов (по весам TF-IDF можно отобрать ключевые слова текста)
TF-IDF полезен там, где нужно учесть важность слов, а не только их частоту.
TF-IDF уместен
На небольших датасетах (до 100000 текстов).
Создание быстрых прототипов: TF-IDF + логистическая регрессия часто дают baseline качество.
Когда тексты короткие и простые (заголовки, отзывы, темы писем).
Для языков с простой морфологией (английский) или с хорошей лемматизацией (русский).
В поисковых движках для быстрого вычисления релевантности.
Примеры
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
docs = [
"Машинное обучение и анализ данных",
"Анализ данных важен для бизнеса",
"Обучение нейронных сетей требует данных",
]
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(docs)
print("Words in the dictionary: ", vectorizer.get_feature_names_out())
print()
print("TF-IDF matrix: \n", tfidf_matrix.toarray())
Вывод – показывает полный список слов и вес каждого слова в каждом из трех текстов.
Words in the dictionary: ['анализ' 'бизнеса' 'важен' 'данных' 'для' 'машинное' 'нейронных' 'обучение' 'сетей' 'требует']
TF-IDF matrix:
[[0.4804584 0. 0. 0.37311881 0. 0.63174505
0. 0.4804584 0. 0. ]
[0.38376993 0.50461134 0.50461134 0.29803159 0.50461134 0.
0. 0. 0. 0. ]
[0. 0. 0. 0.29803159 0. 0.
0.50461134 0.38376993 0.50461134 0.50461134]]
Пример применения TF-IDF в задаче классификации текстов.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import classification_report, accuracy_score
# Это корпус текстов с метками классов
df = pd.DataFrame({
"text": [
"Купите новый айфон прямо сейчас",
"Срочно звоните, выиграли миллион",
"Как готовить вкусный борщ",
"Рецепт полезного смузи",
"Скидка 50% на смартфоны"
],
"label": ["spam", "spam", "ham", "ham", "spam"]
})
X_train, X_test, y_train, y_test = train_test_split(df["text"], df["label"], test_size=0.3, random_state=1)
# Пайплайн сначала преобразует тексты в числовые векторы весов каждого слова,
# а затем использует эти векторы как данные для обучения.
pipeline = Pipeline([
("tfidf", TfidfVectorizer()),
("clf", LogisticRegression(max_iter=1000))
])
pipeline.fit(X_train, y_train)
# При тесте данные также сначала преобразуются в числовые векторы,
# а затем на этих векторах обучается модель логистической регрессии.
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred))