Привет, Хабр! Мы — GetCourse, SaaS-платформа для онлайн-школ. В прошлом посте мы поговорили об устройстве онлайн-школ. Сегодня хотим затронуть технический аспект нашей работы и рассказать о задачах, которые перед собой ставим и считаем достаточно сложными.
Нам повезло работать на растущем рынке — мы были свидетелями шестикратного роста ниши онлайн-допобразования за последние 6 лет до ожидаемых 55 млрд рублей в этом году. Но неизбежно наступает зрелость, рынок становится всё более конкурентным, а значит, действовать нужно эффективнее, постоянно снижая издержки во всех бизнес-юнитах. Как мы это собираемся сделать — читайте под катом.
Машинное обучение, начало: проверяем домашку по рисунку
“
Сейчас рабочий метод повышения эффективности — машинное обучение.
Впервые эту технологию мы применили, будучи в стрессе от внезапно навалившейся ответственности. Мы готовили к запуску бесплатный конкурс рисования в одном из наших проектов — школе Вероники Калачёвой. Победителей конкурса ждали призы — видимо, настолько привлекательные, что зарегистрировалось не 200 или 300 человек, как мы ожидали, а около 20 тыс.
Их работы по условиям конкурса нужно было проверить за неделю, однако ресурсов на проверку ожидаемых 20 тыс. работ у нас не было. Поэтому мы отметили большую часть работ проверенными — и поймали волну негатива из соцсетей в свой адрес.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild6431-6330-4661-b239-316431323362__1.png)
Как и можно было предположить, среди загруженных участниками фотографий неизбежно попадался «подлог» — кто-то в шутку или для того, чтобы пойти по курсу дальше, разместил фото домашнего питомца. И, получив в качестве фидбэка «всё хорошо, ваша работа принята», рассказал об этом у себя в фейсбуке.
“
Мы сделали из этой истории выводы и к следующему конкурсу пришли подготовленными: обучили нейросеть распознавать фотографии рисунков, соответствующих заданию.
С этой целью мы воспользовались нейросетевым тулкитом Nvidia Digits. В нём есть выбор нескольких архитектур, а сами сети предварительно обучены на стоковых датасетах картинок. Ведь для того, чтобы научить сеть отличать существенные признаки рисунков от несущественных, требуется искажать и трансформировать изображения. Так вот эта важная часть подготовки данных — фильтры и искажения — уже содержится в Nvidia Digits.
Подавая на вход наши рисунки, мы дообучали сеть, которая потом сама принимала или отклоняла ответы учеников. Основная сложность заключалась в том, что на каждом уроке ученики рисуют что-то новое. Поэтому требовалось быстро обучать сеть на новых рисунках, чтобы использовать её для проверки работ.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild3531-6264-4430-b335-616637393933__1.jpg)
“
Чтобы быстро обучить сеть, оказалось достаточным подавать ей 20−30 ответов учеников, присланных на определённое задание.
Насколько точна была в итоге разметка? Популярной метрикой качества является показатель AUC: в нашем случае он достигал 80−90% (для сравнения, при случайном гадании этот показатель равен 50%).
Результат работы обученной сети можно видеть на иллюстрации ниже. Сеть на 99,44% уверена, что изображение в верхнем левом углу — это сделанный учеником рисунок. Следующее изображение нейронка с вероятностью 99,97% считает «мусором», а третье считает таковым на 98,08%. Очевидно, второе и третье изображение — это едва начатые наброски, в то время как задание состояло в том, чтобы в цвете нарисовать скрипку, лежащую поверх нотной тетради. Обратите внимание, что шестое изображение, где скрипка повёрнута на 90°, сеть верно опознаёт как завершённую работу с вероятностью 81,6%.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild6631-3664-4139-b735-343365366661__2.jpg)
Можно ли было решить ту же задачу вручную, силами преподавателей и без всякой автоматизации? Дело в том, что мы запускали проект 1 января в 00:00, и он шёл все новогодние праздники. В день нужно было проверять несколько тысяч работ. Мы, во-первых, не хотели, чтобы тысячи людей ждали проверки, во-вторых, были против превращения новогодних каникул в ад для преподавателей. Люди подключались к проверке работ только тогда, когда нейронка определяла вероятность принадлежности к классу pic менее 0.8.
Новый вызов для МО: увеличение конверсии трафика в лиды
Следующая задача, которую мы планируем решить с помощью МО, — увеличение конверсии привлечённого на школы трафика в лиды. Сразу оговоримся, что задача эта перспективная, мы только подступаемся к ней.
“
«Я точно знаю, что половину рекламного бюджета я трачу впустую, только не знаю, какую именно», — гласит известный анекдот.
Мы, как держатели платформы и продюсеры собственных школ, понимаем, что вопрос эффективности использования рекламных бюджетов — один из ключевых для бизнеса. Кто-то из клиентов-школ тратит 30% выручки на рекламу, кто-то 50% и всё равно остаётся в плюсе (понятно, что есть и другие примеры). Так или иначе, ежедневно с помощью рекламы онлайн-школы привлекают на свои продукты тысячи пользователей.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild3033-6632-4035-a438-383361386532__2.png)
“
Все взаимодействия пользователя с системой составляют длинный набор параметров, который мы будем использовать для обучения нейросети.
Сейчас мы собираем более пятидесяти параметров, которые могут быть использованы для анализа поведения пользователя. Эти параметры можно условно сгруппировать по классу задачи, для которой параметр используется.
Так, для анализа поведения посетителя используются данные о времени событий на сайте, устройстве и операционной системе посетителя, информация о географии и, если доступно, о рекламном источнике посещения.
Анализ лидов (второй класс задач) проводится по таким параметрам, как доля лидов в общем количестве посещений, доходимость до конкретного мероприятия или вебинара, время просмотра трансляции.
Для анализа поведения учеников собираются данные о количестве тренингов этого ученика, успешности прохождения уроков, времени на прохождение урока, времени от открытия урока до ответа на дз и др.
Таким образом, мы выделяем три этапа, входящих в декомпозицию глобальной цели по увеличению конверсий:
1
работа с пользователями, пришедшими на сайт, но уходящими без регистрации;
2
работа с теми, кто пришёл на вебинар, прослушал часть, но собирается уйти без покупки;
3
работа с учениками, которые уже купили.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild6536-6164-4261-b731-646434343331__3.png)
На первом этапе, когда «холодный» пользователь пришёл на лендинг курса, конверсия в регистрацию у многих проектов невелика: от 2 до 10%. Тут можно использовать несколько вариантов работы с трафиком, например воспользоваться cookie и через специальные сервисы получить e-mail и телефон пользователя, чтобы продолжать «прогревать» по другим каналам. Или воспользоваться моментом, когда пользователь решает уйти, и попытаться его удержать, узнать причины ухода.
А ещё на первом этапе можно поработать с самой формой регистрации. Например, конверсия статистически выше, когда первичная форма заполнения контактов реализована в механике квиза.
Квиз тут — короткий опросник с прогресс-баром: человек отвечает на вопрос «Мужчина вы или женщина?» и видит, что завершил регистрацию уже на 50%. У него появляется побуждение пройти до конца — так срабатывает психологический приём. И, надо признать, это не самый эффективный метод: если человеку тема неинтересна настолько, что он не готов потратить время на ввод e-mail, протащить его на вебинар и заставить там что-то купить будет нереально. Усилия, которые потрачены на этом этапе воронки, практически не окупаются.
Работа на втором этапе, более перспективном в плане увеличения конверсий из лида в покупателя, связана с тем, чтобы удержать пользователя на вебинаре. Часто люди уходят с вебинара раньше, чем получили ключевое предложение с хорошей скидкой. В этот момент можно использовать понятный «ручной» механизм подхватывания — ставить задачу менеджеру, чтобы писал или звонил оповестить, что вот-вот начнётся секция про скидки и после вебинара продукт уже нельзя будет купить по специальной цене. Наша задача на втором этапе — автоматизация всех подобных процессов.
И наконец, задачи третьего этапа, самые перспективные, — наша зона роста. Актив онлайн-школ — это в первую очередь существующие клиенты, а точнее вся информация о взаимодействии с ними. Если считать суммарно выручку всех школ на GetCourse, видно, что половина её — это повторные продажи. Доля новых продаж (50%) очень высока: это объясняется тем, что многие школы продают лишь один продукт. Привлечение клиента (САС) должно окупиться в первой же продаже, и САС для них со временем становится всё выше.
“
Повторные продажи новых продуктов — вот путь, который удлиняет жизнь школы, давая возможность заработать больше.
![](https://webcf.waybackmachine.org/web/20200911053707im_/https://habrastorage.org/getpro/tmtm/articles/tld/images/13658259/tild3037-3030-4439-a130-323830326666__4.png)
И о той точке, где совершаются повторные продажи, мы знаем довольно много. Например, можем оценить покупательскую способность ученика, потому что знаем его историю — какие ещё продукты он купил в других школах. Можем измерять его вовлечённость, активность и использовать эти данные, показывая школам соответствующие выборки.
“
Таким образом, выделяя активных учеников на базовом продукте с хорошей покупательской способностью, можно будет эффективнее продавать продвинутый продукт с индивидуальными условиями.
При условии, что накоплено достаточно данных, оптимизировать работу с имеющейся базой и увеличить конверсию в новые продажи с помощью машинного обучения вполне реально. При этом оптимальный для нас путь — это не изобретать велосипед, а найти на рынке решения-полуфабрикаты и адаптировать их к нашим процессам.
Железо и софт. Как GetCourse масштабирует IT
В завершение расскажем немного о технической начинке платформы GetCourse.
Когда-то давно проект размещался на одном сервере, и всё работало. По мере роста понадобилось масштабироваться. Например, база данных была отделена от PHP, балансеры были вынесены на отдельные серверы. В момент, когда мы стали делать больше e-mail-рассылок, поняли, что под них нужны отдельные серверы, иначе мешают ограничения на количество сообщений, которые разрешалось отправлять с одного IP.
В итоге это породило большой отдельный парк серверов. Сейчас у нас больше 200 серверов-отправщиков, которые только отправляют рассылки. Больше 10 серверов с базами данных и порядка 10 серверов под обслуживание клиентских запросов. Есть отдельные серверы под видеофайлы. Общая масса хранимого контента в GetCourse составляет около 500 Тбайт.
С момента запуска платформы рост нагрузки шёл постоянно. Постепенно сформировалась команда эксплуатации, которая занимается исключительно тем, что меняет существующую систему так, чтобы она продолжала стабильно работать под растущей нагрузкой.
Поскольку в последние четыре года число клиентов то удваивается, то утраивается за год, мы регулярно сталкиваемся с новыми проблемами. Раза три или четыре сталкивались с DDos: если нашего клиента начинали DDos’ить, тогда мы применяли существующие механизмы через провайдера. Бывают проблемы, которые не зависят от нас, например когда Роскомнадзор одно время банил Telegram, то он заодно банил огромные подсети каких-то зарубежных провайдеров. А в некоторых из этих подсетей были наши IP-адреса отправщиков почты, что приводило к проблемам. Это были локальные проблемы, мы с ними справились достаточно быстро.
Основная часть критичной инфраструктуры у GetCourse в России у провайдера Selectel. Это сделано по двум причинам. Во-первых, чтобы быстро всё работало у пользователей в России. Во-вторых, по закону «О персональных данных» мы обязаны хранить данные пользователей в России, и мы эту штуку чётко выполняем. При этом используем и другие хостинги.
Крупные компании вроде «Яндекса» строят свои дата-центры, и у них нет потребности в облачном хостинге. Мы не такие большие, чтобы строить дата-центр, поэтому у нас всё в облачных хостерах — используем их штук пять под разные задачи в России и вне её. Основные причины — либо экономия, либо диверсификация рисков.
Стек технологий
Мы используем устоявшийся стек технологий. Где-то в глубине находится база данных MySQL, основной язык — PHP, веб-сервер Nginx. Дальше идут менее значимые технологии для кэширования memcached, Redis, есть технологии виртуализации, Docker. В какой-то момент понадобился Postgres.
Кроме того, мы использовали Clickhouse. Это движок по аналитике от «Яндекс.Метрики», который представляет собой базу для того, чтобы сохранять данные о посетителях. ClickHouse прекрасен тем, что позволяет очень быстро агрегировать данные и строить отчёты. На базе ClickHouse мы сделали собственный модуль по аналитике для наших клиентов — это сэкономило человеко-годы разработки.
“
По похожему принципу мы планируем собрать базу под наши задачи машинного обучения: найти нужные кирпичики, чтобы прикрутить их к нашей системе.
Интересно послушать читателей: ваши проекты в их сегодняшнем состоянии собраны по тому же принципу конструктора или вы отдаёте предпочтение монолитному подходу и полностью самостоятельной разработке? Нам интересны разные мнения!
Комментарии 1
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.