VDS за 300р от нашего партнера SpaceWeb
[3]
04 Июл 2020, 15:47

Kaggle Titanic Competition: построение моделей и тюнинг на Python

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

Общие сведения

  • Библиотека импорта
  • Подготовка кадров обучающих и тестовых данных
  • Матрица Коэффициентов Корреляции
  • Создать Вспомогательную Функцию: Статистика Выходной Модели
  • Множественные приспособленные модели и самая лучшая подходящая модель
  • Создайте вспомогательную функцию: выведите рейтинг важности функции RF
  • Выбор объектов со случайной важностью лесных объектов, важностью перестановок и иерархической кластеризацией
  • RandomizedSearchCV: Random Forest Classifier
  • GridSearchCV: Random Forest Classifier
  • Conclusion: Latest Results & Final Thoughts

Import Libraries

import numpy as np 
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inlinefrom sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC, LinearSVC
from sklearn.naive_bayes import GaussianNBfrom sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import RandomizedSearchCV, GridSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score, recall_score, roc_auc_score

Подготовка Train & Test Data Frames

Используя Pandas, я импортировал файлы CSV как фреймы данных. Для обучения модели я начал с 17 функций, как показано ниже, включая Survived и PassengerId.

train_df = pd.read_csv(‘file/path/data-train.csv’)
test_df = pd.read_csv(‘file/path/data-test.csv’)
 

Матрица коэффициента корреляции

В качестве первого шага я создал парную корреляционную матрицу, используя функцию corr, встроенную в Pandas и Seaborn для визуализации данных. Он рассчитывает коэффициенты корреляции Пирсона (линейные отношения) в качестве метода по умолчанию. Я также использовал методы Спирмена и Кендалла, которые доступны в pandas.DataFrame.corr. Все результаты выглядели одинаково по всем направлениям. Условно говоря, метод ранг-корреляции Спирмена может быть лучшим здесь без углубления в понятие корреляции и ассоциации для различных типов признаков. Одно предостережение заключается в том, что Спирмен будет относиться к номинальным характеристикам как к порядковым.

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

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

Я сгенерировал тепловую карту коэффициента корреляции и обратил внимание на значения в диапазоне корреляции от 0,75 до 1,00 с использованием цветовой шкалы. Я обвел области на тепловой карте, которые привлекли мое внимание (всего семь кругов).

train_corr = train_df.corr(method='pearson')
plt.figure(figsize=(18, 12))
sns.set(font_scale=2)
sns.heatmap(train_corr, cmap='magma')

Корреляционная Матрица Пирсона

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

  • между pclass и cabin_level,
  • между is_woman_child и сексом,
  • между тарифом и fare_bucket,
  • между возрастом и age_bucket, и
  • между is_one_family и family_size.

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

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

train_corr = train_df.corr(method='pearson')
plt.figure(figsize=(18, 12))
sns.set(font_scale=1.4)
sns.heatmap(train_corr, 
            annot=True, 
            linecolor=’white’, 
            linewidths=0.5, 
            cmap=’magma’)
 

Корреляционная Матрица Пирсона
 

Создать вспомогательную функцию: статистика выходной модели

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

Кроме того, я определил объект конвейера (строка 27 ниже), содержащий масштабировщик и экземпляр оценщика. Я не масштабирую X_train и X_test в нескольких случаях при использовании случайного леса, потому что в этом нет необходимости. Однако для некоторых моделей (например, градиентных оценок) без надлежащего масштабирования конвергенция оценок может быть замедлена, а также предотвращена.

 

Многофункциональные модели и модели наилучшего соответствия

Вспомогательная функция имеет три параметра. Во-первых, ему нужен словарь с именем модели (строка) в качестве ключа и экземпляром класса модели в качестве значения. Во-вторых, он нуждается в наборе данных для обучения функции (X_train) и, наконец, в данных целевого класса (y_train). Давайте посмотрим на результаты!

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

При ближайшем рассмотрении оценки точности с использованием перекрестной проверки с Kfold, равным 10, позволили получить более реалистичные оценки: 84,07% для случайного леса и 81,3% для дерева решений. Другие модели, которые также выделялись, были KNN, SVM, логистическая регрессия и линейный SVC со всеми респектабельными показателями. Высокое стандартное отклонение указывает на модель, которая может плохо обобщаться с новыми данными, поэтому я также обратил на это внимание.

Давайте внимательнее посмотрим на точность и вспомним. В этом случае имело смысл максимизировать как точность, так и отзыв, и высокий показатель Ф1 будет свидетельствовать об этом. Хотя существует компромисс между точностью и отзывом, относительно высокая точность [TP / (TP + FP)] дает мне точность положительных прогнозов, тогда как относительно высокая степень отзыва [TP / (TP + FN)] дает мне% фактических положительных результатов, правильно обнаруженных модель. Напомним также известен как True Positive Rate (TPR) и чувствительность. Кроме того, я хотел высокий AUC под кривой ROC. В результате я сузил свой список до четырех моделей — случайный лес, KNN, логистическая регрессия и линейный SVC.

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

 

 

Создайте вспомогательную функцию: выведите рейтинг важности функции RF

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

Выбор объекта с учетом важности объекта RF, важности перестановок и иерархической кластеризации

Итерация 1

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

X_train = train_df.drop([“survived”, “passengerid”], axis=1)
y_train = train_df[“survived”]
X_test = test_df.drop([“passengerid”], axis=1)rf_base = RandomForestClassifier(n_estimators=100, random_state=0)
rf_base.fit(X_train, y_train)n = len(X_train.columns)
importance_scores = rf_base.feature_importances_
rf_feature_ranking(n, importance_scores)

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

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

На данный момент меня беспокоит коллинеарность. В результате я использую важность перестановок и иерархическую кластеризацию, чтобы определить, какие функции актуальны. Концептуально, по важности перестановки, он вычисляет базовую точность для объектов, используя набор проверки. Затем он переставляет все значения для одного столбца / объекта и измеряет изменение относительно базовой точности, используя набор тестовых данных. Это будет повторяться для каждой функции.

 

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

Для иерархической кластеризации, ось Y на дендрограмме представляет близость или различие. По мере приближения к 0, чем ближе расстояние между кластерными объектами и, таким образом, указывается корреляция / ассоциация. В этой итерации я исследовал все кластеры, попавшие под 1,5 — произвольный порог. 

 

Дендрограмма слева и матрица корреляции Спирмена справа
Используя дендрограмму, я более внимательно посмотрел на более мелкие кластеры с двумя характеристиками (например, pclass и cab_level) и эвристически определил, какие функции, возможно, нужно отбросить. Я решил отбросить возраст, потому что он очень коллинеарен с age_bucket и это непрерывная функция. Кроме того, я решил отказаться от секса и платы за проезд, потому что их взаимосвязанные функции будут в равной степени способствовать модели. В результате в следующей итерации было отброшено 7 функций: возраст, пол, стоимость проезда, is_alone, is_mix_group и is_one_family
Рассчитать особенность и важность перестановки
 
Генерация иерархических кластеров и матрицы корреляции Спирмена

Итерация 2

Давайте посмотрим на обновленные результаты. В этой итерации я работал с 9 функциями, которые представляют новые X_train и X_test.

 

X_train.info()

Я использовал функцию output_model_stats для сравнения метрик производительности с исходными метриками случайного леса. Метрики итерации 2 привязаны к индексу «rf_base — итерация 2». В целом модель выполнена чуть менее эффективной, чем модель со всеми функциями. Скорее всего, первая модель случайного леса была переоснащением (относительно низкий уклон и высокая дисперсия) и не должна вызывать беспокойство на данном этапе.

 

 
Имейте в виду, что X_train содержит только 9 функций, как показано выше.

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

 

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

Подобное логическое мышление упало на age_bucket после наблюдения того, как высоко он ранжируется по сравнению с pclass и is_woman_child, используя важность перестановки. В то же время, cost_bucket и age_bucket коррелировали друг с другом. Интуиция подсказывала мне, что при сохранении этих характеристик это, скорее всего, уменьшит смещение и увеличит дисперсию. Следовательно, эффективность модели для обобщения новыми данными будет снижена.

 

Как показывает дендрограмма, первый кластер слева под 0.5 состоит из pclass и cab_level. Расстояние между pclass и cab_level очень близко, и матрица корреляции Спирмена показывает, что они коррелированы. Я не решался отбросить либо pclass, либо is_woman_child, потому что обе функции показали высокую корреляцию с выживанием пассажиров во время моего поискового анализа.

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

Итерация 3

На этом этапе обновленные наборы данных X_train и X_test содержат 5 функций, которые, как я понял, наиболее актуальны.

 

X_train.info()

Затем я вывел показатели производительности («rb_base — Итерация 3») и сравнил с предыдущими результатами. Precision_cv_score был выше, чем предыдущие две итерации. Точность немного улучшилась, что означало, что больше истинных положительных результатов (TP) были обнаружены среди всех положительных результатов (TP + FP), обнаруженных моделью. Это был хороший знак. Напоминание немного снизилось, как и ожидалось, что означало, что способность модели обнаруживать истинные положительные результаты (TP) среди фактических истинных положительных результатов (TP + FN) немного снизилась. Счет F1 улучшился после итерации 2, и AUC под кривой ROC поднялся до нового максимума.

 

 

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

 

 

Я вывел предсказанный y_test (y_pred_base), используя обученную модель с X_test. Я создал свой файл представления и отправил его в Kaggle. Я смог набрать 80,382% точности с этим представлением. Я думаю, что это довольно респектабельная оценка.

rf_base = RandomForestClassifier(n_estimators=100, random_state=0)
rf_base.fit(X_train, y_train)
y_pred_base = rf_base.predict(X_test)df_output = pd.concat([test_df[‘passengerid’], y_pred_df], axis=1, sort=False)
df_output = df_output.rename(columns={“passengerid”: “PassengerId”})
df_output.to_csv(‘gender_submission.csv’, index=False)
 

RandomizedSearchCV: классификатор случайных лесов

странице документации Scikit-Learn. Приятно знать подход Python к ООП. Объекты класса модели в Scikit-Learn содержат параметры, атрибуты и методы.

«Параметры оценщика, используемого для применения этих методов, оптимизируются путем перекрестного проверки настроек параметров.

В отличие от GridSearchCV, проверяются не все значения параметров, а фиксированное число настроек параметров, взятых из указанных распределений. Количество настроек параметров, которые пробуются, дается n_iter.

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

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

Случайные лесные гиперпараметры

  • n_estimators: представляет количество деревьев решений в лесу. Значение по умолчанию установлено в n_estimators = 100.
    критерий: эта функция измеряет качество разделения. Например, age — это функция, которая может быть корневым узлом. Основываясь на критериях разделения, он разделяется на внутренние и конечные узлы, пока рост дерева не будет остановлен, когда для ветви будет достигнута самая низкая примесь Джини (по умолчанию установлено значение Джини, а второй вариант — энтропия для получения информации).
  • max_features: количество случайных подмножеств объектов, которые следует учитывать при поиске наилучшего разделения.
  • max_depth: максимальная глубина дерева. Если None, то узлы расширяются до тех пор, пока все листья не станут чистыми или пока все листья не будут содержать менее чем
  • min_samples_split: минимальное количество выборок, необходимое для разделения внутреннего узла.
  • min_samples_leaf: минимальное количество выборок, которое требуется для конечного узла. Точка разделения на любой глубине будет учитываться только в том случае, если она оставляет не менее min_samples_leaf обучающих выборок в каждой из левой и правой ветвей.

RandomizedSearchCV Parameters

  • estimator: экземпляр класса модели, используемый для проведения рандомизированного поиска лучших параметров.
  • param_distributions: словарь с именами параметров (str) в качестве ключей и распределений или списками параметров, которые нужно попробовать.
  • n_iter: количество настроек параметров, которые выбираются.
  • cv: Определяет стратегию разделения перекрестной проверки.
  • verbose: контролирует многословие; чем больше число подробностей, тем дольше выводятся / регистрируются сообщения.
  • random_state: Состояние генератора псевдослучайных чисел, используемое для случайной равномерной выборки из списков возможных значений вместо распределений scipy.stats.
  • n_jobs: количество заданий, запускаемых параллельно. None означает 1, если только в контексте joblib.parallel_backend означает использование всех процессоров.
 

Рандомизированный поиск занял около 5 минут, используя всю мощность моего процессора (n_jobs = -1). Param_distributions содержит в общей сложности 8 232 комбинации настроек (7 * 2 * 2 * 7 * 7 * 6). Для моего рандомизированного поиска я установил cv в 5, что равно количеству стратифицированных Kfolds. Поэтому, если бы я начал с GridSearchCV, было бы опробовано в общей сложности 41 160 настроек или подгонок параметров. Это займет очень много времени, чтобы бежать. Однако, с RandomizedSearchCV, он выбирает n_iter = 200 из всех возможных настроек и, таким образом, уменьшает количество задач или подгонок до 1000 в этом случае. Вот лучшие значения гиперпараметра из этого рандомизированного поиска.

 

best_params_ attribute of RandomizedSearchCV
 

Установив verbose = 3, вы получите хороший вывод о том, что происходит.

Давайте сравним результаты моих предыдущих запусков. Precision_cv_score увеличился примерно на 1,1%, а precision_cv_stddev снизился примерно до 4%. Показатель точности также улучшился (91,47%), в то время как отзыв немного снизился. Общая оценка F1 улучшилась. Показатель AUC оставался стабильным на уровне 89%. Теперь, используя то, что я узнал до сих пор, цель состоит в том, чтобы запустить поиск по сетке с меньшим набором настроек и измерить приращения.

 

 

GridSearchCV: классификатор случайных лесов

GridSearchCV похож на RandomizedSearchCV, за исключением того, что он будет выполнять исчерпывающий поиск на основе определенного набора гиперпараметров модели (param_grid в GridSearchCV). Другими словами, он пройдет все 41 160 посадок сверху. Тем не менее, я использую полученные ранее знания и сокращаю список значений для каждого гиперпараметра. Подробный обзор параметров GridSearchCV можно найти на странице документации.

“Параметры оценщика, используемого для применения этих методов, оптимизируются путем перекрестной проверки сетки поиска по сетке параметров.”

 

best_params_ attribute from GridSearchCV
 

verbose=3

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

 

 

В качестве последнего шага я сгенерировал обновленный файл представления и отправил его в Kaggle. Даже с настройкой гиперпараметра моя оценка осталась на уровне 80,382% для этого набора функций и этого набора оптимизированных гиперпараметров.

Выводы

Последние результаты

Благодаря методам проб и ошибок, а также расширению настроек гиперпараметра мне удалось достичь текущего постоянного показателя 80,861%, который, по словам Кэггла, попадает в верхние 6%. На мой взгляд, это довольно солидный счет.

 

Последние мысли

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

Пожалуйста, не стесняйтесь делиться своими комментариями, отзывами и / или вопросами. Если вы заинтересованы в исследовательском анализе и разработке функций этого проекта, ознакомьтесь с моей первой статьей “ «Kaggle Titanic Competition in SQL«. Спасибо за чтение!

 

Ресурсы

Я рекомендую эти три книги, если вы ищете хорошие справочники по машинному обучению, анализу данных и улучшению своих навыков программирования на Python.

Комментарии (0)

Добавить комментарий

Войдите, чтобы написать о чем-нибудь...
Вход Регистрация
Web.onRails
Здесь вы можете спросить или написать обо всём, что касается Веб-разработки.
написать о чем-нибудь...
Метки:
Лучшее
[52]
16 Окт 2011, 15:38
Вывести все элементы POST
[просмотров 12493]
[74]
31 мая 2011, 11:48
Python проверка существования переменной
[просмотров 8692]
[4]
10 Окт 2018, 15:33
Как запретить просмотр сайта по IP?
[просмотров 8510]
[100]
19 Дек 2014, 16:16
User-agent для Internet Explorer 11
[просмотров 7250]
[124]
21 Июл 2011, 14:04
Python Imaging Library (PIL)
[просмотров 6517]
[58]
29 мая 2012, 12:08
Узнать версию PHP из командной строки
[просмотров 4774]
[315]
16 Июл 2011, 20:03
Python работа с MySQL
[просмотров 4677]

Вести с Хабра