Эксперименты A/B со слоями статистики

Эксперименты A/B со слоями статистики

12 апреля 2022 г.

Если вы просто хотите пропустить учебник и получить завершенный проект, вы можете скачать его [здесь] (https://gist.github.com/daniel-statsig/1e3f8d58930664a15eab1fdd6a6875db/archive/eb19e4f67d1920d92840dfb05dde74cb88ee7b32.zip) (вам все еще нужно обновить scripts.js, чтобы включить ваш клиентский ключ SDK).


Стартер


Во-первых, нам нужно настроить веб-сайт, на котором мы будем использовать Statsig.


Стартовый проект можно скачать [здесь] (https://gist.github.com/daniel-statsig/71b9d3d68cc06c37faf6ab2e62aa53bd/raw/1e11558484c752980a625ecb0fbc59fdebdba215/rps-starter.zip), или вы можете выполнить следующие шаги.


Следующая команда создает файлы, которые нам понадобятся:


дотроньтесь до index.html, стилей.css, scripts.js


В index.html вставьте следующее:


```разметка



<голова>





<тело>



Выберите ход


...


<дел>









В scripts.js вставьте следующее:


```javascript


пусть движется = ["✊", "🖐", "✌"];


функция onPick(playerIndex) {


const randomMove = move[Math.floor(Math.random() * move.length)];


const cpuIndex = move.indexOf(randomMove);


const lossIndex = (playerIndex + 1) % move.length;


пусть результат = "Выиграл";


если (cpuIndex === playerIndex) {


Результат = "Привязан";


} иначе если (cpuIndex === lossIndex) {


Результат = "Потерян";


document.getElementById("компьютер-переместить-текст").innerHTML =


"Выбрано компьютером" + randomMove;


document.getElementById("текст-результата").innerHTML = "Вы " + результат;


И в styles.css вставьте следующее:


``CSS


.контейнер {


преобразование: перевести (-50%, -50%);


положение: абсолютное;


слева: 50%;


верх: 50%;


п {


выравнивание текста: по центру;


размер шрифта: 32px;


семейство шрифтов: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",


"Lucida Sans", Arial, без засечек;


вес шрифта: 700;


результат-текст {


размер шрифта: 40px;


вес шрифта: 900;


.кнопка {


контур: нет;


граница: нет;


фон: нет;


размер шрифта: 60px;


курсор: указатель;


радиус границы: 100 пикселей;


отступ: 10px 20px;


.кнопка:наведите {


цвет фона: rgba (0, 0, 0, 0,133);


Если вы сейчас откроете файл index.html в своем веб-браузере, вы должны увидеть нашу базовую игру «Камень, ножницы, бумага». Как игрок, вы можете выбрать ход для броска, и компьютер случайным образом выберет ход, который будет играть против вас. Как только ход будет выбран, страница обновится, чтобы отобразить результат.



Добавление статистики


Давайте теперь добавим Statsig, чтобы мы могли начать экспериментировать с нашей RPS-игрой.


Включим в наш файл index.html SDK Statsig JS, добавив импорт скрипта в наш тег head.


```разметка


<голова>







Теперь в нашем файле scripts.js мы можем добавить вызовы к Statsig SDK. Следующий код использует SDK Statsig, который мы загрузили из CDN JSDelivr, чтобы выполнить «инициализацию», которая будет извлекать все данные, относящиеся к серверам Statsig данного пользователя. Этот вызов инициализации попадает в сеть и является асинхронным, поэтому мы должны дождаться его.


```javascript


пусть движется = ["✊", "🖐", "✌"];


(асинхронный () => {


ждать statsig.initialize(


"<КЛИЕНТ_SDK_KEY>",


ID пользователя: "some_user_id",


функция onPick(playerIndex) {


Теперь в конце функции onPick давайте добавим вызов logEvent для регистрации того, что игра была сыграна. Следующий код регистрирует событие game_played, содержащее результат игры. Это будет метрика, которую мы пытаемся изменить во всех предстоящих экспериментах. Если экспериментальная функция оценивается как «хорошая», она должна увеличивать объем этой метрики по мере того, как все больше людей играют.


```javascript


document.getElementById("computer-move-text").innerHTML = "Компьютер выбрал " + randomMove;


document.getElementById("текст-результата").innerHTML = "Вы " + результат;


statsig.logEvent("game_played", result.toLowerCase()); // новая линия


Теперь всякий раз, когда вы играете в игру, событие регистрируется в Statsig. Мы можем убедиться в этом, перейдя на страницу метрик на console.statsig.com



Запуск эксперимента


Теперь мы настроим наш первый эксперимент, чтобы протестировать новые функции, добавленные в нашу игру RPS. Наш первый эксперимент добавит в игру новые ходы в виде карточных мастей (♣️, ♥️, ♦️, ♠️). На самом деле это не имеет смысла для RPS-игры, но продемонстрирует, как работают эксперименты.


Создать слой


Войдите на console.statsig.com, и мы добавим новый слой. Если вы еще этого не сделали, вам нужно создать проект, выбрав «Создать новый» в раскрывающемся списке вверху слева.



Когда у вас есть проект, перейдите на страницу экспериментов, выбрав «Эксперименты» в левом списке навигации. Когда страница загрузится, выберите вкладку «Слои», а затем создайте новый слой. Мы назовем наш новый слой «rps_experiments».



Настроить эксперимент


На странице «Эксперименты» с выбранной вкладкой «Слои» вы можете нажать «Создать новый эксперимент в слое».


Кроме того, на странице «Эксперименты» с выбранной вкладкой «Эксперименты» вы можете нажать «Создать».


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


В диалоговом окне создания мы назовем наш эксперимент «alternative_movesets». Убедитесь, что поле слоя под Advanced заполнено слоем, который мы создали выше.



Теперь, когда наш эксперимент создан, мы можем добавить параметры к нашему слою, а затем выбрать их как часть этого эксперимента. Мы собираемся создать группу тестирования и контроля для этого эксперимента. Группа «Контроль» сохранит те же ходы, что и сейчас, но группа «Тест» будет использовать масти карт вместо жестов руками.


На странице экспериментов выбираем «+ Добавить параметр» и добавляем наши новые ходы. Это будет просто массив строк, которые являются смайликами карточной масти.



После этого ваша установка должна выглядеть примерно так, как показано ниже. С контролем просто используйте текущие ✊, ✋ и ✌️ и протестируйте, используя обновленные ♠️, ♥️, ♣️ и ♦️.



Реализовать в коде


Давайте обновим наш index.html, чтобы мы могли динамически добавлять кнопки во время выполнения. Мы изменим тело, чтобы оно выглядело так, присвоив кнопкам div идентификатор «действия».


```разметка


<тело>



Выберите ход


...





Затем мы обновим файл scripts.js, чтобы получить набор ходов из Statsig и динамически добавить кнопки в DOM. Новая функция настройки должна выглядеть следующим образом. Сначала мы получаем ссылку на наш слой через getLayer("rps_experiments"), а затем получаем наши ходы, вызывая layer.get("moves", move). Первый аргумент — это имя параметра перемещения, а второй — значение по умолчанию, если параметр не найден.


```javascript


пусть движется = ["✊", "🖐", "✌"];


асинхронный () => {


ждать statsig.initialize(


"<КЛИЕНТ_SDK_KEY>",


ID пользователя: "some_user_id",


// -- новые строки ниже


const layer = statsig.getLayer("rps_experiments");


движется = layer.get («движется», движется);


константные действия = document.getElementById («действия»);


// Динамически добавлять кнопки в DOM


move.forEach((значение, индекс) => {


постоянная кнопка = document.createElement("кнопка");


кнопка.textContent = значение;


button.onclick = () => onPick(index);


button.className = "кнопка";


действия.appendChild (кнопка);


Теперь, если мы перезагрузим страницу, в зависимости от того, в какой экспериментальной группе находится ваш пользователь, вы либо не увидите никаких изменений, либо увидите новые отображаемые ходы.


Если вы не видите никаких изменений, меняйте userID, пока не получите тот, который находится в группе «Тест». Вы также можете использовать Feature Gate, чтобы переопределить группу, в которой находится данный пользователь, но это выходит за рамки этого руководства (подробнее [здесь] (https://docs.statsig.com/experiments-plus/overrides)).



Расширение эксперимента


Итак, мы провели эксперимент с использованием getLayer, но до сих пор процесс не сильно отличался от API getExperiment. Давайте добавим еще несколько параметров для экспериментов, чтобы продемонстрировать мощь getLayer.


Даем нашему противнику имя


Во-первых, мы добавим к нашему слою новый параметр, который будет содержать имена для нашего противника ИИ. На нашей странице слоев (Experiments > Layers Tab > rps_experiments) добавьте параметр к слою, выбрав «+ Add Parameter». В появившемся диалоговом окне создания параметров введите значения, показанные ниже.



Теперь в нашем файле scripts.js в функции onPick добавим вызов нашего нового параметра ai_name. Мы будем ссылаться на тот же слой, что и раньше, но на этот раз имя нашего параметра — «ai_name». Мы снова предоставим значение по умолчанию («Компьютер»), чтобы вернуться к нему, если параметр не может быть найден. С нашим aiName, полученным из слоя, мы затем обновляем DOM, чтобы использовать наше новое имя.


```javascript


const aiName = layer.get("ai_name", "Компьютер"); // новая линия


document.getElementById("computer-move-text").innerHTML = ${aiName} выбрал ${randomMove}; // обновлено


Добавление таблицы результатов


Подобно нашему параметру ai_name, мы добавим к нашему слою новый параметр score_board_enabled. Однако на этот раз мы будем использовать простое логическое значение вместо строки.



Теперь в верхней части scripts.js мы добавим новую переменную для хранения нашего счета. Затем в функции onPick мы увеличим счет при выигрыше и отобразим его в DOM. Мы будем использовать логическое значение scoreboard_enabled, чтобы контролировать, будет ли это отображаться пользователю.


```javascript


// Верхняя часть scripts.js


пусть движется = ["✊", "🖐", "✌"];


пусть оценка = 0; // новая линия


```javascript


// функция onPick в scripts.js


функция onPick () {


пусть результат = "Выиграл";


если (cpuIndex === playerIndex) {


Результат = "Привязан";


} иначе если (cpuIndex === lossIndex) {


Результат = "Потерян";


} еще {


оценка++;


// новые строки добавлены ниже


если (layer.get("scoreboard_enabled", false)) {


document.getElementById("табло").innerHTML = "Ваша оценка: " + оценка;


Запуск второго эксперимента


Теперь с этими новыми параметрами мы можем запустить еще один эксперимент (даже если первый все еще выполняется), который содержит исходный параметр движений, а также более новые параметры ai_name и scoreboard_enabled.


Поскольку мы используем getLayer, а не getExperiment, нам не нужно обновлять наш код, чтобы явно ссылаться на эксперимент, getLayer автоматически возвращает правильные значения в зависимости от того, в каком эксперименте, если таковой имеется, находится пользователь.


Как и в предыдущем эксперименте, мы перейдем на страницу «Эксперименты» и добавим новый эксперимент (опять же, не забудьте установить наш слой «rps_experiments» в разделе «Дополнительно» > «Добавить слой» > «Слой»). Назовем этот новый эксперимент «updated_features».


Для этого эксперимента мы создадим 3 группы (Control, Test_Pokemon и Test_AI).


Управление будет таким же, как и раньше. Test_Pokemon будет содержать эмодзи и противника на тему покемонов. Test_AI также будет иметь разные смайлики и имя противника, но также будет отображать табло. Это должно привести к установке ниже.



Теперь вы можете запустить эксперимент updated_features параллельно с первым экспериментом alternative_movesets. В зависимости от того, в какой группе находится пользователь, ему будет показана другая RPS-игра, чем другим пользователям. Измените идентификатор пользователя, если хотите попробовать разные возможности.


updated_features Test_AI vs updated_features Test_Pokemon


Оценка экспериментов


Итак, наш эксперимент продолжается уже несколько дней, и пришло время проверить результаты.


Перейдя на вкладку «Результаты» в нашем эксперименте updated_features, мы можем оценить, как прошел наш эксперимент.



Мы видим, что в нашем эксперименте приняли участие 1,17 тыс. пользователей. Мы определили событие game_played как ключевую метрику. Глядя на результаты, мы видим, что тестовая группа «Test_Pokemon» имеет статистически значимый рост. Если бы это была реальная функция, группа Test_Pokemon была бы отличным кораблем.



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE