Тебе нравится Starbucks? Сколько ты там тратишь? Вы пользуетесь предложениями Starbucks?

Меня заинтриговали приведенные выше вопросы. Итак, я решил исследовать себя. В основном меня интересовало, сколько люди тратят в Starbucks, поэтому я решил построить модель, которая предсказывает количество продукта, которое покупатель купит.

Используемая метрика:

Я буду использовать среднеквадратичную ошибку (RMSE) в качестве показателя для оценки производительности моей модели.

Почему я выбрал RMSE в качестве показателя?

Среднеквадратичная ошибка (RMSE) - это стандартное отклонение остатков (ошибок прогноза). Остатки - это мера того, насколько далеко от точек данных линии регрессии; RMSE - это мера того, насколько разбросаны эти остатки. Другими словами, он показывает, насколько данные сконцентрированы вокруг линии наилучшего соответствия.

Некоторые преимущества использования RMSE:

1) Это просто и интуитивно понятно для непрофессионала, поскольку у него те же единицы, что и у целевого значения. Это просто означает, насколько наши прогнозы далеки от фактических значений.

2) Это легко и не требует больших вычислительных затрат.

3) Поскольку мы возводим значения в квадрат, следовательно, положительные и отрицательные значения ошибок не компенсируются.

4) Поскольку ошибки возводятся в квадрат перед их усреднением, RMSE дает относительно высокий вес большим ошибкам по сравнению с маленькими ошибками.

5) RMSE является метрикой по умолчанию для многих моделей, потому что функция потерь, определенная в терминах RMSE, плавно дифференцируема и упрощает выполнение математических операций.

Я посмотрел на некоторые другие варианты, такие как средняя абсолютная ошибка (MAE), средняя ошибка смещения (MBE), среднеквадратичная ошибка (MSE), R-Squared; но обнаружил, что RMSE лучше подходит для моей цели, потому что:

1) Средняя абсолютная ошибка (MAE): MAE измеряет среднюю величину ошибок в наборе прогнозов без учета их направления. Это просто означает, что MAE придает равный вес как большим ошибкам, так и небольшим ошибкам. Следовательно, RMSE более полезен, когда большие ошибки особенно нежелательны, как в моем случае. Кроме того, MAE принимает абсолютное значение, что нежелательно во многих математических расчетах.

2) Средняя ошибка смещения (MBE): если абсолютное значение не берется в MAE (признаки ошибок не удаляются), средняя ошибка становится средней ошибкой смещения (MBE) и обычно составляет предназначен для измерения среднего смещения модели. MBE может передавать полезную информацию, но ее следует интерпретировать осторожно, поскольку положительные и отрицательные ошибки взаимно компенсируются. Что для нашей цели нежелательно.

3) Среднеквадратичная ошибка (MSE): RMSE - это просто квадратный корень из MSE. Таким образом, у него не те же единицы измерения, что и у целевого значения, а их квадрат. Поэтому я им не пользовался.

4) R-квадрат: R-квадрат ничего не говорит об ошибке предсказания. Мы не можем использовать R-квадрат, чтобы определить, смещены ли оценки коэффициентов и прогнозы, поэтому необходимо оценивать графики остатков. R-квадрат не обязательно указывает, обеспечивает ли регрессионная модель адекватное соответствие вашим данным. Хорошая модель может иметь низкое значение R2. С другой стороны, смещенная модель может иметь высокое значение R2. Поэтому я не использовал R-квадрат в качестве метрики.

Вы можете найти полный код этого проекта в моем профиле на github по ссылке ниже:



Итак, приступим ………

В этом проекте я буду следовать процессу CRISP-DM, который состоит из следующих этапов:
1) Понимание бизнеса
2) Понимание данных
3) Подготовка данных
4) Моделирование данных
5) Оцените результаты
6) Разверните

1) Деловое понимание

Раз в несколько дней Starbucks рассылает предложения пользователям мобильного приложения. Предложение может быть просто рекламой напитка или фактическим предложением, таким как скидка или BOGO (купите один, получите один бесплатно). Некоторые пользователи могут не получать никаких предложений в течение определенных недель. Кроме того, не все пользователи получают одинаковое предложение, и это трудная задача.

У каждого предложения есть срок действия до истечения срока действия предложения. Например, предложение BOGO может действовать всего 5 дней. Информационные предложения также имеют срок действия, даже если эти объявления просто предоставляют информацию о продукте; например, если информационное предложение действует 7 дней, предполагается, что покупатель ощущает влияние предложения в течение 7 дней после получения объявления.

2) Понимание данных

Данные, которые я буду использовать, доступны в Udacity Starbucks Capstone Project. Он содержит смоделированные данные, имитирующие поведение клиентов в мобильном приложении Starbucks rewards. Этот набор данных представляет собой упрощенную версию настоящего приложения Starbucks, потому что в базовом симуляторе есть только один продукт, тогда как Starbucks фактически продает десятки продуктов.

Данные содержатся в трех наборах данных:

  1. портфель - содержащий идентификаторы предложений и метаданные о каждом предложении (продолжительность, тип и т. д.)
  • id (строка) - id предложения
  • offer_type (string) - тип предложения, т.е. BOGO, скидка, информационное
  • сложность (int) - минимальные затраты, необходимые для завершения предложения
  • reward (int) - награда за выполнение предложения
  • duration (int) - время открытия оферты в днях
  • каналы (список строк)

2. профиль - демографические данные для каждого клиента

  • age (int) - возраст покупателя
  • стала_member_on (int) - дата, когда клиент создал учетную запись приложения
  • пол (str) - пол покупателя (обратите внимание, что некоторые записи содержат "O" вместо M или F)
  • id (str) - идентификатор клиента
  • доход (float) - доход клиента

3. расшифровка - записи транзакций, полученных предложений, просмотренных предложений и завершенных предложений

  • событие (str) - описание записи (т.е. транзакция, полученное предложение, просмотренное предложение и т. д.)
  • person (str) - идентификатор клиента
  • time (int) - время в часах. Данные начинаются в момент времени t = 0
  • value - (dict of strings) - либо идентификатор предложения, либо сумма транзакции в зависимости от записи

Я провел исследовательский анализ данных (EDA), чтобы лучше понять данные. Получил следующие результаты:

  1. Распределение людей по возрасту. Был сделан интересный вывод. Так много людей в возрасте 118 лет. Это означает, что либо Starbucks обнаружила «Фонтан молодости», либо в данных есть ошибка. После некоторых исследований я обнаружил, что это код пропущенных значений. Мы разберемся с этим позже.

2. Уровень доходов клиентов: Люди всех слоев населения пьют из Starbucks. Хорошо для Starbucks!

3. Дата членства клиентов: 2017 год, кажется, был удачным для программы членства Starbucks.

3) Подготовьте данные

Это самая сложная и трудоемкая часть любого проекта по науке о данных. И этот проект не стал исключением.

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

  1. Для данных портфолио:
  • Мы делаем отдельные столбцы для каждого канала (интернет, электронная почта, мобильный, социальный). Столбец имеет значение 1, если предложение работает на этом канале, в противном случае - 0.

Функция очистки:

Результирующие данные:

2. Для данных профиля:

  • Как отмечалось ранее, 118 - это код для пропущенных значений в столбце возраста, поэтому я удаляю строки с отсутствующими данными.
  • Я также создал новый столбец «Дни участника», то есть количество дней, в течение которых пользователь является членом Starbucks. Это будет более интуитивно понятно, чем столбец «стал_компонент_вон».

Функция очистки:

Результирующие данные:

3. Для данных расшифровки:

  • Столбец «значение» содержит данные типа {«сумма», «идентификатор предложения», «идентификатор_предложения», «вознаграждение»}. В данных «идентификатор предложения» и «идентификатор предложения» представлены отдельно. Но мы знаем, что это одно и то же. Я сделал столбец «offer_id», объединяющий значения «id предложения» и «offer_id». Этот столбец будет содержать соответствующее значение предложения, если оно есть, в противном случае - NaN.
  • Я сделал два отдельных столбца «сумма» и «вознаграждение» из столбца «стоимость». Эти столбцы будут содержать соответствующие суммы, если они есть, в противном случае - NaN.

Функция очистки:

Результирующие данные:

Я удалил дубликаты также в данных. Они присутствовали в данных стенограммы.

После этого я объединил три фрейма данных, чтобы сформировать единый консолидированный фрейм данных.

Наконец, я собрал данные, чтобы создать одну строку для каждого клиента и соответствующие функции для этого клиента в виде столбцов.

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

4) Моделирование данных

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

На этом этапе я сделал следующие шаги:

  1. Созданы новые функции для «year_joined» и «month_joined» из столбца «created_member_on». И удалил столбец «стал_элементом_в».
  2. Один горячий закодировал столбец пола.
  3. Разделите данные на функции и целевую метку, а затем на наборы данных для обучения и тестирования. Я сделал для этого функцию.

4. Сделал базовую модель алгоритма случайного леса с параметрами по умолчанию. В качестве метрики я использовал среднеквадратическую ошибку (RMSE), и я получил следующие результаты:

Baseline Random Forest model performance:- 
Train RMSE error: 43.40822633356865, 
Test RMSE error: 100.12625339540412

5. Создал конвейер с MinMaxScaler () и XGBoost Regressor в качестве нашей модели.

6. Использовал GridSearchCV для настройки гиперпараметров нашей модели для получения наилучших результатов. Я использовал ту же метрику Среднеквадратичной ошибки (RMSE) и получил следующие результаты:

Tuned XGBoost model performance:- 
Train RMSE error: 86.93099660022715, 
Test RMSE error: 84.0456223669343

Обсуждение окончательного предиктора (модели):

  1. Я сделал конвейер из MinMaxScaler () и XGBoost Regressor (). Я установил этот конвейер для обучающих данных и использовал этот конвейер для окончательного прогнозирования данных тестирования, а также данных обучения. Наконец, я рассчитал RMSE на основе своих прогнозов. Ошибка тестирования уменьшилась по сравнению с ошибкой тестирования нашей базовой модели.
  2. Создание конвейера делает нашу модель действительно надежной и простой в использовании. У этого есть следующие преимущества:
    i) Мы можем подогнать и спрогнозировать конвейер. Таким образом, масштабирование и окончательные прогнозы модели происходят только за один шаг, вместо того, чтобы сначала масштабировать данные, а затем использовать модель для прогнозирования.
    ii) Использование MinMaxScaler () для стандартизации наших данных с помощью конвейера, подходящего для нашего поезда данные и преобразует их. Но он только преобразует (и не подходит снова) тестовые данные, когда конвейер используется для прогнозирования. Таким образом, с одной стороны, нам не нужно вызывать подгонку и преобразование данных поезда и преобразовывать тестовые данные отдельно (что экономит усилия); и, с другой стороны, это не позволяет информации из тестовых данных проникать в обучающие данные, когда мы используем GridSearchCV (), чтобы найти лучшие параметры для нашей модели. Это делает нашу модель устойчивой к таким ошибкам утечки информации.
  3. Я использовал MinMaxScaler () для стандартизации моих данных в диапазоне (0,1), чтобы все функции имели одинаковый масштаб данных и, следовательно, не влияли отрицательно на нашу модель. Наличие данных об объектах, представленных в разной шкале значений, может серьезно снизить производительность модели. Следовательно, модель достаточно хорошо реагирует на небольшие изменения в наборе данных.
  4. Оценщиком в моем конвейере является XGBoost Regressor (), который представляет собой реализацию деревьев решений с градиентным усилением, предназначенных для скорости и производительности. Он имеет несколько преимуществ, что делает его очень надежным. Это:
    i) Регуляризация: XGBoost имеет встроенную регуляризацию L1 (регрессия лассо) и L2 (регрессия гребня), которая предотвращает чрезмерную подгонку модели.
    ii) Обработка отсутствующих значений: XGBoost имеет встроенный -встроенная возможность обрабатывать пропущенные значения. Когда XGBoost обнаруживает отсутствующее значение в узле, он пробует как левое, так и правое разделение и изучает путь, ведущий к более высоким потерям для каждого узла. Затем он делает то же самое при работе с данными тестирования.
    iii) Эффективное сокращение дерева: GBM прекратит разбиение узла, когда обнаружит отрицательную потерю при разбиении. Таким образом, это скорее жадный алгоритм. XGBoost, с другой стороны, делает разбиения до указанной max_depth, а затем начинает обрезку дерева в обратном направлении и удаляет разбиения, за пределами которых нет положительного прироста.
    iv) Параллельная обработка: XGBoost использует возможности параллельной обработки, и именно поэтому он намного быстрее, чем GBM. Для выполнения модели он использует несколько ядер ЦП.
  5. Я использовал GridSearchCV (), чтобы найти лучшие параметры для моей модели. Для своей задачи он использует стандартную трехкратную перекрестную проверку. Это позволяет легко адаптировать мой конвейер к любому изменению данных, так как на этом этапе модель будет оптимизирована только для этих данных. Это в сочетании с использованием трубопровода делает весь процесс надежным.
  6. Надежность модели можно оценить, наблюдая, что RMSE тестирования уменьшилась по сравнению с нашими базовыми результатами.

Параметры, которые были точно настроены:

Я настроил следующие параметры XGBoost Regressor ()

  • n_estimators в диапазоне [50, 75, 100, 125]
  • max_depth в диапазоне [3, 4, 5]
  • скорость обучения в диапазоне [0,03, 0,06, 0,1]

5) Оцените результаты

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

Базовая производительность модели случайного леса: -

  • Ошибка поезда RMSE: 43.40822633356865
  • Ошибка теста RMSE: 100.12625339540412

Настроенная производительность модели XGBoost: -

  • Ошибка поезда RMSE: 86.93099660022715
  • Ошибка теста RMSE: 84.0456223669343

Хотя в настроенной модели ошибка поезда увеличилась, но ошибка теста уменьшилась. Это указывает на то, что наша базовая модель была в некоторой степени переоборудована, в то время как наша настроенная модель не переборщила.

Обоснование полного процесса и предпринятых шагов:

  • В этом проекте я следовал процессу CRISP-DM, то есть процессу, которому вы должны следовать, чтобы решить любую проблему науки о данных. Это дает вам надлежащую основу для решения проблемы, иначе вы можете запутаться в том, что делать дальше.
  • Я создавал функции, когда требовалось следовать принципу DRY, и повторно использовал эти функции. Я предлагаю сделать это, поскольку это экономит много времени.
  • Сначала я исследовал данные и по пути обнаружил некоторые проблемы с данными. Он был нечистым, со многими пропущенными значениями.
  • Я обнаружил, что возраст = 118 в данных, и это тоже много данных с возрастом = 118. Сначала я был удивлен, но потом, немного подумав и исследуя, я обнаружил, что это код пропущенного значения.
  • После очистки данных мне пришлось как-то объединить 3 фрейма данных, которые у меня были. Это было немного сложно из-за разных способов хранения. Чтобы найти правильный способ, потребовались некоторые размышления и эксперименты.
  • После объединения данных я агрегировал данные и обрабатывал их еще больше. Я также сделал некоторые функции, которые были более интуитивно понятными.
  • После того, как данные были готовы для ввода в модель, я разделил их на данные для обучения и тестирования в соответствии с практикой, чтобы решить любую проблему науки о данных.
  • Был получен результат базового прогноза, после чего я улучшил эти результаты, создав конвейер и используя gridsearch cv для настройки гиперпараметров модели.
  • Наконец, я получил результаты прогнозов на тренировочных и тестовых данных, которые были перечислены выше.

Отражение:

  • У меня была интересная и актуальная проблема. Мне понравился весь процесс CRISP-DM, весь процесс проходил в пошаговой манере, описанной выше, что действительно помогло мне двигаться в правильном направлении.
  • Я нашел слияние и консолидацию трех наборов данных правильным образом довольно сложной задачей. Мне потребовалось много экспериментов и исследований, прежде чем я смог это сделать. Правильно сказано, что очистка и предварительная обработка данных являются наиболее важной частью любого проекта в области науки о данных.

Объем улучшения:

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

6) Развернуть

Последний этап процесса - это блог. Я продемонстрировал здесь свои выводы и надеюсь, вам понравилось это читать.