Сравнение текстов «вручную»

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


Пример 1

  1. Создадим мини-модель эмбеддингов (векторы слов вручную).
  2. Реализуем TF-IDF взвешивание.
  3. Посчитаем усреднённые векторы документов.
  4. Сравним их через косинусное сходство.
  5. Визуализируем результаты.

🔍 Шаг 1: Создаём «базу знаний» — ручные эмбеддинги (hand-crafted embeddings)

Допустим, у нас есть 5 слов и мы вручную зададим их векторы (размерность=3), отражающие:

  • animal (животное): чем ближе к 1, тем более «животное» слово.
  • action (действие): чем ближе к 1, тем более «активное» слово.
  • location (место): чем ближе к 1, тем больше связано с местом.
СловоВектор [animal, action, location]Пояснение
кот[0.9, 0.1, 0.3]Животное, мало действий
собака[0.8, 0.5, 0.2]Животное, более активное
лежит[0.2, 0.1, 0.8]Действие + связано с местом
бежит[0.1, 0.9, 0.4]Активное действие
подоконник[0.0, 0.0, 0.9]Чисто «место»

📝 Шаг 2: Подготовка документов

Возьмём 3 документа (уже предобработанные):

  • D1: [«кот», «лежит»]
  • D2: [«собака», «бежит»]
  • D3: [«кот», «лежит», «подоконник»]

Уникальные слова (термины):
["кот", "лежит", "собака", "бежит", "подоконник"]


📊 Шаг 3: Вычисляем TF-IDF

TF-IDF (Term Frequency-Inverse Document Frequency) — статистическая мера, которая:

  • TF (Term Frequency): Учитывает частоту слова в документе.
  • IDF (Inverse Document Frequency): Штрафует слова, встречающиеся во многих документах (например, предлоги).

3.1. Считаем TF (Term Frequency) — частота слова в документе

ТерминD1D2D3
кот1/2 = 0.501/3 ≈ 0.333
лежит1/2 = 0.501/3 ≈ 0.333
собака01/2 = 0.50
бежит01/2 = 0.50
подоконник001/3 ≈ 0.333

3.2. Считаем IDF

IDF (Inverse Document Frequency) — это мера того, насколько редким или уникальным является слово в коллекции документов.

  • В классической формуле TF-IDF (например, в sklearn) используется натуральный логарифм (ln⁡).
  • Но в некоторых старых источниках или ручных вычислениях применяют log⁡10​.
Без логарифма:С логарифмом:
Редкие слова получают гипертрофированный вес, искажая результаты.Веса слов балансируются:: частые слова (например, «и», «в») получают почти нулевой IDF, редкие — умеренный вес.

Всего документов: 3.

Расчёт IDF:

ТерминntIDF
кот2 (D1, D3)log⁡(3/2)≈0.405
лежит2 (D1, D3)log⁡(3/2)≈0.405
собака1 (D2)log⁡(3/1)≈1.098
бежит1 (D2)log⁡(3/1)≈1.098
подоконник1 (D3)log⁡(3/1)≈1.098

3.3. TF-IDF = TF * IDF

ТерминD1D2D3
кот0.5 × 0.405 ≈ 0.20300.333 × 0.405 ≈ 0.135
лежит0.5 × 0.405 ≈ 0.20300.333 × 0.405 ≈ 0.135
собака00.5 × 1.098 ≈ 0.5490
бежит00.5 × 1.098 ≈ 0.5490
подоконник000.333 × 1.098 ≈ 0.366

Итоговые вектора документов:

  • D1[0.203 (кот), 0.203 (лежит), 0 (собака), 0 (бежит), 0 (подоконник)]
  • D2[0, 0, 0.549 (собака), 0.549 (бежит), 0]
  • D3[0.135 (кот), 0.135 (лежит), 0, 0, 0.366 (подоконник)]

Интерпретация:

  • «Собака» и «бежит» имеют высокий TF-IDF в D2, так как встречаются только там.
  • «Подоконник» уникален для D3, поэтому его вес максимален в этом документе.
  • «Кот» и «лежит» встречаются в двух документах, поэтому их TF-IDF ниже.

Этот метод помогает выделить наиболее значимые термины для каждого документа.


🧮 Шаг 4: Усреднение векторов с учётом TF-IDF

1. Вектора слов

СловоВектор
кот[0.9, 0.1, 0.3]
собака[0.8, 0.5, 0.2]
лежит[0.2, 0.1, 0.8]
бежит[0.1, 0.9, 0.4]
подоконник[0.0, 0.0, 0.9]

2. TF-IDF веса

СловоD1D2D3
кот0.20300.135
лежит0.20300.135
собака00.5490
бежит00.5490
подоконник000.366

Усреднение по документам:

  1. Умножаем каждый вектор слова на его TF-IDF вес в документе.
  2. Суммируем полученные вектора.
  3. Делим на сумму TF-IDF весов (или количество слов, если используем простое усреднение).

Документ D1: [«кот», «лежит»]

  1. Умножаем вектора на TF-IDF:
    • кот = [0.9, 0.1, 0.3] × 0.203 ≈ [0.1827, 0.0203, 0.0609]
    • лежит = [0.2, 0.1, 0.8] × 0.203 ≈ [0.0406, 0.0203, 0.1624]
  2. Суммируем:[0.1827+0.0406, 0.0203+0.0203, 0.0609+0.1624]=[0.2233, 0.0406, 0.2233]
  3. Делим на сумму TF-IDF (0.203 + 0.203 = 0.406):≈[0.55, 0.10, 0.55]

Итоговые усреднённые вектора документов:

ДокументУсреднённый вектор (animal, action, location)Интерпретация
D1[0.55, 0.10, 0.55]Сбалансирован между animal и location (кот лежит где-то).
D2[0.45, 0.70, 0.30]Максимум action (собака бежит), средние значения animal и location.
D3[0.23, 0.04, 0.75]Доминирует location (подоконник), слабые animal и action.

Такой подход позволяет:

  1. Учитывать семантику слов (через их вектора).
  2. Взвешивать вклад каждого слова через TF-IDF.
  3. Получать осмысленные документные вектора, отражающие их содержание.

🔥 Шаг 5: Сравнение через косинусное сходство

Косинусная близость (cosine similarity) — это мера схожести двух векторов, вычисляемая как косинус угла между ними. В NLP (Natural Language Processing) она часто используется для сравнения векторных представлений слов, предложений или документов.

Косинусное сходство измеряет угол между векторами, игнорируя их длину. Однако если вектора имеют разную длину, скалярное произведение может дать искажённые результаты. Поэтому:

Нормализация — это процесс приведения векторов к единичной длине (норме), что особенно важно для корректного расчёта косинусного сходства.

L2-нормализация (евклидова норма)

Дано:

  • D1[0.55, 0.10, 0.55] (норма ≈ 0.784) → [0.701, 0.128, 0.701]
  • D2[0.45, 0.70, 0.30] (норма ≈ 0.874) → [0.515, 0.801, 0.343]
  • D3[0.23, 0.04, 0.75] (норма ≈ 0.788) → [0.292, 0.051, 0.955]

После нормализации (||A|| = ||B|| = 1) косинусное сходство можно считать как простое скалярное произведение: cos(θ) = A · B

Косинусное сходство после нормализации

ДокументыD1D2D3
D11.0000.7080.831
D20.7081.0000.366
D30.8310.3661.000

Интерпретация:

  • D1 и D3 наиболее близки (оба содержат «кот» и «лежит»).
  • D2 («собака бежит») отличается от остальных.

📉 Шаг 6: Визуализация в 2D

Используем PCA.

*D1 и D3 близки по оси PC1 (Animal + Location), D2 выделяется по PC2 (Action).*

💡 Выводы:

  1. Ручные эмбеддинги позволяют контролировать признаки (например, «животное», «действие»).
  2. TF-IDF уменьшает влияние частых слов (например, «кот» в нескольких документах).
  3. Косинусное сходство показывает семантическую близость (даже если слова разные).
  4. Визуализация помогает увидеть кластеры документов.

Пример 2.

После предобработки (токенизации, приведения к нижнему регистру и удаления стоп-слов) документы имеют следующий вид:

  • Док1: [«кот», «лежит»]
  • Док2: [«собака», «бежит»]
  • Док3: [«кот», «лежит», «подоконник»]
  • Док4: [«собака», «бежит», «парк»]
  • Док5: [«птица», «сидит», «подоконник»]
  • Док6: [«кот», «ловит», «птица»]

Шаг 1: Построение словаря уникальных терминов

Из всех документов извлекаем уникальные слова (термины):

  1. «кот» (Док1, Док3, Док6)
  2. «лежит» (Док1, Док3)
  3. «собака» (Док2, Док4)
  4. «бежит» (Док2, Док4)
  5. «подоконник» (Док3, Док5)
  6. «парк» (Док4)
  7. «птица» (Док5, Док6)
  8. «сидит» (Док5)
  9. «ловит» (Док6)

Итоговый словарь:
["кот", "лежит", "собака", "бежит", "подоконник", "парк", "птица", "сидит", "ловит"]


Шаг 2: Векторизация документов (Bag of Words)

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

ТерминДок1Док2Док3Док4Док5Док6
кот101001
лежит101000
собака010100
бежит010100
подоконник001010
парк000100
птица000011
сидит000010
ловит000001

Шаг 3: Анализ тематик (группировка документов)

Можно выделить несколько тематических групп на основе совпадения терминов:

  1. Тема «Кот»:
    • Док1: кот + лежит.
    • Док3: кот + лежит + подоконник.
    • Док6: кот + ловит + птица.
  2. Тема «Собака»:
    • Док2: собака + бежит.
    • Док4: собака + бежит + парк.
  3. Тема «Птица»:
    • Док5: птица + сидит + подоконник.
    • Док6: кот + ловит + птица (пересечение с темой «Кот»).
  4. Общий термин «подоконник»:
    • Док3 (кот) и Док5 (птица).

Шаг 4: Построение матрицы косинусной близости

Вычисление косинусной близости для всех пар:

1. Док1 vs Док2:

  • Векторы: A=[1,1,0,0,0,0,0,0,0], B=[0,0,1,1,0,0,0,0,0]
  • Скалярное произведение: 0+0+0+0+0+0+0+0+0=0
  • Нормы: ∥A∥=1+1=2​, ∥B∥=1+1=2
  • Результат: 0/(2⋅2)=0.

2. Док1 vs Док3:

  • Векторы: A=[1,1,0,0,0,0,0,0,0], B=[1,1,0,0,1,0,0,0,0]
  • Скалярное произведение: 1+1+0+0+0+0+0+0+0=2
  • Нормы: ∥A∥=2, ∥B∥=1+1+1=3
  • Результат: 2/(2⋅3)≈0.82.

Итоговая матрица косинусной близости (6×6):

Док1Док2Док3Док4Док5Док6
Док11.000.000.820.000.000.41
Док20.001.000.000.820.000.00
Док30.820.001.000.000.330.33
Док40.000.820.001.000.000.00
Док50.000.000.330.001.000.33
Док60.410.000.330.000.331.00

Интерпретация результатов:

  1. Высокая близость (≥0.8):
    • Док1 и Док3 («кот», «лежит»).
    • Док2 и Док4 («собака», «бежит»).
  2. Средняя близость (~0.3–0.4):
    • Док3 и Док5 («подоконник»).
    • Док3 и Док6 («кот»).
    • Док5 и Док6 («птица»).
  3. Нулевая близость:
    • Документы без общих терминов (например, Док1 и Док2).

Матрица подтверждает тематическую группировку, выявленную ранее.


Шаг 5: Кластеризация методом k-means (k=3)

Цель:

Автоматически разделить 6 документов на 3 кластера на основе их векторных представлений (из шага 2) и матрицы косинусной близости (из шага 4).


Подготовка данных

Исходные векторы документов (Bag of Words):

Документкотлежитсобакабежитподоконникпаркптицасидитловит
Док1110000000
Док2001100000
Док3110010000
Док4001101000
Док5000010110
Док6100000101

Применение алгоритма k-means

k-means — алгоритм кластеризации, который:

  1. Выбирает k начальных центроидов (случайно или по правилу).
  2. Назначает каждый документ ближайшему центроиду (по косинусной близости).
  3. Пересчитывает центроиды как среднее векторов в кластере.
  4. Повторяет шаги 2–3 до сходимости.

Шаг 2.1: Инициализация центроидов (k=3)

Выберем 3 случайных документа в качестве начальных центроидов:

  • Центроид 1: Док1 ([1, 1, 0, 0, 0, 0, 0, 0, 0])
  • Центроид 2: Док2 ([0, 0, 1, 1, 0, 0, 0, 0, 0])
  • Центроид 3: Док5 ([0, 0, 0, 0, 1, 0, 1, 1, 0])

Шаг 2.2: Назначение документов кластерам

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

ДокументЦентроид 1 (Док1)Центроид 2 (Док2)Центроид 3 (Док5)Ближайший кластер
Док11.000.000.00Кластер 1
Док20.001.000.00Кластер 2
Док30.820.000.33Кластер 1
Док40.000.820.00Кластер 2
Док50.000.001.00Кластер 3
Док60.410.000.33Кластер 1

Промежуточные кластеры:

  • Кластер 1: Док1, Док3, Док6
  • Кластер 2: Док2, Док4
  • Кластер 3: Док5

Шаг 2.3: Пересчёт центроидов

Вычисляем средний вектор для каждого кластера:

  1. Кластер 1 (Док1, Док3, Док6):
    • Среднее по «кот»: (1+1+1)/3=1
    • Среднее по «лежит»: (1+1+0)/3≈0.67
    • Среднее по «подоконник»: (0+1+0)/3≈0.33
    • Среднее по «птица»: (0+0+1)/3≈0.33
    • Среднее по «ловит»: (0+0+1)/3≈0.33
    • Остальные: 0.
    • Новый центроид 1[1, 0.67, 0, 0, 0.33, 0, 0.33, 0, 0.33]
  2. Кластер 2 (Док2, Док4):
    • Среднее по «собака»: (1+1)/2=1
    • Среднее по «бежит»: (1+1)/2=1
    • Среднее по «парк»: (0+1)/2=0.5
    • Остальные: 0.
    • Новый центроид 2[0, 0, 1, 1, 0, 0.5, 0, 0, 0]
  3. Кластер 3 (Док5):
    • Новый центроид 3 (без изменений): [0, 0, 0, 0, 1, 0, 1, 1, 0]

Шаг 2.4: Повторное назначение документов

Повторяем вычисление косинусной близости с новыми центроидами:

ДокументЦентроид 1 (новый)Центроид 2 (новый)Центроид 3 (Док5)Ближайший кластер
Док10.920.000.00Кластер 1
Док20.000.890.00Кластер 2
Док30.880.000.33Кластер 1
Док40.000.840.00Кластер 2
Док50.190.001.00Кластер 3
Док60.640.000.33Кластер 1

Кластеры не изменились → алгоритм сошёлся.


3. Итоговые кластеры

КластерДокументыТематика
1Док1, Док3, Док6Кот
2Док2, Док4Собака
3Док5Птица

Пояснения:

  • Кластер 1: Объединяет документы с ключевым словом «кот».
  • Кластер 2: Документы с «собака» и «бежит».
  • Кластер 3: Док5 («птица»«подоконник») оказался в отдельном кластере, так как не имеет сильной связи с другими.

Проблемный момент:

  • Док6 («кот ловит птица») мог бы быть отнесён к кластеру 3 из-за «птица», но доминирующий термин «кот» перевесил.

Шаг 6: Визуализация (опционально)

Можно использовать PCA для уменьшения размерности и отобразить документы в 2D:

  • Ось X: Главная компонента (например, «кот» vs «собака»).
  • Ось Y: Вторая компонента (например, «подоконник»).
  • Док1, Док3, Док6 будут близки по X, Док5 смещён к «подоконник».

Итоговые согласованные результаты:

  1. Тематические группы:
    • Кот: Док1, Док3, Док6.
    • Собака: Док2, Док4.
    • Птица: Док5 (частично Док6).
  2. Словарь терминов: 9 уникальных слов.
  3. Схожесть документов:
    • Наибольшая: Док1-Док3, Док2-Док4.
    • Наименьшая: Док2-Док5 (нет общих терминов).

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


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

Сравнительные методы в анализе текстов развивались параллельно с развитием лингвистики, компьютерных технологий и исторических исследований:

  • XXI век: Развитие BERT, Doc2Vec и других методов на основе глубокого обучения.
  • XIX век: Сравнительно-исторический метод в лингвистике (Ф. Бопп, Я. Гримм) использовался для анализа родства языков.
  • XX век: Появление TF-IDF (1960–70-е), векторных моделей (1990-е), нейросетевых подходов (2010-е).

Сравнительная таблица методов анализа документов

МетодТипУчёт контекстаТочностьСкоростьПлюсыМинусыИдеальное применение
Bag-of-Words (BoW)СтатистическийНизкая⚡⚡⚡⚡Простота, интерпретируемостьИгнорирует порядок слов и семантикуБыстрый прототипинг, точный поиск ключевых слов
TF-IDFСтатистическийСредняя⚡⚡⚡Учёт важности слов в коллекцииЧувствителен к длине документаПоисковики (Elasticsearch), классификация
BM25СтатистическийВысокая⚡⚡⚡Учёт длины документа, нелинейный TFНет семантикиПоисковые системы, ранжирование
Word2Vec/GloVe (усреднение)Векторный✔️ (частично)Средняя⚡⚡Улавливает семантику словТеряет порядок словКластеризация, рекомендации
Doc2VecВекторный✔️Высокая⚡⚡Учёт контекста документаТребует много данных для обученияАнализ отзывов, тематическое моделирование
BERT/Sentence-BERTНейросетевой✔️✔️✔️Очень высокая⚡ (требует GPU)Лучшая семантическая точностьРесурсоёмкостьЮридические/медицинские тексты, чат-боты
Siamese NetworksНейросетевой✔️✔️✔️Очень высокая⚡ (требует GPU)Сравнение пар документовСложность обученияДетекция плагиата, поиск дубликатов

Инструменты для сравнения документов

Программные библиотеки

  • Python:
    • scikit-learn (TF-IDF, косинусное сходство).
    • gensim (Word2Vec, Doc2Vec).
    • transformers (BERT, RoBERTa).
  • Rtmtext2vec.

Готовые решения

  • Diff Tools:
    • R7-OfficeMicrosoft Word — сравнение версий документов 13.
    • ArcGIS File Compare — для текстовых и бинарных файлов 7.

Онлайн-сервисы

  • Plagiarism Checkers (Turnitin, Antiplagiat).
  • Semantic Text Similarity APIs (Google NLP, Hugging Face).

Прокрутить вверх