Проблема проста: мне нужно найти оптимальную стратегию для реализации точных объединений HyperLogLog на основе их представления Redis — это включает в себя обработку их разреженных/плотных представлений, если структура данных экспортируется для использования в другом месте.
Две стратегии
Есть две стратегии, одна из которых кажется намного проще. Я просмотрел фактический исходный код Redis, и у меня возникли небольшие проблемы (не большие в C, я сам), выясняя, лучше ли с точки зрения точности и эффективности использовать их встроенные структуры/процедуры или разрабатывать свои собственные . Ради большей эффективности я готов пожертвовать пространством и до некоторой степени ошибками (stdev +-2%) в погоне за эффективностью с чрезвычайно большими наборами.
1. Принцип включения
Безусловно, самый простой из двух — по сути, я бы просто использовал объединение без потерь (PFMERGE) в сочетании с этим принципом для расчета оценки перекрытия. Тесты, кажется, показывают, что во многих случаях это работает надежно, хотя у меня возникают проблемы с точным определением эффективности и точности в дикой природе (в некоторых случаях могут возникать ошибки 20-40%, что неприемлемо в этом случае использования).
В принципе:
aCardinality + bCardinality - intersectionCardinality
или, в случае нескольких наборов...
aCardinality + (bCardinality x cCardinality) - intersectionCardinality
кажется, работает во многих случаях с хорошей точностью, но я не знаю, доверяю ли я этому. Хотя в Redis есть много встроенных модификаторов с низкой кардинальностью, предназначенных для обхода известных проблем HLL, я не знаю, сохраняется ли проблема дикой неточности (с использованием включения/исключения) с наборами с большим несоответствием в размере...
2. Пересечение индекса Жаккара/MinHash
Этот способ кажется более интересным, но часть меня чувствует, что он может вычислительно перекрывать некоторые из существующих оптимизаций Redis (т. е. я не реализую свой собственный алгоритм HLL с нуля).
При таком подходе я бы использовал случайную выборку бинов с алгоритмом MinHash (я не думаю, что реализация LSH стоит заморочек). Это была бы отдельная структура, но, используя minhash для получения индекса Жаккара наборов, вы можете затем эффективно умножить мощность объединения на этот индекс для более точного подсчета.
Проблема в том, что я не очень хорошо разбираюсь в HLL, и хотя я хотел бы покопаться в документе Google, мне нужна жизнеспособная реализация в кратчайшие сроки. Скорее всего, я упускаю из виду некоторые основные соображения либо о существующих оптимизациях Redis, либо о самом алгоритме, который позволяет проводить недорогие в вычислительном отношении оценки пересечения с довольно слабыми доверительными границами.
итак, мой вопрос:
Как мне наиболее эффективно получить оценку пересечения N огромных (миллиардов) наборов, используя Redis, если я готов пожертвовать пространством (и в небольшой степени точностью)?