15 апреля 1912 года Титаник столкнулся с айсбергом, в результате чего он затонул, что привело к гибели более 1500 человек. Это сделало его одним из самых смертоносных случаев затопления одиночного корабля. Мы попытаемся предсказать, выжил ли конкретный человек на Титанике или нет, используя 11 признаков о них. Для этого воспользуемся набором данных Титаник от Kaggle.

Импорт библиотек

Давайте сначала импортируем необходимые библиотеки. Если у вас не установлена ​​определенная библиотека, выполните команду 'pip install ‹package_name›', чтобы установить ее.

import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV

Загрузка данных

Мы скачали данные с Kaggle и разархивировали их в каталог с именем titanic. Давайте посмотрим, что осталось внутри каталога, в который мы распаковали данные.

for dirname, _, filenames in os.walk('./titanic'):
    for filename in filenames:
        print(filename)

Мы загрузим набор данных поезда и теста в нашу записную книжку.

train = pd.read_csv('./titanic/train.csv')
test = pd.read_csv('./titanic/test.csv')

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

Мы напечатаем заголовок train, чтобы увидеть, как выглядит набор данных.

train.head()

Мы распечатаем форму поезда и проверим наборы данных, чтобы увидеть их размеры.

print(train.shape)
print(test.shape)

Мы удалим столбцы 'PassengerId', 'Имя', 'Билет', 'Кабина', поскольку они не играют существенной роли в выживании человека.

train.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)
test.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)

Давайте теперь посмотрим на заголовок кадра данных train.

train.head()

Мы воспользуемся методом info() для просмотра такой информации, как ненулевые значения и типы данных для столбцов.

train.info()

Давайте теперь посмотрим статистику по числовым столбцам с помощью describe().

train.describe()

Теперь мы получим количество нулевых значений в каждом столбце.

train.isna().sum()

Визуализация данных

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

#Plotting null values heatmap
sns.heatmap(train.isnull(),yticklabels=False,cbar=False,cmap='viridis')

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

#Plotting correlation heatmap
corr = train.corr()
corr = corr.apply(abs)
plt.figure(figsize=(7,7))
map = sns.heatmap(corr,annot=True,cmap="RdYlGn")

Давайте посмотрим на процент выживших по сравнению с умершими, построив круговую диаграмму.

#Plotting the Pie chart
fig = plt.figure(figsize=(5,5))
colors = ["skyblue",'pink']
surv = train[train['Survived']==1]
died = train[train['Survived']==0]
ck = [surv['Survived'].count(),died['Survived'].count()]
piechart = plt.pie(ck,labels=["Survived","Died"],
autopct ='%1.1f%%',
shadow = True,
colors = colors,
startangle = 45,
explode=(0, 0.1))
train.Survived.value_counts()

Давайте посмотрим на распределение столбца Возраст с помощью гистограммы. Распределение выглядит перекошенным вправо.

sns.histplot(train['Age'].dropna())

Давайте посмотрим на распределение столбца Parch.

sns.histplot(train['Parch'].dropna(),bins=15)

Давайте посмотрим на распределение столбца Pclass.

sns.histplot(train['Pclass'].dropna(),bins=15)

Давайте посмотрим на распределение столбца "Тариф". Распределение выглядит перекошенным вправо.

sns.histplot(train['Fare'].dropna(),bins=20)

Давайте посмотрим на распределение столбца "Пол".

sns.countplot(train['Sex'].dropna())

Разработка функций

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

#Replacing null values by column mean
train['Age'].fillna(train['Age'].mean(),inplace=True)
test['Age'].fillna(test['Age'].mean(),inplace=True)

Теперь мы заменим 0 и пустые значения в столбце "Тариф" на среднее значение столбца.

#Replacing 0’s & nulls by column mean
train['Fare'] = train['Fare'].replace(0, train['Fare'].mean())
train['Fare'].replace('nan',np.nan,inplace=True)
train['Fare'].fillna(train['Fare'].mean(),inplace=True)
test['Fare'] = test['Fare'].replace(0, test['Fare'].mean())
test['Fare'].replace('nan',np.nan,inplace=True)
test['Fare'].fillna(test['Fare'].mean(),inplace=True)

Мы заменим пустые значения в столбце "Embarked" средним значением столбца.

#Replacing nulls by column mean 
train['Embarked'].replace('nan',np.nan,inplace=True)
train['Embarked'].fillna(train['Embarked'].mode()[0],inplace=True)
test['Embarked'].replace('nan',np.nan,inplace=True)
test['Embarked'].fillna(test['Embarked'].mode()[0],inplace=True)

Давайте напечатаем уникальные значения в столбце "Пол". Как вы можете видеть в выводе, в этом столбце есть 2 уникальных значения.

#Printing unique values in 'Sex' column
train['Sex'].unique()

Мы сопоставим категориальные значения в столбце "Пол" с числовыми значениями (0 и 1).

#Mappping categorical to numeric
train['Sex']=train['Sex'].map({'male':0,'female':1})
test['Sex']=test['Sex'].map({'male':0,'female':1})

Давайте напечатаем уникальные значения в столбцах Embarked. Как вы можете видеть в выводе, в этом столбце есть 3 уникальных значения.

#Printing unique values in 'Embarked' column
train['Embarked'].unique()

Мы снова сопоставим категориальные значения в этом столбце с числовыми значениями (0, 1, 2).

#Mappping categorical to numeric
train['Embarked']=train['Embarked'].map({'S':0,'C':1,'Q':2})
test['Embarked']=test['Embarked'].map({'S':0,'C':1,'Q':2})

Мы возьмем журнал столбца «Возраст» для обработки асимметрии.

#Handling skewness in 'Age' column
train['Age']=np.log(train['Age'])
test['Age']=np.log(test['Age'])

Мы также возьмем журнал столбца "Тариф".

#Handling skewness in 'Fare' column
test['Fare']=np.log(test['Fare'])
train['Fare']=np.log(train['Fare'])

Давайте удалим столбец "Выжил" из train и назначим его y. Это потому, что это целевой столбец.

#Dropping the 'Survived' column
x=train.drop(['Survived'],axis=1)
y=train['Survived']

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

#Splitting the data into train & test
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25,random_state=0)

Создание модели

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

#Defining the parameters to search within
param_grid = {
'n_estimators': range(6, 10),
'max_depth': range(3, 8),
'learning_rate': [.2, .3, .4],
'colsample_bytree': [.7, .8, .9, 1]
}
#Specifying our classifier
xgb = XGBClassifier()
#Searching for the best parameters
g_search = GridSearchCV(estimator = xgb, param_grid = param_grid,
cv = 3, n_jobs = 1, verbose = 0, return_train_score=True)
#Fitting the model using best parameters found
g_search.fit(x_train, y_train)
#Printing the best parameters found
print(g_search.best_params_)

Давайте рассчитаем оценку модели с помощью x_test и y_test.

#Calculating the model's score
g_search.score(x_test,y_test)

Делаем прогноз

Мы предскажем цель для фактических тестовых данных. Результатом является массив из 0 и 1. 1 означает, что человек выживет, а 0 означает, что человек умрет.

#Predicting the actual test data
g_search.predict(test)

Мы завершили предсказание выживания на Титанике. Если вам понравился этот урок, ставьте лайк!