Использую аналогичный подход, когда графы в постгресе. Только с 2-мя отличающимися нюансами, которые, возможно, вам будут полезны:
WHERE g.node1 = sg.node2
AND not (g.node1 = ANY(sg.path)) -- тоже самое, но останавливаемся на первом вхождении
AND ((sg.depth = 1)
or (sg.depth > 2 and sg.node1 > g.node1)
) -- исключаем логические повторы
-- актуально если 30 2 3 1003 и 30 3 2 1003 - одно и тоже
-- оставляем только одну последовательность (30 2 3 1003)
public> select count(*) from (select clientid from tbl_fact
where dt between '2021-01-01' and '2021-12-01' group by clientid) q
[2022-01-20 14:57:33] 1 row retrieved starting from 1 in 3 s 322 ms (execution: 3 s 302 ms, fetching: 20 ms)
create index tbl_fact_idx2 on tbl_fact(clientid, dt);
explain analyze
select count(*) from (select clientid from tbl_fact
where dt between '2021-01-01' and '2021-12-01' group by clientid) q;
Aggregate (cost=641207.12..641207.13 rows=1 width=8) (actual time=5522.464..5522.466 rows=1 loops=1)
-> Group (cost=0.44..594183.54 rows=3761887 width=4) (actual time=55.265..5263.736 rows=4817602 loops=1)
Group Key: tbl_fact.clientid
-> Index Only Scan using tbl_fact_idx2 on tbl_fact (cost=0.44..552706.71 rows=16590731 width=4) (actual time=0.095..3838.740 rows=16545711 loops=1)
Index Cond: ((dt >= '2021-01-01'::date) AND (dt <= '2021-12-01'::date))
Heap Fetches: 0
Тогда бы и первый стал бы работать быстрее при повторных запусках, а этого не происходит. Ну плюс план разный, первый seq скан, второй index scan only. + сортировка перед каунтом.
Второй не сортирует. По поводу даты, разумеется, или индекс по дате или составной с датой должен быть. При этом разница между этими индексами тоже будет сильной.
Хотел показать, что есть более простые варианты считать уников. В данном случае, вариант, в котором нет необходимости в сортировке значений. Для вашего распределения числа уникальных записей должно быть быстрее.
Мне кажется, вы слишком усложняете себе задачу, а потом ее зачем-то решаете...
...
CREATE INDEX tbl_fact_idx ON tbl_fact (clientid);
vacuum analyze tbl_fact;
-- 10 s 72 ms
public> select count(distinct clientid) from tbl_fact
[2022-01-20 00:32:34] 1 row retrieved starting from 1 in 10 s 72 ms (execution: 10 s 31 ms, fetching: 41 ms)
--3 s 712 ms
public> select count(*) from (select clientid from tbl_fact group by clientid) q
[2022-01-20 00:33:45] 1 row retrieved starting from 1 in 3 s 712 ms (execution: 3 s 672 ms, fetching: 40 ms)
1. Публично такие данные никто не поставляет, насколько мне известно, но могу поделиться своими, если в личке объясните зачем
2. Не совсем понял вопрос. Как связан объем данных, который не помещается в память, и детектор переобучения?
3. Не вариант, так как у меня всего одна нода с 16 гб памяти. Он возможно помог бы если был бы кластер. К тому же, catboost не умеет пока обучаться распределенно — все равно собирать все на одной ноде.
Обучение на истории без последнего месяца, метрики считаю только на последнем месяце. По поводу того, как оно будет себя вести на новых данных — логгирую все предикты, потом посмотрим, пока рано (этот функционал только вчера выкатил в прод).
Мне кажется это единственный вариант. К тому же современный ml предлагает варианты, которые могут лучше чем «в среднем по больнице».
Вы видите какой-либо другой?
На secretflying (fly4free.com, vandrouki.ru и других, их много) — там вручную. Это как правило очень-очень горячие билеты (часто запрашивают их у агрегаторов) — и в кэше агрегаторов они будут почти с 100% вероятностью, а следовательно, они есть и здесь. Чтобы их уже сейчас мониторить вполне подойдет страница Simple flights с параметром Сортировка=Цена за км. (также скоро появится сортировка по «Отклонению от средней цены», чтобы можно было убрать дешевые, которые всегда дешевые)
>> (читай «только на популярные направления») — это самая большая ложка дегтя.
Все так. С оговоркой, что на непопулярные направления билеты все же чаще есть, но не на все даты (иногда незначительно малое кол-во дат).
Эта проблема пока не решена. Сейчас у меня есть две идеи, как это можно сделать:
Добавить кэш от еще нескольких агрегаторов (сейчас только один). Этот вариант понятно как реализовывать, но он все равно не решит проблему до конца, всегда будут оставаться «белые пятна»;
Предсказывать цены на билеты, если они сейчас отсутствуют в кэше для их использования в комбинаторе (для того, чтобы забить всю сетку origin/destination/date). Здесь у меня больше вопросов, чем ответов, но интуитивно кажется, что это единственный вариант.
Комментарии к заметкам:
— Там есть селектор «Корректировка фильтра по максимальной цене», поменяв значение можно добиться того, чтобы фильтр по максимальной цене оставался на заданном уровне.
— все так, как ни парадоксально
— Лимит только на схему — 50. Максимум значений может быть 200 (4 схемы для RT x 50), но намек понял :)
Да, такое может быть, к сожалению. Сейчас сетка (origin/destination/date) для США достаточно скудная — из-за отсутствия пользователей, которые запрашивают цены по этим направления.
Это сайт про цены из кэша (skyscanner/jetradar). Почему приходится ограничиваться только им описано в этой ветке.
Если вам нужен только билет, где все переменные заранее определены (отправление/назначение/даты и к тому же без пересадок) — лучше сразу переходить на jetradar/skyscanner/kayak/expedia.
Здесь я не ставлю перед собой задачу сделать копию таких гигантов, как
jetradar/skyscanner/kayak/expedia. А только сделать тот функционал, которого там нет.
Если вы находитесь в Dusseldorf и видите NRN(Weeze) в списке — это из-за того, что при первом входе определяются 5 ближайших аэропортов в радиусе 300км, которые становятся значениями по умолчанию. Их можно ввести вручную, введенные значения сохранятся в куках для следующих визитов.
Расходимся. Это снова только обещания, нигде такую ипотеку сегодня не оформить, даже если кто-то сильно захочет.
Получается, что в Яндексе средний оклад - 310 тыс. рублей. Это сильно не сходится со статистикой хабра:
и закроет их окончательно...
Приведите, пожалуйста, несколько примеров
Использую аналогичный подход, когда графы в постгресе. Только с 2-мя отличающимися нюансами, которые, возможно, вам будут полезны:
Нет, выполнение те же 3 секунды
Не ломает
Тогда бы и первый стал бы работать быстрее при повторных запусках, а этого не происходит. Ну плюс план разный, первый seq скан, второй index scan only. + сортировка перед каунтом.
Второй не сортирует. По поводу даты, разумеется, или индекс по дате или составной с датой должен быть. При этом разница между этими индексами тоже будет сильной.
Хотел показать, что есть более простые варианты считать уников. В данном случае, вариант, в котором нет необходимости в сортировке значений. Для вашего распределения числа уникальных записей должно быть быстрее.
Мне кажется, вы слишком усложняете себе задачу, а потом ее зачем-то решаете...
2. Не совсем понял вопрос. Как связан объем данных, который не помещается в память, и детектор переобучения?
3. Не вариант, так как у меня всего одна нода с 16 гб памяти. Он возможно помог бы если был бы кластер. К тому же, catboost не умеет пока обучаться распределенно — все равно собирать все на одной ноде.
Вы видите какой-либо другой?
На secretflying (fly4free.com, vandrouki.ru и других, их много) — там вручную. Это как правило очень-очень горячие билеты (часто запрашивают их у агрегаторов) — и в кэше агрегаторов они будут почти с 100% вероятностью, а следовательно, они есть и здесь. Чтобы их уже сейчас мониторить вполне подойдет страница Simple flights с параметром Сортировка=Цена за км. (также скоро появится сортировка по «Отклонению от средней цены», чтобы можно было убрать дешевые, которые всегда дешевые)
Все так. С оговоркой, что на непопулярные направления билеты все же чаще есть, но не на все даты (иногда незначительно малое кол-во дат).
Эта проблема пока не решена. Сейчас у меня есть две идеи, как это можно сделать:
Комментарии к заметкам:
— Там есть селектор «Корректировка фильтра по максимальной цене», поменяв значение можно добиться того, чтобы фильтр по максимальной цене оставался на заданном уровне.
— все так, как ни парадоксально
— Лимит только на схему — 50. Максимум значений может быть 200 (4 схемы для RT x 50), но намек понял :)
Это сайт про цены из кэша (skyscanner/jetradar). Почему приходится ограничиваться только им описано в этой ветке.
Если вам нужен только билет, где все переменные заранее определены (отправление/назначение/даты и к тому же без пересадок) — лучше сразу переходить на jetradar/skyscanner/kayak/expedia.
Здесь я не ставлю перед собой задачу сделать копию таких гигантов, как
jetradar/skyscanner/kayak/expedia. А только сделать тот функционал, которого там нет.
Если вы находитесь в Dusseldorf и видите NRN(Weeze) в списке — это из-за того, что при первом входе определяются 5 ближайших аэропортов в радиусе 300км, которые становятся значениями по умолчанию. Их можно ввести вручную, введенные значения сохранятся в куках для следующих визитов.