Алгоритм MinHash за 30 минут: сжимаем миллиарды векторов до коротких сигнатур
Алгоритм MinHash (алгоритм минимальных хэшей) позволяет сжать огромный разреженный вектор из нулей и единиц в компактный набор целых чисел, сохранив при этом возможность сравнивать исходные векторы на похожесть, и разобраться в нём можно за один вечер на примере всего четырёх векторов.

Когда векторов миллиарды, а размерность каждого измеряется десятками тысяч, попарное сравнение в лоб физически невозможно. Алгоритм MinHash решает задачу: он создаёт короткую «подпись» вектора, по которой можно быстро прикинуть похожесть без возврата к оригиналу.
Алгоритм MinHash отвечает на конкретный вопрос: как транслировать разреженные бинарные (состоящие из нулей и единиц) векторы большой размерности в целочисленные векторы многократно меньшей размерности, сохранив информацию для оценки похожести. Результат называется сигнатурой (signature). Она уже не несёт геометрической информации исходного вектора, зато позволяет приблизительно вычислить коэффициент Жаккара, меру пересечения двух множеств. Размерность сигнатуры произвольная, но чем она длиннее, тем точнее оценка. Ниже разберём алгоритм на четырёх векторах размерности 20 с сигнатурой длиной 3. Такой масштаб помещается в голову, а принцип переносится на реальные данные с размерностями в 40 и 140 тысяч.
Что понадобится?
- Любой язык программирования или даже таблица: алгоритм MinHash реализуется буквально на бумаге.
- Четыре бинарных вектора размерности 20 (даны ниже).
- Три случайные перестановки (permutations) чисел от 1 до 20.
- Около 30 минут на разбор и ручной прогон.
- Для продакшена: семейство хэш-функций вместо готовых перестановок (экономит память и процессорное время).
Пошаговая инструкция: три шага алгоритма MinHash
Алгоритм состоит ровно из трёх действий. Разберём каждое.
Шаг 1. Генерируем вспомогательные последовательности
Каждая последовательность это числа от 1 до 20, перемешанные случайным образом. Их называют перестановками (permutations), потому что это буквально перестановка индексов. Число последовательностей равно желаемой длине сигнатуры. Нам нужна сигнатура длиной 3, значит генерируем три перестановки:
P1: 14 3 19 7 2 11 20 5 16 8 1 12 18 4 9 15 6 13 10 17
P2: 5 12 8 19 1 15 3 11 20 7 14 2 16 9 18 4 10 13 6 17
P3: 18 7 11 2 20 5 14 9 1 16 3 12 8 19 6 15 10 4 17 13
В реальном коде вместо хранения перестановок применяют хэш-функции. Каждая функция детерминированно отображает индекс в число, заменяя массив в памяти одним вызовом. Суть та же, реализация компактнее.
Шаг 2. Накладываем перестановку на вектор как битовую маску
Возьмём вектор V1:
V1: 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0
Единицы стоят в позициях 2, 5, 8, 12, 15, 18. Выписываем значения из первой перестановки P1 для этих позиций:
- Позиция 2 → значение 3
- Позиция 5 → значение 2
- Позиция 8 → значение 5
- Позиция 12 → значение 12
- Позиция 15 → значение 9
- Позиция 18 → значение 13
Получаем набор: 3, 2, 5, 12, 9, 13.
Шаг 3. Берём минимум и записываем в сигнатуру
Отсюда и название MinHash: из полученного набора забираем минимальное значение.
min(3, 2, 5, 12, 9, 13) = 2
Число 2 становится первым элементом сигнатуры вектора V1. Повторяем шаги 2 и 3 для каждой перестановки и каждого вектора. Четыре вектора, три перестановки, двенадцать проходов.
Итоговые сигнатуры:
- V1:
[2, 1, 4] - V2:
[2, 1, 6] - V3:
[7, 3, 2] - V4:
[1, 8, 1]
Два похожих вектора (V1 и V2, различающиеся только в разрядах 18 и 19) получили сигнатуры, совпадающие на двух из трёх позиций. Непохожие векторы не совпали ни в одной.
Проверяем, действительно ли сигнатуры сохраняют информацию о похожести. Считаем коэффициент Жаккара (отношение пересечения множеств к объединению) для исходных векторов:
- V1 и V2: коэффициент Жаккара = 0.714
- V1 и V3: коэффициент Жаккара = 0
- V1 и V4: коэффициент Жаккара = 0
Теперь оцениваем похожесть по сигнатурам. Долю совпавших позиций принимаем за приближённый коэффициент Жаккара:
- V1 и V2: совпали 2 из 3 позиций → 0.667 (реальный 0.714, близко)
- V1 и V3: совпали 0 из 3 → 0 (точно)
- V1 и V4: совпали 0 из 3 → 0 (точно)
Сигнатура длиной 3 уже отделяет похожие векторы от непохожих. Длиннее сигнатура, точнее оценка.
Короткая сигнатура и переоценка точности. Сигнатура длиной 3 даёт грубое приближение. На реальных данных с размерностью 40 000 и выше берите сигнатуры длиной от 100 и больше, иначе оценка похожести будет слишком шумной.
Путаница с геометрией. Сигнатура не является вектором в привычном геометрическом смысле. Считать для неё косинусное расстояние или евклидову метрику бессмысленно. Единственная корректная операция: подсчёт доли совпавших позиций как приближение коэффициента Жаккара.
Хранение перестановок целиком. При размерности 140 000 и сотне перестановок массивы займут гигабайты. В продакшене заменяйте перестановки семейством хэш-функций: каждая функция детерминированно превращает индекс в число, не требуя массива в памяти.
Применение к плотным векторам. Алгоритм MinHash предназначен для разреженных бинарных (sparse binary) векторов. Если ваш вектор плотный (большинство элементов ненулевые), MinHash будет работать, но без выигрыша: посмотрите на SimHash или LSH (Locality-Sensitive Hashing, хэширование, чувствительное к близости) для других типов данных.
Что делать с этим прямо сейчас?
ML-практику и разработчику. Возьмите четыре вектора из примера, прогоните алгоритм MinHash руками или в Jupyter-ноутбуке. Потом увеличьте размерность до 1 000, длину сигнатуры до 50 и посмотрите, как падает ошибка оценки Жаккара. Это займёт вечер и даст интуицию, которую не заменят десять прочитанных статей.
Автору и контент-маркетологу. MinHash используется внутри систем поиска дубликатов текстов. Если ваш контент проверяют на уникальность, велика вероятность, что под капотом работает именно этот или родственный алгоритм. Понимание принципа помогает осмыслить, почему переставленные абзацы всё равно ловятся как дубликаты.
Предпринимателю. Если у вас в продукте есть задача быстрого поиска похожих объектов (товаров, профилей, документов) среди миллионов записей, MinHash и его развитие LSH дают способ сравнивать не каждый с каждым, а кластеризовать кандидатов по сигнатурам. Реализации есть в открытых библиотеках на Python: datasketch, а также в Spark MLlib.
Алгоритм MinHash красив тем, что укладывается в три строчки псевдокода, но при этом масштабируется на миллиарды векторов. По моим наблюдениям, именно такие простые алгоритмы чаще всего работают в продакшене крупных поисковых систем и рекомендательных сервисов, потому что их легко распараллелить, легко отладить и легко объяснить команде.
Честная оговорка: на сигнатуре длиной 3 пример выглядит идеально, но автор оригинала прямо говорит, что подбирал данные для наглядности. На реальных данных с короткой сигнатурой ошибки будут заметнее. Не принимайте учебный пример за гарантию точности.
Попробуйте нейросети для работы с текстом
Если вы разбираетесь в алгоритмах, вам будет интересно протестировать, как нейросети помогают авторам Дзена находить темы и проверять тексты.
Попробовать инструменты dzen.guruРазобраться в MinHash стоит не ради экзамена, а ради одного навыка: видеть, как из трёх простых шагов рождается инструмент, который держит на себе поиск дубликатов в системах с миллиардами документов.

Основатель dzen.guru. Эксперт по монетизации и продвижению на Дзен. Автор курса «Старт на Дзен 2026».
Читайте также

Автосводка новостей дня из 4 источников: как Python-скрипт заменил ручные отчёты
Компания или автор запустили не коммерческий продукт, а личный скрипт-автоматизацию. Источник — авторский пост-разбор без названия компании-разработчика, без…

AI-агенты пишут 15% кода Block: как устроен Builderbot и его открытая основа Goose
Block сделала одну полезную вещь: рассказала не просто «мы используем ИИ-агентов» (ИИ-агент, программа, которая сама выполняет задачи по цепочке, а не ждёт…
Google DeepMind описала 4 пути от AGI к ASI: искусственный интеллект ждут барьеры на каждом
Исследователи Google DeepMind 10 июня 2026 года опубликовали отчёт, в котором разобрали четыре конкретных пути перехода от AGI (искусственного общего…
Комментарии