avva: (Default)
[personal profile] avva
(эта запись может быть интересна программистам)

Иногда возникает ситуация, когда нужно найти самые частые элементы в длинном списке повторяющихся элементов, который желательно к тому же не хранить целиком. Например, представьте себе сервер, который обрабатывает поисковые запросы, и вы хотите знать, с начала работы сервера и до сих пор какие 10 запросов всречались чаще всего и сколько раз. Или: какие пользователи обращались к серверу чаще всего и сколько раз (top N users). Или: какого рода запросы/какие пользователи использовали больше всего памяти сервера (top N users by RAM).

Можно сохранять весь поток идентификаторов по мере их прихода, сортировать его (или держать сортированным) и брать самые частые. Но это может требовать очень много места. Можно делать сэмплинг, брать каждый элемент из потока с вероятностью 1/n. Но нужно брать вероятность так, чтобы гарантировать попадание в сэмпл самых частых элементов, и тогда все равно может оказаться много места.

Вот эта статья: Moses Charikar, Kevin Chen, Martin Farach-Colton, Finding frequent items in data streams

описывает несложный алгоритм, который может пригодиться в хозяйстве. Мне, например, очень пригодился. Алгоритм использует двумерный массив хэш-значений, который позволяет оценивать примерно частоту каждого элемента и составить с помощью этих оценок список N самых частых элементов в один проход; величину ошибки можно ограничить дешево небольшим окном вокруг N-го элемента. Скажем, если вы хотите 10 самых частых запросов и ошибку в 10%, и "честный" 10-й по частоте запрос встречался 1000 раз, то все, кто встречался больше 1100 раз, "честно" попадут на свои места в топ-10, а из окна 900-1100 могут в топ-10 попасть не "честные", а какие-то другие элементы.

Самое главное - что памяти он использует пропорционально логарифмам всех важных величин - числа элементов, числа потенциальных разных элементов. Выходит очень экономно, так что дешево выходит даже память по байтам отслеживать (т.е. например, если юзер foo послал запрос который истратил 1M памяти, считать это концептуально 1,048,576 повторениями строки "foo", и в таком потоке находить чемпионов).

Update: ссылка из комментариев - обзор нескольких алгоритмов такого рода.

Date: 2014-11-02 03:55 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Moses Charikara, Kevin Chenb, Martin Farach-Coltonc

Последние буквы от фамилий авторов надо бы откусить. :)

Date: 2014-11-02 03:56 pm (UTC)
From: [identity profile] avva.livejournal.com
Ой :) сейчас, спасибо.

Date: 2014-11-02 04:30 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Алгоритм прекрасен, надо будет запомнить. С двумерностью особенно красиво.

Date: 2014-11-02 08:30 pm (UTC)
From: [identity profile] sergey schetinin (from livejournal.com)
Такого рода алгоритмы обычно называют "probabilistic data structures (https://www.google.com.ua/search?q=probabilistic+data+structures)". Вот неплохой их обзор (https://highlyscalable.wordpress.com/2012/05/01/probabilistic-structures-web-analytics-data-mining/).

Date: 2014-11-02 09:29 pm (UTC)
From: [identity profile] avva.livejournal.com
Спасибо, Сергей!

Date: 2014-11-03 05:38 pm (UTC)
From: [identity profile] avnik.livejournal.com
Пожалуй даже поинтереснее ссылки в оригинальном посте.
Меньше матана, и есть примеры кода для тупых.

Date: 2014-11-03 06:49 pm (UTC)
From: [identity profile] iskra11.livejournal.com
Спасибо за ссылки. А можно поинтересоваться, для каких задач они использовались? Я сейчас на курсере слушаю курс mining massive data sets, и мне интересны области применения.

Date: 2014-12-17 10:17 pm (UTC)
From: [identity profile] http://users.livejournal.com/_winnie/
Я правильно понял, что если заранее набор значений элементов {oi} не известен, то это все-таки two pass алгоритм?
Edited Date: 2014-12-17 10:18 pm (UTC)

Date: 2014-12-18 12:34 am (UTC)
From: [identity profile] avva.livejournal.com
нет.

Date: 2014-12-18 01:26 am (UTC)
From: [identity profile] http://users.livejournal.com/_winnie/
Да, действительно. Я слишком быстро прочитал, а там уж очень уж подробное объяснение, что такое COUNT SKETCH.

January 2026

S M T W T F S
    1 2 3
4 5 6 7 8 910
11 12 1314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 15th, 2026 03:55 pm
Powered by Dreamwidth Studios