</center> Автор материала: программист-исследователь Mail.ru Group, старший преподаватель Факультета Компьютерных Наук ВШЭ Юрий Кашницкий. Материал распространяется на условиях лицензии Creative Commons CC BY-NC-SA 4.0. Можно использовать в любых целях (редактировать, поправлять и брать за основу), кроме коммерческих, но с обязательным упоминанием автора материала.
Заполните код в клетках и выберите ответы в веб-форме.
Соревнование Kaggle "Titanic: Machine Learning from Disaster".
In [1]:
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import roc_auc_score, accuracy_score, confusion_matrix
%matplotlib inline
from matplotlib import pyplot as plt
import seaborn as sns
Функция для формирования csv-файла посылки на Kaggle:
In [2]:
def write_to_submission_file(predicted_labels, out_file, train_num=891,
target='Survived', index_label="PassengerId"):
# turn predictions into data frame and save as csv file
predicted_df = pd.DataFrame(predicted_labels,
index = np.arange(train_num + 1,
train_num + 1 +
predicted_labels.shape[0]),
columns=[target])
predicted_df.to_csv(out_file, index_label=index_label)
Считываем обучающую и тестовую выборки.
In [3]:
train_df = pd.read_csv("../data/titanic_train.csv")
test_df = pd.read_csv("../data/titanic_test.csv")
In [4]:
y = train_df['Survived']
In [5]:
train_df.head()
Out[5]:
In [6]:
train_df.describe(include='all')
Out[6]:
In [7]:
test_df.describe(include='all')
Out[7]:
Заполним пропуски медианными значениями.
In [8]:
train_df['Age'].fillna(train_df['Age'].median(), inplace=True)
test_df['Age'].fillna(train_df['Age'].median(), inplace=True)
train_df['Embarked'].fillna('S', inplace=True)
test_df['Fare'].fillna(train_df['Fare'].median(), inplace=True)
Кодируем категориальные признаки Pclass
, Sex
, SibSp
, Parch
и Embarked
с помощью техники One-Hot-Encoding.
In [9]:
train_df = pd.concat([train_df, pd.get_dummies(train_df['Pclass'],
prefix="PClass"),
pd.get_dummies(train_df['Sex'], prefix="Sex"),
pd.get_dummies(train_df['SibSp'], prefix="SibSp"),
pd.get_dummies(train_df['Parch'], prefix="Parch"),
pd.get_dummies(train_df['Embarked'], prefix="Embarked")],
axis=1)
test_df = pd.concat([test_df, pd.get_dummies(test_df['Pclass'],
prefix="PClass"),
pd.get_dummies(test_df['Sex'], prefix="Sex"),
pd.get_dummies(test_df['SibSp'], prefix="SibSp"),
pd.get_dummies(test_df['Parch'], prefix="Parch"),
pd.get_dummies(test_df['Embarked'], prefix="Embarked")],
axis=1)
In [10]:
train_df.drop(['Survived', 'Pclass', 'Name', 'Sex', 'SibSp',
'Parch', 'Ticket', 'Cabin', 'Embarked', 'PassengerId'],
axis=1, inplace=True)
test_df.drop(['Pclass', 'Name', 'Sex', 'SibSp', 'Parch', 'Ticket', 'Cabin', 'Embarked', 'PassengerId'],
axis=1, inplace=True)
В тестовой выборке появляется новое значение Parch = 9, которого нет в обучающей выборке. Проигнорируем его.
In [11]:
train_df.shape, test_df.shape
Out[11]:
In [12]:
set(test_df.columns) - set(train_df.columns)
Out[12]:
In [13]:
test_df.drop(['Parch_9'], axis=1, inplace=True)
In [14]:
train_df.head()
Out[14]:
In [15]:
test_df.head()
Out[15]:
Обучите на имеющейся выборке дерево решений (DecisionTreeClassifier
) максимальной глубины 2. Используйте параметр random_state=17
для воспроизводимости результатов.
In [16]:
tree = DecisionTreeClassifier(max_depth=2, random_state=17)
tree.fit(train_df, y)
Out[16]:
Сделайте с помощью полученной модели прогноз для тестовой выборки
In [17]:
predictions = tree.predict(test_df)
Сформируйте файл посылки и отправьте на Kaggle
In [18]:
write_to_submission_file(predictions,
'titanic_tree_depth2.csv')
Вопрос 1. Каков результат первой посылки (дерево решений без настройки параметров) в публичном рейтинге соревнования Titanic?
У такой посылки результат на публичной тестовой выборке - 0.74641.
In [19]:
export_graphviz(tree, out_file="../img/titanic_tree_depth2.dot",
feature_names=train_df.columns)
!dot -Tpng ../img/titanic_tree_depth2.dot -o ../img/titanic_tree_depth2.png
Вопрос 2. Сколько признаков задействуются при прогнозе деревом решений глубины 2?
Обучите на имеющейся выборке дерево решений (DecisionTreeClassifier
). Также укажите random_state=17
. Максимальную глубину и минимальное число элементов в листе настройте на 5-кратной кросс-валидации с помощью GridSearchCV
.
In [20]:
# tree params for grid search
tree_params = {'max_depth': list(range(1, 5)),
'min_samples_leaf': list(range(1, 5))}
locally_best_tree = GridSearchCV(DecisionTreeClassifier(random_state=17),
tree_params,
verbose=True, n_jobs=-1, cv=5)
locally_best_tree.fit(train_df, y)
Out[20]:
In [21]:
export_graphviz(locally_best_tree.best_estimator_,
out_file="../img/titanic_tree_tuned.dot",
feature_names=train_df.columns)
!dot -Tpng ../img/titanic_tree_tuned.dot -o ../img/titanic_tree_tuned.png
In [22]:
print("Best params:", locally_best_tree.best_params_)
print("Best cross validaton score", locally_best_tree.best_score_)
Вопрос 3. Каковы лучшие параметры дерева, настроенные на кросс-валидации с помощью GridSearchCV
?
Вопрос 4. Какой получилась средняя доля верных ответов на кросс-валидации для дерева решений с лучшим сочетанием гиперпараметров max_depth
и min_samples_leaf
?
Сделайте с помощью полученной модели прогноз для тестовой выборки.
In [23]:
predictions = locally_best_tree.predict(test_df)
Сформируйте файл посылки и отправьте на Kaggle.
In [24]:
write_to_submission_file(predictions, 'titanic_tree_tuned.csv')
Вопрос 5. Каков результат второй посылки (дерево решений с настройкой гиперпараметров) в публичном рейтинге соревнования Titanic?