Най-добрият метод за пресичане на огромни HyperLogLogs в Redis

Проблемът е прост: трябва да намеря оптималната стратегия за внедряване на точни HyperLogLog обединения въз основа на тяхното представяне на Redis - това включва обработка на техните разредени/плътни представяния, ако структурата на данните се експортира за използване другаде.

Две стратегии

Има две стратегии, едната от които изглежда много по-проста. Разгледах действителния източник на Redis и имам малко проблеми (аз самият не съм голям в C) да разбера дали е по-добре от гледна точка на прецизност и ефективност да използвам техните вградени структури/програми или да разработя свои собствени . Колкото и да си струва, готов съм да пожертвам пространство и до известна степен грешки (стандартно отклонение +-2%) в преследване на ефективност с изключително големи комплекти.

1. Принцип на включване

Досега най-простият от двата - по същество бих използвал обединението без загуби (PFMERGE) в комбинация с този принцип, за да изчисля оценка на припокриването. Тестовете изглежда показват, че това работи надеждно в много случаи, въпреки че имам проблеми с получаването на точна оценка на ефективността и точността в природата (някои случаи могат да доведат до грешки от 20-40%, което е неприемливо в този случай на употреба).

По принцип:

aCardinality + bCardinality - intersectionCardinality

или, в случай на множество комплекти...

aCardinality + (bCardinality x cCardinality) - intersectionCardinality

изглежда работи в много случаи с добра точност, но не знам дали му вярвам. Въпреки че Redis има много вградени модификатори с ниска кардиналност, предназначени да заобикалят известни проблеми с HLL, не знам дали проблемът с дивата неточност (използване на включване/изключване) все още присъства при набори с голямо несъответствие в размера...

2. Пресичане на индекса на Jaccard/MinHash

Този начин изглежда по-интересен, но част от мен има чувството, че може изчислително да се припокрива с някои от съществуващите оптимизации на Redis (т.е. не внедрявам собствен HLL алгоритъм от нулата).

С този подход бих използвал произволна извадка от контейнери с алгоритъм MinHash (не мисля, че внедряването на LSH си струва труда). Това би било отделна структура, но като използвате minhash, за да получите индекса на Jaccard на наборите, след това можете ефективно да умножите кардиналността на обединението по този индекс за по-точно преброяване.


Проблемът е, че не съм много добре запознат с HLL и макар че бих искал да се разровя в документа на Google, имам нужда от жизнеспособна реализация в кратки срокове. Вероятно пренебрегвам някои основни съображения или на съществуващите оптимизации на Redis, или в самия алгоритъм, който позволява изчислително евтини пресечни оценки с доста слаби граници на доверие.

И така, моят въпрос:

Как най-ефективно да получа изчислително евтина оценка на пресичане на N огромни (милиарди) комплекта, използвайки redis, ако съм готов да жертвам пространство (и в малка степен, точност)?


person Julian    schedule 07.05.2015    source източник
comment
Какви са критериите за „най-добрия метод“, за да знаем какви отговори да предоставим? т.е. как бихте решили кой е „най-добрият отговор“? Трябва да предоставите някои ограничения - какви са ресурсите, с които разполагате, за да разрешите този проблем?   -  person Ryan Vincent    schedule 07.05.2015
comment
Дали „redis“ е най-добрият инструмент за решаване на проблема със „съвпадението“, който имате? 'redis' изисква всичко да се съхранява в 'памет'. Това може да бъде „интересно“ за „милиарди“ записи.   -  person Ryan Vincent    schedule 07.05.2015
comment
Е, „най-доброто“ в този случай е по същество редът, който описах @Ryan, пространството е без значение; точността ще бъде следващата жертва в дадените граници на отклонение, а изчислителната ефективност е моят приоритет №1.   -  person Julian    schedule 08.05.2015
comment
Също така не съм съвсем сигурен, че е така, но го чувствам, тъй като не искам да излизам отвъд решение в паметта предвид нуждите ми за достъп до тези данни и извършване на тези заявки в динамичен стек - ресурсите за поддръжка са по същество неограничени, но имайте предвид, че не е задължително да пресичам точните СТОЙНОСТИ на N набора от милиарди, просто имам точно/евтино кардинално решение, базирано на HLL, където мога да пресичам по желание... тогава отново, когато вие имам чук...   -  person Julian    schedule 08.05.2015
comment
Благодаря за отговора, честно казано, това е „далеч извън моята област на експертиза“, но изглежда забавен проблем, върху който трябва да се работи. :-)   -  person Ryan Vincent    schedule 08.05.2015
comment
Това е страхотно! Опитвам се да разреша нещо много подобно. Можете ли да споделите как внедрихте minhash във връзка с redis HLL? Това може да е много полезно за други, които се опитват да разрешат, което би трябвало да бъде, много често срещан проблем   -  person Sid    schedule 29.08.2015


Отговори (2)


Прочетете тази статия преди време. Вероятно ще отговори на повечето от вашите въпроси. Принципът на включване неизбежно усложнява границите на грешки при голям брой набори. Подходът Min-Hash би бил правилният начин.

http://tech.adroll.com/media/hllminhash.pdf

person frugalcoder    schedule 21.08.2015
comment
Всъщност това вече е направено :). Тази хартия определено помогна, но наистина започна да лети, когато сменях персонализирано разширение murmurhash3. Поддържайте силно @ 4MM заявки/мин. - person Julian; 21.08.2015
comment
Добавете отговор на въпроса си, ако сте намерили правилния начин за него. И го маркирайте като прието. - person frugalcoder; 12.01.2016

Има трета стратегия за оценка на размера на пресичането на всеки два комплекта, дадени като скици на HyperLogLog: оценка на максималната вероятност.

За повече подробности вижте документа, наличен на http://oertl.github.io/hyperloglog-sketch-estimation-paper/.

person otmar    schedule 02.11.2016