惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
F
Fortinet All Blogs
B
Blog
GbyAI
GbyAI
P
Proofpoint News Feed
量子位
The Register - Security
The Register - Security
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
B
Blog RSS Feed
WordPress大学
WordPress大学
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Secure Thoughts
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Webroot Blog
Webroot Blog
AWS News Blog
AWS News Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The GitHub Blog
The GitHub Blog
爱范儿
爱范儿
O
OpenAI News
月光博客
月光博客
H
Hacker News: Front Page
S
Security Affairs
W
WeLiveSecurity
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
Docker
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Blog — PlanetScale
Blog — PlanetScale
J
Java Code Geeks
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
A
About on SuperTechFans

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Красота математики и ML (part 1/2): алгоритм MinHash
Андрей Шевченко · 2026-06-20 · via Все публикации подряд на Хабре

Простой

5 мин

3

Вернулся к одному из своих исследований в области векторизации текста. Возможно, расскажу о нём позже, а пока, в поисках ответа на вопрос насколько моё исследование повторяет уже существующие разработки, изучил два интересных алгоритма.

SimHash: про то, как векторизовать текст в плотный вектор из нулей и единиц.

MinHash: про то, как транслировать разряжённый (sparse) бинарный вектор в компактный отпечаток, состоящий из целых чисел.

Кроме того, что оба алгоритма работают с бинарными векторами, у них есть еще одна общая черта.

Они оба гениальны в своей простоте и потому потрясающе красивы!

Это именно то, что меня вдохновляет в ML, и потому не могу сдержаться, чтобы не рассказать о них, хоть инфы в инете и так полно. Данная статья, написанная почти полностью пальцами, задумана как первая из двух, и я расскажу в ней про MinHash.

Итак, на какой же вопрос является ответом MinHash?

Алгоритм позволяет транслировать разряжённые (sparse) бинарные векторы большой размерности в целочисленные векторы многократно меньшей размерности с сохранением информации, позволяющей оценить похожесть исходных векторов.

При этом, данный набор чисел, называемый сигнатурой (signature):

  • Хоть и, строго говоря, по-прежнему будет являться вектором в математическом пространстве, но не будет нести правильной геометрической информации;

  • Сохранит информацию, позволяющую приблизительно высчитать коэффициент и расстояние Жаккара для исходных векторов;

  • Может быть произвольной размерности, но чем длиннее, тем лучше.

Вводные. С чем будем работать?

Допустим, есть у нас пара миллиардов разряжённых векторов, а размерность у них, при этом, тоже какая-нибудь субрелятивистская, скажем, 40 тысяч. Или 140 тысяч, и такое бывает. В наших примерах далее всё будет много компактнее, но именно на таких масштабах преимущества и смысл MinHash проявляются наиболее полно.

Мы рассмотрим 4 вектора размерности 20. В каждом из них от 5 до 7 единиц, остальные разряды выставлены в ноль. Два вектора (V1 и V2) будут похожи друг на друга, они различаются лишь в 18 и 19 разрядах. и еще два вектора — уникальны.

Вектор

Бинарное представление

Позиции единиц

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

V2

0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0

2, 5, 8, 12, 15, 19

V3

1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0

1, 4, 7, 10, 13, 16

V4

0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1

3, 6, 9, 11, 14, 17, 20

Отсчёт индексов в данной статье решил вести с единицы.

Real action!

Алгоритм действительно гениально прост, и состоит из 3 шагов.

  1. Генерация вспомогательных последовательностей

  2. Применение каждой вспомогательной последовательности к каждому вектору

  3. Запись получившегося значения в результирующую сигнатуру

Поехали.

1. Генерация вспомогательных последовательностей

Так их называю только я, и это самый точный термин. Официально они называются перестановками, и далее вы поймёте почему.

Прелесть алгоритма (кроме прочих) состоит в том, что размерность сигнатур мы можем делать буквально какую захотим. Однако, как уже было сказано, чем длиннее будет сигнатура, тем точнее мы потом сможем оценить схожесть векторов на её основе.

Мы с вами сейчас будем высчитывать сигнатуры размерностью 3. Значит, нам сначала нужно сгенерировать 3 вспомогательные последовательности. Это будут наши "ключи кодирования", еще один довольно точный синоним.

Каждая последовательность — это просто числа от 1 до 20, случайным образом перемешанные. Потому и называют их "перестановками". Обратите внимание, что размерность 20 здесь именно потому, что такова размерность наших исходных векторов!

Выпишем их полностью:

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

В реальном коде вместо готовых последовательностей применяют хэш-функции, но это исключительно для оптимизации, чтобы быть более CPU-bound, и не хранить все перестановки в памяти. Суть та же: каждая хэш-функция, являясь, по сути, ключом кодирования, детерминированно отображает каждый индекс в некоторое число, обращаемся к ней, вместо того, чтобы хранить в памяти набор чисел (и потом всё равно дёргать функцию для работы с этим набором).

Мы для наглядности продолжим именно с готовыми вспомогательными последовательностями.

2. Применяем каждую вспомогательную последовательность к каждому вектору

Вспомним наш первый вектор, V1: 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0

А вот наша первая последовательность P1: 14 3 19 7 2 11 20 5 16 8 1 12 18 4 9 15 6 13 10 17

Используем исходный вектор как битовую маску, накладываем её на вспомогательную последовательность, получая в итоге наборы целочисленных значений.

Распишу это по шагам.

Единицы в векторе V1 стоят в позициях: 2, 5, 8, 12, 15, 18.

Теперь выписываем значения из P1 строго для этих позиций:

Позиция 2 -> значение *3**

Позиция 5 -> значение *2**

Позиция 8 -> значение *5**

Позиция 12 -> значение *12**

Позиция 15 -> значение *9**

Позиция 18 -> значение *13**

Соответственно, вот наш искомый набор для V1: 3, 2, 5, 12, 9, 13.

3. Забираем минимальное значение в результирующую сигнатуру

Берём min() от перечисленных значений.

Из набора [3, 2, 5, 12, 9, 13] минимум — это 2.

Повторяем шаги 2 и 3 для каждого исходного вектора и для каждой вспомогательной последовательности

А именно, берём вторую перестановку, применяем к тому же, первому векторую, минимальное значение из получившихся интов будет равно 1, потому, что в пятой позиции нашей перестановки стоит значение 1.

И так далее. Чтобы не утомлять вас арифметикой, я просто сведу все расчеты в итоговую таблицу. Представим, что мы честно прогнали все 4 вектора через все 3 перестановки:

Вектор

Сигнатура

V1

[2, 1, 4]

V2

[2, 1, 6]

V3

[7, 3, 2]

V4

[1, 8, 1]

Напомню, что в продакшене это всё будут обращения к семейству хэш-функций.

Действительно ли всё работает?..

Давайте теперь убедимся, что идея действительно сработала, а потом поймём что мы можем делать с получившимися сигнатурами, и чего не можем.

Высчитаем коэффициент Жаккара для пар исходных векторов:

V1 и V2: 0.714

V1 и V3: 0

V1 и V4: 0

Возвращаемся к сигнатурам

  • V1 vs V2: сигнатуры [2, 1, 4] и [2, 1, 6] совпали на 2 из 3 позиций → оценка сходства = 2/3 ≈ 0.667

  • V1 vs V3: сигнатуры [2, 1, 4] и [7, 3, 2] совпали на 0 из 30

  • V1 vs V4: сигнатуры [2, 1, 4] и [1, 8, 1] совпали на 0 из 30

Всё сходится. Однако, еще раз напомню, что я просто подобрал пример, на котором хорошо сработали столь короткие сигнатуры. В реальной жизни они должны быть сильно длиннее.

...Но что именно работает?

Сигнатуры сравнивают не как геометрические векторы, а по числу совпавших компонент. Именно эта идея лежит в основе семейства алгоритмов LSH.

Вот тут начинаются тонкости, которые заставляют перечитывать Мерфи и Кострикина по несколько раз. На самом деле, любая последовательность целых чисел принадлежит Zn , и, следовательно, является математическим вектором.

Вот только наши вектора созданы очень кастомным способом, и своим расположением в n-мерном пространстве не несут никакой информации, а значит, привычные методы, такие как вычисление евклидова или косинусного расстояния, не могут быть использованы.

Что делать? А так и сравнивать их, численно.

Сигнатуры сравнивают не как геометрические векторы, а по числу совпавших компонент. Именно эта идея лежит в основе семейства алгоритмов LSH. Возможно, расскажу и про них однажды.

Кто это придумал и зачем?

ML -- это потрясающе интересно. И математика тоже. Жаль, что в 39 лет мне уже трудновато всё это разгрызать. А вот моему тёзке Андрею Бродеру, работавшему в 1997 году в AltaVista, было, видимо, вполне даже норм.

Олдфаги помнят, что АльтаВиста -- это когда-то был такой поисковик. Даже я его не застал, а лишь слышал про него. А поскольку поискови, то и Андрей решал задачу, требующую оценки схожести веб-страниц и поиска клонов.

Он вывел лемму:

Если π — случайная перестановка множества, то вероятность того, что минимальный элемент перестановки для двух множеств A и B совпадёт, в точности равна коэффициенту Жаккара этих множеств.

Впоследствии, в соавторстве с другими математиками это было оформлено в полноценную математическую работу.

Таким образом, бинарные вектора, которые в данной статье рассматривались как исходные, в задаче, которую решал Андрей, являлись one-hot представлением веб-страниц.

----

Здесь не будет рекламы телеграм канала, который у меня, конечно же, есть. Просто расскажу о себе, наконец.

Меня, как вы уже догадались, тоже зовут Андрей, я сотрудник Сбера, и сейчас работаю в рабочей группе, никак не связанной с ИИ. Работал и в таких, которые были связаны.

Всегда рад пообщаться про ML, готов к аргументированной критике данной небольшой статьи. Пожалуйста, указывайте на возможные ошибки и неточности. Приветствуется распространение на прочих ресурсах.