Проект Udacity DataScience Nanodegree Capestone

Введение

В этом проекте Арвато Бертельсманн предоставляет реальные оперативные данные, описывающие население Германии, и набор данных о клиентах, представляющих клиентов компании AZ Direkt, занимающейся доставкой по почте.

Цель состоит в том, чтобы идентифицировать клиентов AZ Direkt среди населения в целом и создать модель, которая предсказывает, может ли человек превратиться в клиента.

Для этого я буду использовать KMeans. KMeans — это метод кластеризации — алгоритм обучения без учителя — для создания сегментов клиентов. В отличие от иерархической кластеризации время выполнения KMeans линейно зависит от количества данных, а не квадратично. Из-за огромного количества данных я решил использовать KMeans.
Сопоставляя KMeans с демографическими данными и прогнозируя кластеры как для населения Германии, так и для клиентов, я ожидаю, что в данных о клиентах будут кластеры с гораздо большей долей людей, чем в демографических данных (признак того, что эти люди лица, представляющие интерес), и кластеры с меньшей долей людей (что указывает на то, что эти люди не представляют интереса для компании).

Но прежде чем применить этот метод к данным, я использую анализ основных компонентов (PCA), чтобы уменьшить размеры набора данных. С одной стороны, это оптимизирует время выполнения KMeans, с другой стороны, этот метод вычисляет так называемые собственные векторы. Собственный вектор — это вектор, содержащий веса для каждого признака. Эти веса описывают, насколько релевантная функция увеличивает этот компонент. Путем сортировки абсолютных значений в таком векторе характеристики можно суммировать в так называемую «скрытую характеристику», которая дает более общее описание людей, которых можно описать. (Ниже приведен пример обсуждения латентного признака, описывающего пенсионеров, которым нравится водить спортивные автомобили).

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

Описание проблемы

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

Как компания, занимающаяся доставкой по почте, заинтересованными лицами являются те, у кого есть подключение к Интернету и адрес электронной почты. Один из лучших способов привлечь внимание — рассылка по электронной почте. Но отправлять электронное письмо каждому человеку в мире «очень неэффективно» и не очень хорошая идея. Таким образом, список адресованных лиц должен состоять из тех лиц, у которых вероятность стать клиентом › 0.

Но как определить потенциальных клиентов?
AZ Direct и Arvato Financial Solutions предоставляют следующие данные:

Атрибуты DIAS — значения 2017.xlsx
описание атрибутов и их значений

Информационные уровни DIAS — Attributes 2017.xlsx
описание атрибутов без их значений

Udacity_AZDIAS_052018.csv
основные клиенты AZ Direct (около 191 600 человек, 366 столбцов (функции)

Udacity_CUSTOMERS_052018.csv
население Германии (примерно 900 000 человек)

Udacity_MAILOUT_052018_TRAIN.csv
файл ответа кампании, содержащий те же столбцы плюс один столбец, содержащий информацию о том, стал ли человек клиентом

Udacity_MAILOUT_052018_TEST.csv
последние, но не менее важные файлы, описывающие некоторые атрибуты в предоставленных наборах данных.

Используя эти файлы, я сделаю:

1. Обработка данных

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

2. Сегментация клиентов
Используйте PCA для уменьшения размеров исходных данных, используйте KMeans для сегментации/группировки клиентов и используйте метод локтя для определения наилучшего количества кластеров и описания целевых кластеров.

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

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

4. Конкурс Kaggle

Загрузите результаты конкурса Kaggle.

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

Метрики

Объект PCA имеет реализованную функцию оценки и обеспечивает вероятностную интерпретацию для каждого компонента. Эти значения хранятся в атрибуте «explained_variance_ratio_» и представляют собой величину дисперсии, которую каждый компонент объясняет относительно исходного набора данных.
Чтобы определить требуемое количество основных компонентов, я установлю минимальный предел (минимальный % исходных данных, которые я намереваюсь объяснить с помощью компонентов), переберу все значения объяснения_дисперсии_отношения_ и остановлюсь до тех пор, пока сумма не станет больше или равна мой лимит. С этим номером PCA будет снова соответствовать данным.

Показатели регрессии, такие как средняя ошибка, среднеквадратическая ошибка и т. д., нельзя использовать, поскольку у нас есть проблема бинарной классификации в контролируемой части.
Для классификации есть такие показатели, как Precison-Recall, ROC_AUC, Log-Loss, но мы будем использовать кривую ROC_AUC.

AUC_ROC означает «Площадь под кривой рабочих характеристик приемника». ROC отображает частоту истинных положительных результатов в зависимости от частоты ложных положительных результатов с различными пороговыми значениями, а площадь под этой кривой описывает точность модели, поскольку максимальная площадь составляет 1x1. Идеальный классификатор создает точку в верхнем левом углу (100% правильный прогноз с 0 ложными срабатываниями). Чем хуже модель, тем ближе к диагонали.

В отличие от Log-Loss, F1-Score и Accuracy, ROC_AUC не зависит от порогового значения, установленного для классификации. Прогнозируемые абсолютные значения не имеют значения, учитываются ранги прогнозов.

Обработка данных

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

Из-за этого огромного количества функций, описаний и так далее у меня было много идей, как подготовить данные. Отбрасывал старые идеи, пробовал новые… Но в какой-то момент пришлось остановиться, потому что я бежал в цейтноте и нужно было просто свой подход. Неполное описание было еще одним фактором.
Мой первый подход состоял в том, чтобы «обобщить» столбцы, чтобы уменьшить набор данных. Например (COL_1_2 = max(COL_1, COL_2) по оси X). Я оказался в одном горячем кодировании порядковых данных, и это было глупо (как я уже сказал, бегая по кругу, теряя нить). Я решил отказаться от этого подхода и начать новый.

Итак, я извлекаю предоставленную информацию из файлов MS Excel.

Затем я проверяю, есть ли какие-либо недокументированные значения в тех столбцах, значения которых описаны, и есть ли 6 признаков. Значение 6 в MODTEMP неизвестно, 0 в других столбцах. Поскольку они не задокументированы, я заменяю их на nan.

Я не хочу обращать внимание на то, что какое-либо значение может быть строкой, поэтому я обрабатываю столбцы объекта следующим образом:

удалите столбец «CAMEO_DEU_2015», поскольку каждое значение из 44 значений в этом столбце представляет собой уникальное значение («Кофе Райдер», «Окно во двор», «Мантаплатте»)

отбросить «LNR» (LNR означает «laufende Nummer» и является индексной функцией)

одногорячее кодирование OST_WEST_KZ (0 = Восток, 1 = Запад)

инженер новые функции от CAMEO_INTL_2015, LP_LEBENSPHASE_GROB и PRAEGENDE_JUGENDJAHRE:
CAMEO_INTL_2015_Ages,

CAMEO_INTL_2015_Wealth LP_LEBENSPHASE_GROB_Household

LP_LEBENSPHASE_GROB_Income PRAEGENDE_JUGENDJAHRE_Ost

PRAEGENDE_JUGENDJAHRE_West PRAEGENDE_JUGENDJAHRE_MainAvant
PRAEGENDE_JUGENDJAHRE_Возраст.

Моя первая модель была очень плохой. При одной попытке оптимизации я намеревался интерпретировать значение 0 = «транзакция неизвестна» как значение ОТСУТСТВУЕТ для столбцов D19. Так что теперь есть еще несколько столбцов, которые будут удалены.
Я также удалил столбцы PLZ8, потому что PLZ=Postleitzahl (почтовый индекс) 8xxxx означает München (Мюнхен), Gütersloh находится в Nordrhein-Westphalen (Северный Рейн-Вестфалия). и я не видел никакого преимущества в сохранении этих функций.

После этого я решил изменить порядок значений, потому что я буду использовать PCA и хочу легко интерпретировать результаты.
Например, функции FINANZ* означают 1 = очень высокое, 5 = очень низкое, тогда как функции KB*, как правило, очень скорее всего, если значение высокое. Если функция FINANZ* имеет большое влияние, я бы хотел видеть ее в положительном, а не в отрицательном направлении.

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

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

Применение PCA

PCA нашел N векторов, которыми можно описать исходные данные. Вектор является главным компонентом и равен собственному вектору матрицы данных. Каждая запись в собственном векторе представляет функцию. Чем выше абсульт, тем выше функция управляет этим компонентом (имея большое влияние на направление ПК/векторов).

Я намеревался описать 95%. Итерация по «explained_variance_ratio_» и суммирование значений приводит к 249 компонентам, которые необходимы для описания 95% данных.

Например, третья главная компонента (индекс 2):

Кажется, это те люди, у которых есть дорогие автомобили (скорее всего, это будут спортивные автомобили, потому что этот компонент говорит о том, что очень маловероятно, что эти автомобили имеют пять или четыре места), двигатели в этих автомобилях, как правило, огромные (более 2500 см3) и максимальное скорости, как правило, превышают 250 км, а не ограничиваются 210 км/ч, очень маловероятно, что этим людям, как правило, меньше 30 лет, им, как правило, больше 60, производители автомобилей Opel, Ford и Азиатско-Тихоокеанского региона редко присутствуют.

Кластеризация

Преобразованные данные PCA теперь имеют размерность dim_origin_rows * 249 основных компонентов. Теперь в этом «облаке данных» мы пытаемся найти оптимальные центры с минимальным расстоянием до всех точек, относящихся к кластеру, чтобы сегментировать людей.

Я использовал MiniBatchKMeans и нашел первый минимум с индексом 5 (обозначает 7 кластеров, потому что начинать с 0 или 1 кластера бессмысленно). Чтобы найти оптимальное количество кластеров, я намеревался реализовать этот метод https://www.linkedin.com/pulse/finding-optimal-number-clusters-k-means-through-elbow-asanka-perera/, но решил продолжайте с 14 кластерами, так как на графике ниже может быть виден изгиб.

KMiniBatchScore показывает отрицательное значение (в документации используется слово «Противоположный», и мне потребовалось время, чтобы понять, что имеется в виду «отрицательное») значения X в задаче KMeans, а цель KMeans — уменьшить сумму квадратов. расстояний точек от соответствующих центроидов кластеров.

Коэффициент силуэта рассчитывается как: (b — a) / max(a, b), где b = среднее расстояние до ближайшего кластера, а a = среднее расстояние внутри кластера.
Значения около -1 указывают на плохую модель,
значения, близкие к 1, указывают на хорошую модель,
значения, близкие к 0, указывают на перекрывающиеся кластеры.

Используя KMeans, установленный на преобразованных демографических данных PCA с 14 кластерами, пришло время очистить набор данных о клиентах, как ранее набор данных azdias, спрогнозировать кластеры для клиентов и сравнить размеры кластеров.

Кластеры с индексами 0, 3 являются перепредставленными, 6, 10, 12 почти равны, все остальные недопредставлены. Я выбрал некоторые особенности, демонстрирующие различия в недопредставленных и перепредставленных кластерах:

Итак, мой вывод:

Клиенты, похоже, в большей степени являются финансовыми инвесторами, а не финансовыми минималистами (более 60% в 5-м кластере), а скорее сберегают деньги.
Это согласуется с тем фактом, что FINANZTYP_2, 5 почти отсутствуют, а 0 и 3 преобладают. Им, как правило, больше 45 лет.
ALTERSKATEGORIE закодировано одним горячим кодом, и тот факт, что 3/4 составляют более 0,35 и 0,58, означает, что этим людям, как правило, больше 45, а скорее всего 60 (PRAEGENDE_JUGENDJAHRE_Ages центральная точка составляет 6,3462783537449665 в исходных данных (не данных PCA)). Наконец, они живут в регионах с низкой скоростью передвижения.

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

Модель под наблюдением

Те же шаги предварительной обработки были применены к Udacity_MAILOUT_052018_TRAIN/~TEST.csv. Данные поезда используются для обучения контролируемой модели, тестовые данные используются или для оценки модели на соревнованиях kaggle.

Взглянув на соответствующий столбец, мы ясно видим, что данные несбалансированы. Только 1,24% откликнулись на кампанию.

Я решил использовать ансамблевые методы, потому что они объединяют разные модели в одну. Хороший пример, который я читал, был следующим: предположим, что вы больны, а болезнь неизвестна, вы бы предпочли обратиться к одному врачу, который является профессионалом в одной области, или вы бы предпочли обратиться к группе врачей, где каждый является профессионалом в своей области? собственное ремесло?
В этом заключается идея ансамблевых методов. EM использует разные классификаторы во время обучения, и будут использоваться те классификаторы, которые обладают наибольшей точностью. Это означает, что ансамблевые методы

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

Базовая модель, на которой построены RandomForest/Adaboost/GradientBoosting-Classifiers, — это деревья решений. Их можно использовать как для регрессии, так и для необходимой здесь классификации.
Помимо этих трех моделей я добавил логистическую регрессию, потому что меня интересовала эта производительность.

Метрика, которая будет использоваться, — ROC_AUC (как обсуждалось выше).

Для оценки модели я использую Learning_curve из scikitlearn, потому что данные разбиваются n раз на обучающие и тестовые данные, а затем для обучения и подсчета баллов используются подмножества разного размера.

Моя первая подготовка данных была недостаточно хороша, и модели не могли делать хороших прогнозов. RandomForestClassifier был переобучен, «лучшей» моделью стал GradientBoostClassifier с ‹ 60%.

Для улучшения этих результатов существует библиотека под названием imblearn module, которая предоставляет технику SMO (SMOTE = Synthetic Minority Over-sampling Technique) для создания экземпляров недопредставленных классов, как описано здесь http://rikunert.com/SMOTE_explained. . Но графики вызвали у меня скептицизм, потому что результаты обучения и теста почти не различались для всех моделей.

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

Линейная регрессия основана на байесовской теории независимых вероятностей. Этот алгоритм предполагает, что каждая функция независима от других и что P(x|y) = P(x) * P(y). Как мы видим, только это предположение, примененное к данным, может набрать до 65%, но это не оптимальная модель.

RandomForestClassifier состоит из набора некоррелированных деревьев решений, и эта модель полностью переобучена. Оценка обучения составляет почти 100%, но оценка обучения составляет +- 50% для каждой итерации.

Лучшие модели — AdaBoost/GradientBoost-Classifier. Эти два метода являются ансамблевыми. EM использует разные классификаторы во время обучения, и будут использоваться те классификаторы, которые обладают наибольшей точностью. Это означает, что ансамблевые методы:

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

Разница между AdaBoost и GradientBoost заключается в том, как создаются слабые ученики. Слабые ученики — это простые модели, которые позже будут объединены в хороший классификатор.

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

Наконец, я обучил GradientBoostClassifier с помощью GridSearchCV и параметров n_estimators = [20, 50, 100], max_depth = [3, 5, 7] и min_samples_split = [2, 4, 8]. Тренировка состояла из 54 подходов, по 3 раза на каждого из 18 кандидатов.

Взглянув на важность функций первой и второй модели, можно увидеть явные различия. D19_Soziales был удален ранее из-за моего ограничения на удаление столбцов с более чем 20% отсутствующих значений, которое я увеличил до 30%.
Раньше я интерпретировал D19_LETZTER_KAUF_BRANCHE_UNBEKANNT как неизвестный и заменял их на nan. В результате этот столбец также был удален. Теперь в топ-40 важных функций входят 7 столбцов с горячим кодированием из D19_LETZTER_KAUF_BRANCHE.

Применив свой второй подход к тестовым данным, я увеличил свой результат на 18%.

Вывод

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

Исследование данных (сравнение населения Германии с клиентами)

Предварительная обработка данных
Как я узнал здесь, правильная интерпретация и обработка признаков — это альфа и омега. Прежде чем я обрабатывал значение D19 0 = нет транзакции, известной как 0, теперь как nan, ранее D19_LETZTER_KAUF_BRANCHE отбрасывался, теперь закодировано горячим способом, PLZ8 сохранен, теперь удален, …

Использование неконтролируемых методов обучения (PCA, KMeans) для рекомендаций

Сравнение основных кластеров

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

Исследование наиболее важной функции и сравнение ее между целевыми и нецелевыми

С помощью PCA удалось найти 249 собственных векторов, которые описывают данные до 90%, а 3 верхних компонента описывают:

  • первая интерпретация была такой: оседлые семьи с доходом выше среднего не имеют материальных проблем
    в связи с новой подготовкой данных это изменилось, «противоположное» теперь увеличивает компонент, а именно люди, которые могли бы не иметь достаточно денег, чтобы купить дом/квартиру/апартаменты, как правило, имеют более низкий доход и могут иметь финансовые проблемы, они финансовые минималисты.
  • люди, склонные к подготовке, 30–40 лет, с онлайн-близостью, но не являющиеся энтузиастами кросс-канала
  • пенсионеры, которые любят водить спортивные автомобили.

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

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

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

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

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

Одной из предлагаемых оптимизаций является использование AutoEncoder для уменьшения количества функций. Автокодировщик использует нейронную сеть, которая будет обучаться на основе входных данных. Скрытые слои описывают приведенные отношения, и Код будет результатом, который мы передаем KMeans.

В заключение я хотел бы поблагодарить Udacity, Arvato и AZ Direct за предоставление файлов, упомянутых выше, и, таким образом, за возможность улучшить свои навыки работы с данными.

И спасибо, что прочитали этот пост. Надеюсь, вам понравилось :)

Обсуждение проблемы

Я начал свою карьеру в качестве разработчика C# в 2010 году. С тех пор я так и не увлекся языками сценариев. Начав эту программу нано-степени, я начал изучать python, библиотеки, такие как pandas, scikitlearn, программы, такие как anaconda, jupyter. Я чувствую, что попал во все возможные ловушки. Я не хочу жаловаться, но обработка исключений и сообщения об ошибках в Python ужасны. Часто требовалось много времени, чтобы вообще понять проблему.

Программирование на Python, концепция «все является объектом» и концепция дескрипторов свойств для прикрепления свойств к классам «на лету», тот факт, что переменные могут быть созданы в операторе if/else, а затем могут использоваться вне этого… Для меня ужасная концепция. Я действительно не могу к этому привыкнуть.

Также простые вещи, такие как «как проверить, является ли «объект» нулевым», мне пришлось изучить и столкнуться с множеством ошибок… Обработка nan в пандах и типы данных… Надеюсь, что постепенно я пойму, как все работает. Но, честно говоря, мне нужно сделать свой собственный обзор и резюме всех изученных методов. И у меня все еще есть ощущение, что я, возможно, пропустил или просмотрел некоторые части.

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