Capstone Project для специалиста по данным Udacity NanoDegree

Введение

В этом проекте методы контролируемого и неконтролируемого обучения используются для анализа демографических данных клиентов компании по продаже товаров по почте в Германии в сравнении с демографической информацией для населения в целом. Цель этого проекта - охарактеризовать потребительский сегмент населения и построить модель, которая сможет предсказывать клиентов для Arvato Financial Solutions.

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

Заявление о проблеме

Проект состоит из четырех основных частей:

  1. Предварительная обработка данных

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

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

2. Сегментация клиентов

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

Я буду использовать метод анализа главных компонент (PCA) для уменьшения размерности. Затем кривая изгиба будет использоваться для определения наилучшего количества кластеров для алгоритма KMeans. В завершение я буду применять KMeans для сегментации населения и клиентов и определения описания целевого кластера для компании.

3. Модель обучения с учителем

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

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

4. Конкурс Kaggle

Результаты этой части необходимо отправить на конкурс Kaggle.

Показатели

Площадь под кривой рабочих характеристик приемника (ROC_AUC) от прогнозируемых вероятностей будет использоваться для оценки характеристик моделей. Кривая ROC создается путем построения графика зависимости истинно положительной скорости (TPR) от ложноположительной скорости (FPR) при различных настройках пороговых значений. AUC обеспечивает совокупный показатель производительности по всем возможным пороговым значениям классификации. Один из способов интерпретации AUC - это вероятность того, что модель оценивает случайного целевого человека выше, чем случайного нецелевого человека. Таким образом, ROC-анализ предоставляет инструменты для выбора возможно оптимальных моделей для задачи прогнозирования клиентов.

Результаты и обсуждение

Предварительная обработка данных

С этим проектом связаны две таблицы Excel с описанием данных и четыре файла данных:

  • AZDIAS: Демографические данные для населения Германии в целом. В нем 891211 человек (строк) и 366 элементов (столбцов).

  • CUSTOMERS: Демографические данные для клиентов компании, занимающейся доставкой по почте. Он имеет 191652 строки и 369 функций.

  • MAILOUT_TRAIN: Демографические данные для лиц, которые были целями маркетинговой кампании; 42982 человека и 367 характеристик, включая отзывы людей.
  • MAILOUT_TEST: Демографические данные для лиц, которые были целями маркетинговой кампании; 42833 человека и 366 функций.

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

Анализ столбцов и строк с пропущенными значениями

Во-первых, я создал Python-словарь кодов отсутствующих значений, где ключ в паре «ключ»: значение является атрибутом, а значение - списком отсутствующих кодов, полученным из DIAS Attributs - Values ​​2017.xlsx.

Интересно, что в словаре только 275 из 366 элементов, а это означает, что есть много функций, которые не перечислены в данном файле описания атрибутов, а также некоторые из недостающих значений атрибутов просто не вводятся и перечисляются в наборе данных как numpy не число (np.nan).

Затем значения, которые соответствуют кодам пропущенных значений набора данных AZDIAS, были преобразованы в значения np.nan, и окончательное количество пропущенных значений было проанализировано для каждого атрибута.

Анализ показывает, что в большинстве столбцов отсутствует менее 30% данных, а в 41 атрибуте отсутствует более 30% данных (см. Распределение пропущенных значений в этих столбцах ниже). Этот 41 атрибут был исключен из анализа.

Кроме того, есть другие столбцы, которые были удалены по следующим причинам:

  • столбец с уникальными значениями, LNR
  • категориальные столбцы с более чем 10 категориями, чтобы избежать множества дополнительных атрибутов после однократного кодирования (CAMEO_INTL_2015 - исключение)
  • столбцы с повторением информации из другого объекта (например, fein vs grob)
  • некоторые атрибуты, для которых не дано описание и трудно предсказать значение и тип столбца (категориальный vs порядковый vs смешанный).

Объединение пропущенных значений по строкам показывает, что максимальное количество пропущенных данных в каждой строке составляет 233 атрибута из 303 атрибутов, оставшихся после отбрасывания столбцов. Распределение количества отсутствующих данных в каждой строке показывает, что в большинстве строк отсутствует менее 25 атрибутов. Итак, данные были разделены на два подмножества: azdias с ‹= 25 отсутствующими атрибутами (737235 строк) и azdias с› 25 отсутствующими атрибутами (153986 строк). Сравнение распределения значений для 6 случайно выбранных столбцов показывает, что существует аналогичное распределение в двух наборах данных (см. Гистограмму для 6 различных атрибутов с несколькими наборами данных nan по сравнению со многими наборами данных nan ниже).

Назначение типов атрибутов

Чтобы перейти к этапу проектирования и преобразования данных, все атрибуты должны быть отнесены к следующим типам: категориальные, числовые, порядковые, двоичные, смешанные. Для этого шага я вручную создал файл attribute_types.csv с именами атрибутов, типами, действием (сохранить, сбросить, одноразовый или инженерный) и столбцами причины сброса.

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

Объект OST_WEST_KZ был закодирован как 0 для Ost и 1 для западного движущегося паттерна. Функция времени EIGEFUEGT_AM была преобразована в формат года. Четыре смешанные функции были переработаны следующим образом:

  • PRAEGENDE_JUGENDJAHRE - ›MOVEMENT (1: Mainstream, 2: Avantgarde) и GENERATION_DECADE (4: 40s, 5: 50s, 6: 60s, 7: 70s, 8: 80s, 9: 90s)
  • CAMEO_INTL_2015 - ›БОГАТСТВО (1: богатые домохозяйства, 2: зажиточные домохозяйства, 3: комфортные домохозяйства, 4: менее обеспеченные домохозяйства, 5: более бедные домохозяйства) и LIFE_AGE (1: семейные пары и одиночки, 2: молодые пары с детьми, 3: семьи с детьми школьного возраста, 4: пожилые семьи и зрелые пары, 5: пожилые люди на пенсии)
  • WOHNLAGE - ›RURAL_NEIGBORHOOD (0: не сельский, 1: сельский)
  • PLZ8_BAUMAX - ›PLZ8_BAUMAX_FAMILY (0: 0 семей, 1: в основном 1-2 семейных дома, 2: в основном 3-5 семейных домов, 3: в основном 6-10 семейных домов, 4: в основном 10+ семейных домов и PLZ8_BAUMAX_BUSINESS (0: не бизнес) , 1: Бизнес)

Стандартизация и работа с NaN

Прежде чем применять методы уменьшения размерности к данным, нам необходимо выполнить масштабирование функций, чтобы на векторы главных компонентов не влияли естественные различия в масштабе функций. На этом этапе все отсутствующие данные np.nan необходимо отбросить или условно вычислить. Есть несколько стратегий работы с NaN. Простой вариант удаления точек данных с NaN может привести к потере большого количества информации (~ 30%). Лучшая стратегия - это вменение отсутствующих значений средним или наиболее частым значением. Вмененные значения в большинстве случаев будут не совсем точными, а будут систематически выше или ниже их фактических значений. Однако обычно это дает более точные результаты, чем полное удаление точек данных или столбцов.

Поэтому я выбираю стратегию для вменения двоичных данных с наиболее частым значением, числовых данных со средним значением в столбце. Категорические пропущенные значения будут присвоены нулям после преобразования в фиктивные столбцы. Затем для масштабирования объектов использовалась процедура стандартизации. Преимущество процедуры стандартизации в том, что она не привязывает значения к определенному диапазону и гораздо меньше подвержена влиянию выбросов.

Конвейер преобразования данных

Во-первых, я идентифицировал асимметричные числовые непрерывные атрибуты, используя метод pandas skew с порогом перекоса 1.0. Эти атрибуты были присвоены как log_attributes, и конвейер был создан для этих атрибутов со следующими шагами: натуральное логарифмическое преобразование, вменение по медиане и стандартное масштабирование. Двоичные атрибуты (bin_attributes) подвергались вменению только по наиболее частому значению. Класс DummiesTransformation создан для преобразования категориальных атрибутов (cat_attributes). В этом преобразовании не отбрасывались лишние фиктивные столбцы, чтобы сохранить скрытую информацию об отсутствующих значениях, закодированных нулями. Все другие преобразования числовых и порядковых атрибутов (num_attributes) были объединены в конвейер с вменением по медиане и масштабированием с использованием стандартного масштабатора. Наконец, создается объект ColumnTransformer, который объединяет несколько конвейеров преобразования функций в один преобразователь. Этот объект в дальнейшем использовался для преобразования данных для всех частей.

трансформаторы = [('log', log_pipeline, log_attributes),
('двоичный', binary_pipeline, bin_attributes),
('cat', cat_pipeline, cat_attributes),
('число', num_pipeline, num_attributes)]

ct = sklearn.compose.ColumnTransformer (трансформаторы = трансформаторы)

Краткое примечание о выбросах

Я использовал правило Тьюки для обнаружения выбросов вне межквартильного диапазона (IQR): IQR = Q3 - Q1. Однако удаление выбросов всего шести атрибутов, которые претерпели преобразования журнала, приводит к потере около 30% данных. Итак, я решил сохранить эти очки.

Сводка предварительной обработки данных

Таким образом, все наборы данных проходят процедуру очистки (функция clean_data), которая: (1) удаляет столбцы и строки, (2) модернизирует 4 функции смешанного типа и (3) претерпевает преобразование с помощью преобразователя столбцов, состоящего из функции конвейера союз. Примечательно, что использование конвейера значительно облегчает преобразование и построение модели машинного обучения. Это предотвращает утечку данных, которая потенциально может привести к переобучению алгоритма, улучшает организацию кода и снижает риск путаницы в столбцах в наборах для обучения и тестирования.

В целом, после этапа конвейера загрузки преобразования и извлечения (ETL) данные AZDIAS были преобразованы в 737235 строк x 410 столбцов, а данные CUSTOMERS были преобразованы в набор данных 134245 строк x 410 столбцов.

Сегментация клиентов

PCA

Анализ главных компонент (PCA) данных был применен для уменьшения размерности. Я построил кумулятивную объясненную дисперсию в зависимости от ряда основных компонентов (показаны линией) вместе с графиком объясненной дисперсии (см. Ниже). После ~ 175 компонентов наблюдается визуальное сокращение объясненной вариативности. Такое количество преобразованных функций приводит к 92% объясненной дисперсии. Таким образом, 175 преобразованных функций были сохранены для кластерной части проекта.

Первая, вторая и третья главные компоненты имеют дисперсию 8,0%, 6,0% и 5,0%, соответственно, и относятся к следующим трем следующим скрытым характеристикам:

  1. Наиболее заметными функциями являются CAMEO_DEUG_2015, HH_EINKOMMEN_SCORE, WEALTH, а наиболее заметными отрицательными характеристиками являются MOBI_REGIO, KBA13_ANTG1, KBA05_ANTG1. Итак, первый главный компонент связан с размером, достатком и типом семьи. Чем больше семья, тем более высокий компонент соответствует доходу и богатству. Отрицательные значения: компонент противоположен более высокой вероятности деления единиц с другими семьями и низкой мобильности.
  2. Наиболее заметными характеристиками являются KBA13_HERST_BMW_BENZ, KBA13_SEG_OBEREMITTELKLASSE, KBA13_MERCEDES, KBA13_BMW. Наиболее заметными отрицательными характеристиками является KBA13_SITZE_5. Эта составляющая связана с владением дорогими автомобилями.
  3. Наиболее заметными функциями являются GENERATION_DECADE, CJT_TYP_1, CJT_TYP_2, FINANZ_SPARER. Наиболее заметными отрицательными характеристиками являются KOMBIALTER и CJT_TYP_5. Этот компонент связан с возрастом, клиентской и финансовой типологией. Более высокий компонент относится к более высокой вероятности того, что люди будут более старшего возраста и будут экономить деньги.

Кластеризация K-средних

Метод Локоть был использован для определения идеального количества кластеров для кластеризации k-средних на данных, преобразованных методом PCA. Среднее значение суммы квадратов ошибок (SSE) внутри кластера было нанесено на график зависимости от количества кластеров от 1 до 30. На этом графике кластеризация была создана с использованием метода MiniBatchKmeans с размером пакета = 40000.

График показывает, что оценка быстро уменьшалась для первых 16 кластеров, затем увеличивалась для 17 кластеров, а затем продолжала снижаться для большего количества кластеров, но с меньшим наклоном. Итак, 16 кластеров были выбраны в качестве идеального числа для кластеризации k-средних.

Конвейер неконтролируемого машинного обучения

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

cluster_pipeline = конвейер ([
('преобразование', ct),
('pca', PCA (n_components = 175)),
('kmeans', KMeans (n_clusters = 16))
])

cluster_pipeline.fit (azdias_cleaned)
general_predictions = cluster_pipeline.predict (azdias_cleaned) customers_predictions = cluster_pipeline.predict (customers_cleaned)

К данным AZDIAS были применены методы подбора и прогнозирования, а к данным КЛИЕНТОВ - метод прогнозирования.

Сравнение данных CUSTOMERS с данными AZDIAS

Результаты кластеризации генеральной совокупности и данных AZDIAS сравнивались друг с другом с использованием соотношения людей в каждой группе.

Сравнение пропорций людей и разницы пропорций между общей аудиторией и аудиторией клиентов в каждом кластере (customers_ratio - general_ratio) показывает, что есть кластеры с перепредставлением, а также недопредставленностью клиентов. Кластеры с наибольшей положительной разницей в соотношении клиентов и общей аудитории чрезмерно представлены в данных о клиентах (заинтересованные кластеры №6 и №8). Кластеры с наибольшей отрицательной разницей в соотношении клиентов и общей аудитории недостаточно представлены в данных о клиентах (нет кластеров интересов № 0 и № 7). Их кластерные центры, которые находятся в скрытых чертах, были сопоставлены с исходными чертами, чтобы идентифицировать типы людей.

Итак, люди, которые пользуются услугами компании по доставке по почте (№6 и №8), состоятельны, им 45–60 лет (ALTERSKATEGORIE_GROB = ~ 3,4) со средним десятилетним поколением 60-х годов (GENERATION_DECADE = 6.1, 6.6 соответственно), экономят деньги или инвесторы с высоким уровнем дохода. вероятность (FINANZ_SPARER = 1.3 и 1.6 соответственно). В недостаточно представленном кластере они отличаются высокими доходами (LP_STATUS_GROB = 4) и низкими доходами (1,2 и 2,3). У этих людей низкая подвижность (MOBI_REGIO = 4.2). Эти люди также религиозны и придерживаются традиционных взглядов (функция SEMIO).

Также есть некоторая разница между двумя чрезмерно представленными кластерами в таких категориях, как D19_GESAMT_DATUM (8,2 против 2,8), D19_KINDERARTIKEL (0,6 против 2,2), D19_VERSAND_DATUM (9,0 против 3,3), D19_KONSUMTYP_MAX (6,1 против 2,1). Не все перечисленные функции были предоставлены с описанием, но общие функции D19_ * связаны с частотой использования определенной группы продуктов. Таким образом, в методе выделены две группы с высокой и низкой транзакционной активностью.

С другой стороны, недопредставленные в компании люди - до 45 лет (ALTERSKATEGORIE_GROB = 1.8 и 1.9). Эти люди родились в 80-х и 90-х годах (GENERATION_DECADE = 8.6) и имеют низкий финансовый интерес (FINANZ_MINIMALIST = 1 и 2). Эти люди бедны, они экономят деньги с очень низкой вероятностью (FINANZ_SPARER ›3.9). Один из кластеров продемонстрировал, что у этих людей высокий уровень движения (MOBI_REGIO = 1,9), что означает, что они не владеют домом, а другой - средний образец движения (MOBI_REGIO = 3,8). Эти люди с большей вероятностью обладают чувственным складом ума; и воинственные и традиционные настроенные с очень малой вероятностью.

Модель обучения с учителем

Теперь мы готовы проанализировать набор данных MAILOUT и построить модель контролируемого обучения, способную предсказать, станет ли человек клиентом. Каждая из строк в файлах данных «MAILOUT» представляет человека, на которого была направлена ​​рассылка, со столбцом «RESPONSE». Примечательно, что только ~ 1,2% набора данных MAILOUT_TRAIN - это клиенты. Здесь были применены аналогичный конвейер преобразования и очистки, за исключением того, что строки не были отброшены, чтобы избежать потери информации (используйте атрибут test_set = True в функции clean_data).

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

  • разделить набор данных на набор для обучения и проверки
  • использовать метод перекрестной проверки

Я решил работать с перекрестной проверкой, потому что клиентов всего 532 (1,2%). В случае разделения набора данных это значение будет уменьшено на 20%. Итак, я использую 5-кратную перекрестную проверку (по умолчанию в версии Scikit-learn 0.2) для получения кривых обучения и параметризации модели с помощью GridSearchCV.

Контур обучения с учителем

Был создан конвейер контролируемого обучения, состоящий из двух шагов: преобразователя столбцов, представленного ранее, и классификатора.

pipeline = Pipeline ([
(«преобразование», ct),
(«классификатор», классификатор)
])

pipeline.fit (maiout_train_cleaned)
прогнозы = pipeline.predict_proba (maiout_train_cleaned)

Классификаторы

Несколько методов ансамбля были протестированы с параметрами по умолчанию, чтобы выбрать лучший классификатор. Ансамблевое обучение - это метод построения модели поверх других моделей. Классификатор случайного леса, классификатор Adaboost и классификатор повышения градиента в Scikit-learn - все это ансамблевые классификаторы, построенные на основе модели дерева решений (по умолчанию).
Эти ансамблевые модели отлично подходят как для классификации, так и для задач регрессии, и в целом имеют следующие преимущества:

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

Оценка классификатора
Для оценки модели использовался метод кривой обучения. Кривая обучения показывает оценку валидации и обучения оценщика для различного количества обучающих выборок от 10% до 100% обучающих данных. Это инструмент, позволяющий узнать, насколько мы выигрываем от добавления дополнительных обучающих данных и страдает ли оценщик больше от ошибки дисперсии или ошибки смещения.

Анализ кривых обучения показал, что классификатор случайного леса имеет небольшую ошибку в наборе поездов (оценка roc_auc = 53%), что означает, что модель плохо соответствует данным. Ошибка в наборе проверки (оценка roc_auc = 53%) огромна, это модель с высоким смещением. Обратите внимание, что кривые уже сходятся, и добавление дополнительных данных не улучшит классификатор. Это модель с большим уклоном.

Adaboost Classifier демонстрирует лучшую производительность. Хотя оценка roc_auc обучения уменьшается до 84% с увеличением размера обучающей выборки, она увеличивается для набора проверки до 72%. Две кривые почти сходятся, и оценка существенно не улучшится с увеличением количества точек в обучающей выборке.

Оценка проверки Gradient Boosting Classifier увеличивается до 76%, а оценка обучения снижается до 92%. Две кривые не сходятся, и добавление большего количества очков может улучшить результат еще больше. Итак, повышение градиента является оптимальной моделью и будет использоваться в параметризации GridSearch.

Параметризация классификатора

Параметризация классификатора повышения градиента была выполнена с помощью поиска по сетке. Grid Search проверяет все возможные комбинации указанных гиперпараметров с помощью перекрестной проверки, а затем выбирает модель с максимальной оценкой (roc_auc) в наборе проверки. Ниже представлена ​​инициализация конвейера повышения градиента с различными гиперпараметрами, протестированными при поиске по сетке.

gbc_pipeline = sml.make_pipeline (ct, GradientBoostingClassifier ())

параметры = {‘classifier__learning_rate’: [0.1, 0.2], ‘classifier__n_estimators’: [100], ‘classifier__max_depth’: [3, 5], ‘classifier__min_samples_split’: [2, 4]}

grid_obj = GridSearchCV (gbc_pipeline, parameters, scoring = ‘roc_auc’)

Лучший классификатор имеет следующие гиперпараметры: learning_rate = 0,1, n_estimators = 100, дерево решений max_depth = 3 и дерево решений min_sample_split = 4 (по умолчанию = 2). Оценка, рассчитанная по обучающей выборке с использованием параметризованной модели, незначительно выше, чем у модели по умолчанию (0,8976 против 0,8968).

График важности функций показывает, что наиболее важной функцией является D19_SOZIALES, описание которой, к сожалению, недоступно. Следующие важные характеристики относятся к типу потребления (D19_KONSUMTYP_MAX) и году движения EINGESOGENAM_HH_JAHR (информация недоступна).

Конкурс Kaggle

Наконец, к данным MAILOUT_TEST была применена контролируемая модель. Полученные вероятности быть клиентом были представлены на конкурс Kaggle. Итоговая оценка составляет 0,789, что всего на 0,009 ниже, чем у текущего победителя.

Выводы

В этом проекте, предоставленном партнерами Udacity из Bertelsmann Arvato Analytics, были проанализированы реальные демографические данные о населении и клиентском сегменте Германии.

  • В первой части была проведена оценка и предварительная обработка данных. Эта часть была одним из самых сложных шагов, которые нужно было сделать, чтобы продолжить, потому что нужно было проанализировать 366 столбцов, и не все из них имели описание. Выявлено множество пропущенных значений и недостающей информации об атрибутах. Был создан конвейер трансформации колонны, который в дальнейшем использовался в контролируемых и неконтролируемых частях.
  • В неконтролируемой части уменьшение размерности с помощью PCA было выполнено до 175 скрытых функций, которые описывают 92% объясненной дисперсии. Кластеризация KMeans до 16 кластеров позволила выявить 2 кластера, которые являются целевыми клиентами компании. Это традиционно мыслящие обеспеченные люди в возрасте 45–60 лет.
  • Наконец, был выбран и параметризован классификатор Gradient Boosting Classifier для построения контролируемой модели и прогнозирования на основе тестового набора данных на KAGGLE. В результате производительность алгоритма обучения с учителем составила 78,9%.

В этом проекте потенциально есть некоторые улучшения. Например, есть другие способы предварительной обработки данных: выбрать другой порог для отбрасывания строк и столбцов, выбрать разные преобразования для столбцов, применить MinMax Scaler вместо Standard Scaler, вменять данные другим способом.

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

Наконец, уловка, которую я хотел бы попробовать, - это случайное добавление данных из набора данных CUSTOMERS в набор данных MAILOUT_TRAIN таким образом, чтобы количество клиентов и не клиентов было равным. Поскольку теперь у нас только 1,2% клиентов в этом наборе данных, модель, обученная на наборе данных с 50% -ным процентом, может быть гораздо лучшим предсказателем.