Как обычно, мы пытаемся решить сложную математическую задачу минимальными средствами и затратами. Суть задачи – сортировать товары интернет-магазина так, чтобы это было наиболее удобно покупателю.

Самый простой способ – задавать порядок вручную. В физических магазинах на полках делается именно так, и это называется «выкладка». У нас её делают продавцы по планограммам под каждую точку (это входит в обучение), а в тех же больших продуктовых – специальные чуваки-мерчендайзеры, которые следят, чтобы всё было ок. В Интернете, конечно, хочется сделать так же, но метод хорош до 50 позиций.

На другой стороне шкалы методы больших данных, когда все данные о вас начиная от сборки браузера, типа девайса (точнее, его цены) и разрешения экрана, плюс все данные профиля и оценка ваших действий на сайте ведут к оптимальному результату. Самый простой способ использования таких данных – за первые 20-30 секунд нахождения на сайте строить ваш профиль и сравнивать с профилями таких же людей. И предлагать вам в итоге не самые дешёвые квартиры и отели, например, а начинать с тех цен, которые для вас будут приемлемыми. Вы наверняка знаете эту сортировку, которую почему-то подают в прессе под соусом «самой удобной для клиента».

По моим ощущениям, самая удобная для нашего покупателя – это такая, которая понятна и поддаётся контролю.

Если вы посмотрите на то, как отсортированы товары в различных интернет-магазинах, то увидите, что совершенно точно есть упорядочивание по цене, наличию и ещё какой-то вуду-параметр типа «по популярности», «по-озоновски» и так далее. Вот про эту магию мы и поговорим.

С чего мы начинали


Делали вручную. До 50 товаров – это лучший способ. На самом деле, в похожих раскладах можно было и без сортировки — товары помещаются на 2-3 экранах, и даже навигация не всегда нужна. Можно вывалить всё кучей, пользователь будет счастлив. Так мы и делали.

Однако когда покупатель не может запихнуть все товары категории (или вообще каталога) себе в оперативную память, сортировка всё-таки нужна. Когда мы дошли до примерно сотни игр, то понадобился первый функциональный инструмент – лесенка по цене. Вообще, сортировка по цене – очень простая и понятная штука. У вас есть бюджет, и вы хотите в него уложиться. Или вы хотите сравнить несколько похожих товаров. Или вам просто хочется взять «низ» и «верх» категории, чтобы понять, на что опираться при сравнении товаров.

Эта сортировка позволяет эксплуатировать один баг мышления
Многие специально вводят в категорию дорогой товар, который продвигает границу вилки вверх, и «золотой серединой» становится уже что-то более дорогое, чем до этого. При неимении информации об актуальных ценах человек покупает нечто не самоё дешёвое (потому что хочет хорошее), но и не самое дорогое. Разброс идёт внутри отрезка примерно по нормальному распределению. Самый известный задокументированный опыт такой (упрощая): в баре продавали пиво 0,3, 0,5 и 0,7. Брали, в основном, 0,5. Экспериментаторы сдвинули границы к 0,5, 0,7 и 0,9. Народ стал брать 0,7, хотя до этого нормой потребления было 0,5.


Механически она реализуется очень просто – сравниваются цены. При одинаковых ценах везёт тому товару, который попал в массив сравнения раньше (скорее всего, был раньше добавлен на сайт).

Первая проблема сортировки по цене в том, что бестселлеры будут заныканы довольно глубоко вниз. Вторая – товары не в наличии, которые могут затесаться в середину списка. Третья – часто появляется много мусора наверху, то есть всякие расходники, упаковки и прочее-прочее, что стоит дёшево, но часто не имеет прямого отношения к товарам, за которыми пришёл человек.

Соответственно, как инструмент она нужна, но как дополнительный. Основная сортировка должна быть другой.

Мы попробовали сортировать по продажам и одновременно стали набирать оценки товаров по шкале от 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)


  1. ToSHiC
    04.11.2015 11:32
    +1

    Можно сделать предположение, что лайк — это маленькая продажа, 10р, или даже 100 (тут я не знаю цифр, вам виднее отношение лайков к обороту). В вашу текущую сортировку такой подход вливается органически. В качестве приятного дополнения лайки автоматически будут бустить новинки, которые упоминаются где либо. Лайки желательно считать не только из вашего магазина, но и лайки статей про игры.


    1. Milfgard
      04.11.2015 11:37

      Спасибо. Формула похожа на весовой кожффициент, просто заход с другой стороны. Лайки, в отличие от продаж, надо считать за большие периоды ещё — год, например.


      1. ToSHiC
        04.11.2015 12:54

        Вот, кстати, важный вопрос: как вы убеждаетесь, что сортировка хорошая? Если ваша метрика может быть измерена на коротком интервале времени, то можно несколько моделей построить и запустить сплиты на сайте с контрольными группами.


        1. Milfgard
          04.11.2015 13:28

          Можно, но задача больше в сортировке в реале, а там так просто не сделать.


  1. psylosss
    04.11.2015 13:43

    Ошибка сортировки

    Не сортировки, а фильтрации. Сортировка — расстановка в правильном порядке, фильтрация — убирание лишнего. Справа на скриншоте здравая мысль — фильтрация снижает необходимость в сортировке. Например фильтр «Показывать только товары в наличии» снимает проблему отображения отсутствующих товаров. Есть ли возможность построить поиск игры таким образом, чтобы пользователь применил 1-2-3 фильтра и у него бы осталось не больше 10 игр, которые подходят именно ему? А 10 игр можно и по цене отсортировать без возможности изменить сортировку.


    1. Milfgard
      04.11.2015 14:00
      -1

      Нет, именно сортировки. В фильтрации эта игра на месте, поскольусоответствует формальному признаку категории, но она должна быть с низким приоритетом.


      1. psylosss
        04.11.2015 14:11

        Если же подразумевается, что компания — «сугубо взрослая», то это все-таки ошибка фильтрации — должно быть дополнительное условие выборки «Игры, которые для компании И которые не детские». Если же компания скорее всего взрослая, но точно хз, то да, это ошибка сортировки. ORDER BY ........., game.isForAdults DESC.

        Не совсем по теме, но близко: может быть, дополнительные иконки помогут быстрее ориентироваться? У вас есть иконки «в наличии», «хит». Что если добавить прямо в списке другие стандартные, типа «6-14 лет», «18+», «4+ игроков». Тогда пользователь сможет фильтровать в своей собственной оперативке, не задействуя UI.

        Сейчас решаю аналогичную задачу с сортировкой и фильтрацией, но в другой области (сортируем компании).


        1. Milfgard
          04.11.2015 14:17

          Вот «Не раскачивай лодку». Берут её либо детям, как задумывалось, либо играть в 35-летних компаниях играть на вечеринках.


          1. psylosss
            04.11.2015 14:22

            Я для решения этой задачи использую простую методику, из которого вытекают все технические следствия (уже совсем не такие простые). Предположим, я не ограничен ни в чём, всё знаю и всё умею. Какие товары и в каком порядке тогда я бы показал данному конкретному пользователю в это конкретное время? Иначе говоря, какая сортировка и фильтрация с точки зрения пользователя была бы идеальна? Исходя из этого становится понятным ответ на вопрос — должна быть «День вождей» в этом списке или нет, и если должна, то в каком месте? И с «лодкой» то же самое. Вопрос не техники, вопрос предметной области.


          1. psylosss
            04.11.2015 14:31
            +1

            Кстати, как ваш пользователь: не хватает чего-то типа «Похожие игры». Меня интересуют игры, похожие на «имаджинариум» например. Или даже на «Диксит», которая у вас не продаётся (это мне уже позже в вашем магазине подсказали, что диксит и имаджинариум — это как аналогия-которую-я-не помню). Как мне их найти?


            1. Milfgard
              04.11.2015 17:51

              Игры той же серии и тех же авторов — пожалуйста. Похожие — придётся сканить по механике, тоже пожалуйста. Также мы вручную иногда рекомендуем товары в дополнительном блоке.


  1. dom1n1k
    04.11.2015 14:03
    +6

    Про мусор сверху это точно. Постоянно такое. Сортируешь например список телефонов, а первые пара страниц — это чехлы и пленки на экран.


    1. Dreyk
      04.11.2015 14:31

      потому что опять же фильтрация. на eBay это решается выбором нужной категории


      1. khim
        04.11.2015 18:04
        +2

        На eBay как раз лучше достаточно популярные товары отсеивать вручную. Потому как все фильтруют по категориям — соответственно если что-то вам интересное продавек засунул не в ту категорию, то он офигивает от того, что все подобные товары давно проданы, а него никто не берёт, а вы можете прикупить что-то с хорошей скидкой.

        Но так, конечно, бывает не всегда… если товар достаточно редкий, то его откопают и купят в какую бы категорию его не засунули…


  1. 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.7


    1. Milfgard
      04.11.2015 23:39
      +1

      Я очень упростил описание. Методика была более сбалансированной и в большее число итераций.


  1. evnuh
    04.11.2015 22:16
    +1

    Сортировать товары в магазине нужно по «интересности» их для покупателя. Можно также назвать это «популярностью», только не по продажам, а по просмотрам. А главное — никаких хитрых вычислений вести не надо и придумывать сложные формулы. Мы делаем так:

    Пользователь навёл мышою на товар в каталоге и задержал (условно, «изучает») — 1 очко товару
    Пользователю зашёл на страницу товара — 5 очков

    А чтобы чуть добавить корелляции с продажами, можно ещё две метрики:

    Пользователь добавил в корзину — 30 очков
    Купил — ещё 30 очков.

    Итого, наверху будут именно те товары, которые хочется кликнуть, посмотреть. Что определенно увеличит показатели пользователей на сайте.


    1. Aingis
      04.11.2015 23:04
      +1

      Тогда какой-нибудь условный Верту или Тесла будет в топе: всем интересно, но никто не берёт — слишком дорого.


    1. Milfgard
      04.11.2015 23:41
      +1

      Прелесть в том, что большая часть наших продаж приходится на розничные магазины. И мы подтягиваем данные из них как опорные. А в них корзины нет.


      1. evnuh
        05.11.2015 19:53

        Ну вот у вас конечно аудитория онлайн/оффлайн сильно пересекается, поэтому да. трудно. Но, вообще, нет ничего плохого в том, чтобы сортировка товаров в ИМ была только по стате с самого ИМ. Раз пользователи на сайте проявляют какой-то интерес к товару, значит именно на сайте он предстапвлен интересно. Возможны даже ситуации, когда смена картинки/описания товара может выбить его в топ по популярности, используя мою формулу. Это именно улучшение поведенческих показателей на сайте, только и всего. И нужно ещё доказать что это влияет на продажи, так же, как и доказать то, что не влияет)


    1. Fedcomp
      04.11.2015 23:44
      +1

      а у вас есть например данные от визора яндекса? (просто интересно) как мне кажется пользователи далеко не всегда наводят мышкой на то что им нравится.


      1. vlivyur
        06.11.2015 10:13

        Было же исследование какое-то, что пользователи часто наводят мышь на интересующий их об'ект, без клика (мышь-то всё равно в руках, а руки ничем не заняты). Ну и подпирают ею те места, где читают.


  1. Minras
    10.11.2015 13:15
    +2

    всё-таки мы в большинстве помним школьную систему оценок, где, по факту, нет единицы


    Я с этой ментальностью как-то на работе в Голландии попал на свой первый митинг с менеджером по оценке успешности моей работы. Надо было мне свои показатели оценить по шкале 1-5, и он независимо от моих оценок тоже меня оценивал. Потом сравнивали.

    В общем, я по опыту советской школы наставил себе везде 4-5, а менеджер принес листик с оценками 3-4, даже одна-две двойки были.

    В общем, я первым делом попросил обсудить значение оценок. Оказалось, что 3 — это просто нормальная работа. 4 — хорошая, с конкретно описываемыми успехами. 5 обычно не бывает и означает, что человек достиг потолка и ему надо подумывать о повышении или смене деятельности. 2 — есть над чем работать, но за пару двоек никто увольнять не будет. Единица — тоже нормальная существующая оценка.

    В общем, восприятие оценок гораздо ближе к математике, чем к долбаному советскому перфекционизму, где единицу иметь настолько зазорно, что их не бывает по факту.