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

Я буду работать с данными конкурса на drivendata.org, на котором размещены данные из taarifa, API с открытым исходным кодом и Министерства водных ресурсов Танзании. Я продемонстрирую использование модели классификации случайного леса для выполнения тройной классификации функциональности водяных скважин.

Танзания переживает водный кризис. 1/3 территории - это засушливая пустыня, и доступ к чистой воде для жителей, которые не живут рядом с одним из трех крупных озер на границе страны, очень ограничен. Загрязнение в значительной степени не регулируется, и многие люди прибегают к питьевой воде из загрязненных грунтовых вод. Кроме того, водяные насосы не работают большую часть времени. Людям нужна наша помощь!

Фреймворк OSEMN

Мы используем фреймворк OSEMN для организации этого проекта, так как его метод разумный и эффективный. Мы начинаем с импорта наших наборов данных, которые разделяются на обучающие значения (в данном случае наши предикторы), тестовые значения и целевую переменную «status_group» только для обучающего набора. «Status_group» состоит из трех классифицирующих значений:

[«функциональный», «нефункциональный», «функциональный, требующий ремонта»]

Очистка наших данных

Ради соревнований мы выполнили pd.merge для всех трех таблиц, чтобы мы могли очистить тестовые значения, а затем отделить их от набора для прогнозов тестового набора.

Мы начинаем очищать наш набор данных от пропущенных значений, вводя некоторые пропущенные значения и удаляя избыточные столбцы данных (для которых на этот раз их было слишком много: например, «количество» и «группа_количества», «управление» и «группа_управления» и т. Д. ) все эти пары имели примерно одинаковые значения.

Функции, которые мы исключили, включали 4 из 9 столбцов для местоположения, включая долготу и широту, каждый с разной степенью специфичности местоположения. Мы сохранили «регион», «код_района», «lga», «широту» и «долготу» на тот случай, если в некоторых районах по какой-либо причине может произойти поломка скважинного насоса.

Одну функцию мы легко разработали, преобразовав «date_recorded» (дата записи данных) в тип «дата-время», а затем вычтя год на «год постройки» и создав новый столбец «Возраст скважины».

Для логических столбцов мы вменяли нулевые / пропущенные значения соотношением значений, которые у нас были, чтобы сохранить потенциальные отношения. Например, у «public_meeting» было 4155 пропущенных значений.

После всей очистки и удаления повторяющихся и ненужных функций у нас осталось всего 25 столбцов!

Следующий шаг после очистки меня немного сбивает с толку по следующей причине: из-за характера прогнозного моделирования все входные данные должны быть числовыми. То есть не строковое значение / объект / обычное слово. Тем не менее, мы хотим, чтобы наши данные были тактичными, чтобы мы могли выполнить некоторый исследовательский анализ (EDA), чтобы прочувствовать наши данные и понять их природу и связь с целевой переменной функциональной «status_group». Так что я оставил категорические сделки после EDA.

Изучение наших данных

Давайте зададим несколько вопросов по нашей проблеме:

Связано ли местоположение с хорошей функциональностью?

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

Имеет ли вода_качество какое-либо отношение к работе насоса?

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

Имеет ли (pump) extract_type какое-либо отношение к «status_group»?

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

Работа с категориальными данными и высокой мощностью

Как мы упоминали перед EDA, мы должны преобразовать все наши категориальные данные в числовые, иначе наша модель вернет ошибки. Сначала я рассматривал возможность использования pd.factorize для каждого столбца, что полезно для преобразования значений объекта / строки в числовое представление массива, когда все, что имеет значение, - это идентификация отдельных значений. Однако для модели машинного обучения это портит ситуацию, потому что модель неверно интерпретирует каждое возрастающее число как имеющее больший вес. В нашем случае у нас есть масса совершенно уникальных ценностей. Например, гравитационная экстракция не зависит от погружной добычи. Эти два совершенно уникальны.

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

Одной из таких уникальных колонн является «установщик», который представляет собой группу из 2370 установщиков скважинных насосов в Танзании. Мы не хотим полностью отказываться от этого на всякий случай, если здесь есть какая-то модельная ценность. Вместо этого мы собираемся объединить все установщики с наименьшими значениями value_counts в «unknown» (уже есть большое количество отсутствующих / NaN значений) и оставить 4 самых больших для однократного горячего кодирования.

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

Мне пришлось серьезно погуглить, чтобы найти рабочее решение для этого

Показано ниже:

Успех! Сейчас для установщика есть только 5 уникальных значений, большинство из которых «неизвестны», но, по крайней мере, у нас есть наибольшее количество установщиков, не избавляющихся от потенциально ценной информации. Объединенным таблицам назначается новый набор данных. Я делаю это для остальных столбцов категорий / объектов, которые я горячо кодирую, в качестве контрольной точки на всякий случай.

Конечный результат категориальных отношений дает нам большой набор данных из 69 столбцов.

Моделирование со случайным лесом

Сначала мы назначаем нашим обучающим столбцам «X», а нашему целевому столбцу «status_group» - «y». Затем мы разделили наши данные на отдельные обучающие и тестовые наборы с размером теста по умолчанию 25% данных. Это позволяет нам обучить модель случайного леса на большинстве данных и зарезервировать 25% для проверки достоверности этой модели.

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

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

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

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

Общая точность при 0,802 = 80,2%. Не так уж плохо! Однако, похоже, что «функциональная потребность в ремонте» плохо спрогнозирована с точностью до 50%, что означает, что 50% скважин, которые были помечены как нуждающиеся в ремонте, действительно нуждаются в ремонте. Напомним, что хуже - 32%, из всех колодцев, нуждающихся в ремонте, мы правильно пометили 32%. Однако более важно то, что мы более точно прогнозируем полностью нефункционирующие скважины, потому что люди не могут получить воду из этих насосов. Давайте попробуем еще раз с нашими данными повторной выборки:

Наша передискретизированная точность оказалась на 1% ниже, точность ухудшилась из-за необходимости ремонта, а отзывчивость улучшилась на 8%. Точность нефункциональных провалов на 1%. Если бы «функциональная потребность в ремонте» была более серьезной проблемой, чем полностью нефункциональная, то эта модель была бы лучшей, однако нефункциональная более важна.

Давайте попробуем настроить нашу исходную модель, реализовав GridSearchCV, и посмотрим, сможем ли мы вообще повысить эту точность, изменив следующее:

max_depth: глубина дерева

min_samples_split: минимальное количество выборок, необходимых для разделения внутреннего узла в дереве решений

критерий: качество раскола, примесь Джини и «энтропия» получения информации.

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

На этот раз мы оставим max_depth разгуляться, снизив min_samples_split с критерием энтропии.

После двух попыток сужения мы получили немного улучшенную модель!

… На 1%. Но это лучше, чем наша базовая модель, что дает нам общую точность 0,8096 с лучшим min_samples_split из 7 образцов.

Построим матрицу неточностей для этой модели:

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

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

Наша модель случайного леса говорит нам, что широта и долгота имеют наибольшее значение, затем возраст колодца, gps_height и количество воды, перекачиваемой насосом. Используя этот случайный лес, мы можем лучше всего предсказать работоспособность колодцев в Танзании с точностью 81% - хорошая рабочая команда !!

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

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