Как обычно, мы пытаемся решить сложную математическую задачу минимальными средствами и затратами. Суть задачи – сортировать товары интернет-магазина так, чтобы это было наиболее удобно покупателю.
Самый простой способ – задавать порядок вручную. В физических магазинах на полках делается именно так, и это называется «выкладка». У нас её делают продавцы по планограммам под каждую точку (это входит в обучение), а в тех же больших продуктовых – специальные чуваки-мерчендайзеры, которые следят, чтобы всё было ок. В Интернете, конечно, хочется сделать так же, но метод хорош до 50 позиций.
На другой стороне шкалы методы больших данных, когда все данные о вас начиная от сборки браузера, типа девайса (точнее, его цены) и разрешения экрана, плюс все данные профиля и оценка ваших действий на сайте ведут к оптимальному результату. Самый простой способ использования таких данных – за первые 20-30 секунд нахождения на сайте строить ваш профиль и сравнивать с профилями таких же людей. И предлагать вам в итоге не самые дешёвые квартиры и отели, например, а начинать с тех цен, которые для вас будут приемлемыми. Вы наверняка знаете эту сортировку, которую почему-то подают в прессе под соусом «самой удобной для клиента».
По моим ощущениям, самая удобная для нашего покупателя – это такая, которая понятна и поддаётся контролю.
Если вы посмотрите на то, как отсортированы товары в различных интернет-магазинах, то увидите, что совершенно точно есть упорядочивание по цене, наличию и ещё какой-то вуду-параметр типа «по популярности», «по-озоновски» и так далее. Вот про эту магию мы и поговорим.
С чего мы начинали
Делали вручную. До 50 товаров – это лучший способ. На самом деле, в похожих раскладах можно было и без сортировки — товары помещаются на 2-3 экранах, и даже навигация не всегда нужна. Можно вывалить всё кучей, пользователь будет счастлив. Так мы и делали.
Однако когда покупатель не может запихнуть все товары категории (или вообще каталога) себе в оперативную память, сортировка всё-таки нужна. Когда мы дошли до примерно сотни игр, то понадобился первый функциональный инструмент – лесенка по цене. Вообще, сортировка по цене – очень простая и понятная штука. У вас есть бюджет, и вы хотите в него уложиться. Или вы хотите сравнить несколько похожих товаров. Или вам просто хочется взять «низ» и «верх» категории, чтобы понять, на что опираться при сравнении товаров.
Механически она реализуется очень просто – сравниваются цены. При одинаковых ценах везёт тому товару, который попал в массив сравнения раньше (скорее всего, был раньше добавлен на сайт).
Первая проблема сортировки по цене в том, что бестселлеры будут заныканы довольно глубоко вниз. Вторая – товары не в наличии, которые могут затесаться в середину списка. Третья – часто появляется много мусора наверху, то есть всякие расходники, упаковки и прочее-прочее, что стоит дёшево, но часто не имеет прямого отношения к товарам, за которыми пришёл человек.
Соответственно, как инструмент она нужна, но как дополнительный. Основная сортировка должна быть другой.
Мы попробовали сортировать по продажам и одновременно стали набирать оценки товаров по шкале от 1 до 5, чтобы затем ввести сортировку по рейтингу.
При сортировке по продажам резко начали пробиваться вверх не бестселлеры, а дешёвые товары, которых явно (в штуках) берут больше, чем чего-то ещё. Любой товар с ценой выше средней имеет заниженные шансы оказаться вверху такой сортировки. Соответственно, нужно как-то это балансировать.
Мы думали, что хорошей идеей будет сделать ансамбль моделей, и в качестве второй весовой функции для общей оценочной использовать рейтинг. И не только, но об этом далее.
Оказалось, что нельзя просто брать и выгружать рейтинг, потому что товар с 4,5 «звёздами» на 100 отзывов явно лучше товара на 5 звёзд, но с 1 отзывом. Решение очевидно – изменять весовой коэффициент рейтинга в общей оценочной функции в зависимости от количества отзывов. Рассматривался вариант с тем, что он меняется от 1% до 50% нелинейно, например, 200 отзывов дают 40% к весу, а 10 оценок – 15% к весу. Но наиграться с коэффициентами мы не успели – возникла совершенно тупая проблема сортировки по оценкам.
Дело в том, что оценки тоже ставили по нормальному распределению.
Долбанная гауссиана была сдвинута только на одно деление снизу – всё-таки мы в большинстве помним школьную систему оценок, где, по факту, нет единицы. То есть большая часть товаров приходит на отрезок 2-5 с оптимумом где-то в районе 3,5-4 баллов. Все хиты стали 4,5, все не-хиты — 4.
Ещё через некоторое время вообще все товары стали одинаковыми, и отдельная сортировка «по рейтингу» не давала ровным счётом ничего хорошего.
Ещё одна проблема заключалась в старой дилемме голосования на сайте: надо либо авторизовывать пользователя по почте или чему-то похожему (достаточно трудно генерируемому), либо не делать так и фильтровать накрутки. В том числе медленные и плавные. Я это очень хорошо знаю, потому что ещё во время учёбы в университете благодаря «тестированию безопасности» сайта университета, который поддерживала другая группа (мы были математиками-системными программистами, а они – защитой информации), как-то мимоходом выбралась эмблема университета. На голосовалке. В субботу. В понедельник утром, ещё до прихода админа, ректор стукнул кулаком по столу и сказал – «Хватит тут разводить, вон, за выходные 400 студентов проголосовало, эту эмблему и берём». Проблема была в том, что самый популярный в городе коннект – это диалап, и мы ходили без графики. И за что там было голосование, попросту не видели. Через два года я рассказал чуть больше деталей, чем вам, руководителю IT-службы университета. И после этого бежал три квартала. Именно тогда я ногами осознал важность защиты голосовалок.
Так вот. Товар можно было накрутить, потому что авторизовываться ради оценки – это дичайший геморрой. Собирать же оценки только с залогиненных пользователей (то есть после заказа, но до его получения в большинстве случаев) казалось не очень трезвой идеей.
Мы отключили сбор рейтингов и сортировку по нему и стали дальше думать.
Второй заход
Сравнив популярность товаров при продаже в физическом мире и через сайт, получили следующий вывод – важен не только и не столько рейтинг товара, сколько количество оценок к нему. То есть товар с сотней оценок явно лучше товара с десятком оценок при том, что оба не выбиваются достаточно сильно из центральной области нормального распределения.
Можно было провесить весовой коэффициент и на эту часть, но всё решилось куда проще. Как раз в момент, пока я думал над этой проблемой (отключив сортировку по рейтингу, потому что она уже мало что давала), Facebook напихал в интернет своих кнопок «Мне нравится».
Три кнопки – гугловская, вконтактовская и фейсбучечная — решили вопрос. У нас появилась сортировка «по рейтингу», причём рейтинг определялся суммой показателей лайков. Причём каждый голос в этой системе учитывался точно – спасибо соцсетям и их авторизации, нам не пришлось думать над этой проблемой.
Мы опять попробовали скрестить сортировку по рейтингу с сортировкой по продажам, но тут во весь рост встала проблема наличия товара.
Наличие
Это были лихие годы, и мы продавали как могли. Наличие в реальном времени на сайте казалось нам достаточно космической технологией, но оно понадобилось. Росло количество магазинов, росло количество ошибок по тому, что человек пришёл, а игры нет, увеличивалось количество негативных отзывов типа «сравнивал полчаса три товара, а двух нет» и так далее.
Довольно быстро, но большой кровью мы синхронизировали базу каждого магазина в реальном времени (ну, почти, минус кэш) с сайтом.
Напомню, работали мы тогда не очень давно, поэтому внезапно поняли ещё одну вещь: сортировка по продажам должна ограничиваться неким интервалом. Потому что иначе у новых игр не будет шансов пробиться вверх — ведь старые в топе, и их исторически продано больше.
Ограничили месяцем.
Далее, приняли волевое решение не учитывать в сортировке товары, которых сейчас нет. Они просто складываются в кучу внизу сортировки под списком в порядке «былых заслуг», то есть исторической позиции в этом же списке. Это было сделано для того, чтобы человек не сравнивал товары, один из которых нельзя купить прямо сейчас.
Возникла проблема. Точек тогда только в Москве было уже девять, и не факт, что товар заканчивался везде одновременно. Плюс интернет-магазин. Как показывать на сайте товар, которого в интернет-магазине нет, но зато на точках он есть?
Правильным казался метод, предложенной одной из розничных сетей бытовой техники – пользователь при заходе на сайт выбирает или магазин (ближайший к дому) или же решает покупать с доставкой. До вообще сёрфинга. И все товары «пританцовывают» по параметрам этого магазина. Нет там – отсортировали вниз и показали, что есть только на складе интернет-магазина.
Наблюдение за профилем поведения наших покупателей показало, что идея так себе. Конкретно у нас. Почему? Всё просто – магазины на кольцевой линии метро и узлах, и обычно в 1-2 минутах от метро (или даже в здании метро, как на Курской, если повезёт). Это означало, что у покупателя нет «любимого» магазина. Он заезжает в тот, который ему удобнее по дороге между домом, офисом, баром и любовницей.
Однако сортировка по продажам за последний месяц на 80% решила проблему наличия только в отдельных магазинах – когда игра продаётся не по всей сети, ей позиция начинает резко падать.
Текущая модель
Следующая гипотеза звучала так: а что, если решить проблемы продажи кучи мелких штук, приравняв одну «крупную» игру к паре «средних» или куче «мелких»? Тогда вся мелочь не будет лезть вверх сортировки.
Решение нашлось очень простое – вместо сортировки по количеству проданных штук за месяц мы стали сортировать по обороту за месяц.
Потом ещё поиграли сроками и сократили период, чтобы прямо на сортировке отражались текущие тренды.
Сортировка такого типа стала основой и для запуска продвижения в реальном мире. То есть товары, которые лучше оборачиваются, идут в рекламу. Это уже пришло из физического принципа выкладки – самый оборачиваемый товар на высоту груди, чтобы поближе к рукам и глазам.
Чем короче срок – тем актуальнее показывается игра в позиции «топа». Больше интервал – большее влияние прошлых продаж. Соответственно, мы подняли градус конкуренции между товарами. Раньше «старички» сидели в топе, откуда их было не выдавить. Теперь каждая новая хорошо продающаяся игра получала солидный шанс. Стоило закрепиться в топе – и вот она хорошо продаётся уже не только сама по себе, но и благодаря топу. Но, конечно, закрепиться можно было только благодаря текущим заслугам – то есть если интерес к позиции угасал, она уходила обратно в «подвал». Это отлично балансировало сезонные товары – Городки и Петанк бодро вылезали вверх летом.
Вторым методом сортировки остаётся совокупность лайков.
Проблемы текущей модели
Во-первых, мы не учитываем в нашей базовой сортировке лайки и количество комментариев к игре – это, конечно, определяет её популярность, но вынесено в отдельный инструмент. Почему? Просто потому, что мы дошли до тех оборотов, где «голосование кошельком» даёт более реалистичные данные. В теории, конечно, можно включить скорость и ускорение набора лайков как весовые коэффициенты, но это дело будущего.
Во-вторых, мы не учитываем «температуру» игры. То есть новинки проходят на общих основаниях. У нас нет одновременных запусков из-за географии (самая далёкая точка – Южно-Сахалинск, туда летает самолётом; самые же долгие точки на материке – поставка 3-4 недели). Поэтому игра не может получить начальное ускорение везде и сразу – и эффект «яркой новинки» размазывается по городам. Наверное, правильно будет в течение первых 3-4 недель ранжировать новику выше за счёт новизны.
В-третьих, у нас довольно много игр, в которых могут играть как дети, так и взрослые. И ещё почти каждая – хороший подарок. Это автоматом означает, что в 2-3 категориях точно будут похожие списки бестселлеров, то есть «верх» сортировки будет одинаков. При этом было бы логично брать сортировку по каждой категории, но это пока сделать сложно – надо знать, для кого покупается каждая позиция (это уже крутой Data Mining, и мы его медленно делаем, расскажу при случае).
В-четвёртых, да, можно использовать сервисы оптимальных товарных предложений, выдающих сортировку от действий пользователя на сайте. Возможно, вы такие знаете. Общий принцип – анализ данных входа (браузер, экран, география и т.п.), поведения на сайте (зашёл в «детские», посмотрел вот эти два товара) и профилирование, а затем наложение – что покупали люди с таким же профилем, как у вас, надо показать вам. Проблема в том, что, во-первых, при такой сортировке теряется контроль, а, во-вторых, мы всё же протестили. И не получили существенных различий «танца реальности» со своими базовыми методами. Отмечу, что одна из возможных причин – яростное желание сервиса таких рекомендаций продавать больше всеми силами через «не хочу», что сказывалось на «агрессивности» предложений и алгоритмов. Отключили.
В итоге стало понятно, что правильная идея – «фичерить» игры, то есть к обычной сортировке добавлять «выбор редактора». Мы пробовали делать это в рамках тестирования на половые праздники (14 и 23 февраля, 8 марта) в этом году. Скоро попробуем ещё раз, но иначе. Скорее всего – сработает.
Вот так это будет в новом интерфейсе
То есть, опять же, мы сейчас описали полный круг от полностью ручной сортировки до умной автоматизации, а потом обратно к ручной.
И да, задача решена не полностью, есть куда докручивать. В целом же, в ретроспективе, всё описанное выше кажется логичным и простым, но, поверьте, когда мы только-только начинали, это было совсем не так. Надеюсь, вам были интересны наши историчесике грабли.
Комментарии (23)
psylosss
04.11.2015 13:43Ошибка сортировки
Не сортировки, а фильтрации. Сортировка — расстановка в правильном порядке, фильтрация — убирание лишнего. Справа на скриншоте здравая мысль — фильтрация снижает необходимость в сортировке. Например фильтр «Показывать только товары в наличии» снимает проблему отображения отсутствующих товаров. Есть ли возможность построить поиск игры таким образом, чтобы пользователь применил 1-2-3 фильтра и у него бы осталось не больше 10 игр, которые подходят именно ему? А 10 игр можно и по цене отсортировать без возможности изменить сортировку.Milfgard
04.11.2015 14:00-1Нет, именно сортировки. В фильтрации эта игра на месте, поскольусоответствует формальному признаку категории, но она должна быть с низким приоритетом.
psylosss
04.11.2015 14:11Если же подразумевается, что компания — «сугубо взрослая», то это все-таки ошибка фильтрации — должно быть дополнительное условие выборки «Игры, которые для компании И которые не детские». Если же компания скорее всего взрослая, но точно хз, то да, это ошибка сортировки. ORDER BY ........., game.isForAdults DESC.
Не совсем по теме, но близко: может быть, дополнительные иконки помогут быстрее ориентироваться? У вас есть иконки «в наличии», «хит». Что если добавить прямо в списке другие стандартные, типа «6-14 лет», «18+», «4+ игроков». Тогда пользователь сможет фильтровать в своей собственной оперативке, не задействуя UI.
Сейчас решаю аналогичную задачу с сортировкой и фильтрацией, но в другой области (сортируем компании).Milfgard
04.11.2015 14:17Вот «Не раскачивай лодку». Берут её либо детям, как задумывалось, либо играть в 35-летних компаниях играть на вечеринках.
psylosss
04.11.2015 14:22Я для решения этой задачи использую простую методику, из которого вытекают все технические следствия (уже совсем не такие простые). Предположим, я не ограничен ни в чём, всё знаю и всё умею. Какие товары и в каком порядке тогда я бы показал данному конкретному пользователю в это конкретное время? Иначе говоря, какая сортировка и фильтрация с точки зрения пользователя была бы идеальна? Исходя из этого становится понятным ответ на вопрос — должна быть «День вождей» в этом списке или нет, и если должна, то в каком месте? И с «лодкой» то же самое. Вопрос не техники, вопрос предметной области.
psylosss
04.11.2015 14:31+1Кстати, как ваш пользователь: не хватает чего-то типа «Похожие игры». Меня интересуют игры, похожие на «имаджинариум» например. Или даже на «Диксит», которая у вас не продаётся (это мне уже позже в вашем магазине подсказали, что диксит и имаджинариум — это как аналогия-которую-я-не помню). Как мне их найти?
Milfgard
04.11.2015 17:51Игры той же серии и тех же авторов — пожалуйста. Похожие — придётся сканить по механике, тоже пожалуйста. Также мы вручную иногда рекомендуем товары в дополнительном блоке.
dom1n1k
04.11.2015 14:03+6Про мусор сверху это точно. Постоянно такое. Сортируешь например список телефонов, а первые пара страниц — это чехлы и пленки на экран.
Dreyk
04.11.2015 14:31потому что опять же фильтрация. на eBay это решается выбором нужной категории
khim
04.11.2015 18:04+2На eBay как раз лучше достаточно популярные товары отсеивать вручную. Потому как все фильтруют по категориям — соответственно если что-то вам интересное продавек засунул не в ту категорию, то он офигивает от того, что все подобные товары давно проданы, а него никто не берёт, а вы можете прикупить что-то с хорошей скидкой.
Но так, конечно, бывает не всегда… если товар достаточно редкий, то его откопают и купят в какую бы категорию его не засунули…
saboteur_kiev
04.11.2015 20:59«Брали, в основном, 0,5. Экспериментаторы сдвинули границы к 0,5, 0,7 и 0,9. Народ стал брать 0,7, хотя до этого нормой потребления было 0,5»
Тут пример не совсем корректный. Просто подорожал тот товар, который был 0.5 и покупатели были вынуждены брать то, что они привыкли по более дорогой цене.
Корректно было бы, если к товара за 0.3, 0.5 и 0.7 добавить еще один новый товар за 0.9 (при этом предыдущие товары не менялись).
Тогда многие из тех, кто обычно брал 0.5, будут брать 0.7, игнорируя новый самый дорогой 0.9. Ну а мажоры будут брать 0.9, чтобы «выделяться», хотя раньше их вполне устраивал 0.7Milfgard
04.11.2015 23:39+1Я очень упростил описание. Методика была более сбалансированной и в большее число итераций.
evnuh
04.11.2015 22:16+1Сортировать товары в магазине нужно по «интересности» их для покупателя. Можно также назвать это «популярностью», только не по продажам, а по просмотрам. А главное — никаких хитрых вычислений вести не надо и придумывать сложные формулы. Мы делаем так:
Пользователь навёл мышою на товар в каталоге и задержал (условно, «изучает») — 1 очко товару
Пользователю зашёл на страницу товара — 5 очков
А чтобы чуть добавить корелляции с продажами, можно ещё две метрики:
Пользователь добавил в корзину — 30 очков
Купил — ещё 30 очков.
Итого, наверху будут именно те товары, которые хочется кликнуть, посмотреть. Что определенно увеличит показатели пользователей на сайте.Aingis
04.11.2015 23:04+1Тогда какой-нибудь условный Верту или Тесла будет в топе: всем интересно, но никто не берёт — слишком дорого.
Milfgard
04.11.2015 23:41+1Прелесть в том, что большая часть наших продаж приходится на розничные магазины. И мы подтягиваем данные из них как опорные. А в них корзины нет.
evnuh
05.11.2015 19:53Ну вот у вас конечно аудитория онлайн/оффлайн сильно пересекается, поэтому да. трудно. Но, вообще, нет ничего плохого в том, чтобы сортировка товаров в ИМ была только по стате с самого ИМ. Раз пользователи на сайте проявляют какой-то интерес к товару, значит именно на сайте он предстапвлен интересно. Возможны даже ситуации, когда смена картинки/описания товара может выбить его в топ по популярности, используя мою формулу. Это именно улучшение поведенческих показателей на сайте, только и всего. И нужно ещё доказать что это влияет на продажи, так же, как и доказать то, что не влияет)
Fedcomp
04.11.2015 23:44+1а у вас есть например данные от визора яндекса? (просто интересно) как мне кажется пользователи далеко не всегда наводят мышкой на то что им нравится.
vlivyur
06.11.2015 10:13Было же исследование какое-то, что пользователи часто наводят мышь на интересующий их об'ект, без клика (мышь-то всё равно в руках, а руки ничем не заняты). Ну и подпирают ею те места, где читают.
Minras
10.11.2015 13:15+2всё-таки мы в большинстве помним школьную систему оценок, где, по факту, нет единицы
Я с этой ментальностью как-то на работе в Голландии попал на свой первый митинг с менеджером по оценке успешности моей работы. Надо было мне свои показатели оценить по шкале 1-5, и он независимо от моих оценок тоже меня оценивал. Потом сравнивали.
В общем, я по опыту советской школы наставил себе везде 4-5, а менеджер принес листик с оценками 3-4, даже одна-две двойки были.
В общем, я первым делом попросил обсудить значение оценок. Оказалось, что 3 — это просто нормальная работа. 4 — хорошая, с конкретно описываемыми успехами. 5 обычно не бывает и означает, что человек достиг потолка и ему надо подумывать о повышении или смене деятельности. 2 — есть над чем работать, но за пару двоек никто увольнять не будет. Единица — тоже нормальная существующая оценка.
В общем, восприятие оценок гораздо ближе к математике, чем к долбаному советскому перфекционизму, где единицу иметь настолько зазорно, что их не бывает по факту.
ToSHiC
Можно сделать предположение, что лайк — это маленькая продажа, 10р, или даже 100 (тут я не знаю цифр, вам виднее отношение лайков к обороту). В вашу текущую сортировку такой подход вливается органически. В качестве приятного дополнения лайки автоматически будут бустить новинки, которые упоминаются где либо. Лайки желательно считать не только из вашего магазина, но и лайки статей про игры.
Milfgard
Спасибо. Формула похожа на весовой кожффициент, просто заход с другой стороны. Лайки, в отличие от продаж, надо считать за большие периоды ещё — год, например.
ToSHiC
Вот, кстати, важный вопрос: как вы убеждаетесь, что сортировка хорошая? Если ваша метрика может быть измерена на коротком интервале времени, то можно несколько моделей построить и запустить сплиты на сайте с контрольными группами.
Milfgard
Можно, но задача больше в сортировке в реале, а там так просто не сделать.