from IPython.display import Image
Image(filename='titanic.jpeg', width=800, height=200)
O Titanic foi um navio construído na Irlanda, que naufragou quatro dias após sua viagem de inauguração em abril de 1912. Essa acidente é muito conhecido, ainda mais depois do lançamento do filme em 1997. Esse projeto visa criar um modelo a fim de predizer quem morreu e quem sobreviveu nesse desastre, com base no Dataset do Titanic do Kaggle.
Utilizaremos uma versão semi-limpa do dataset e o modelo de Regressão Logística para classificar os que morreram e os que sobreviveram.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
train = pd.read_csv('titanic_dataset.csv')
train.head()
train.describe()
train.info()
Esse dataset de treino conta com 891 entradas, e segundo esse resultado acima já verificamos que há dados faltantes. Vejamos de forma mais clara no heatmap abaixo:
sns.heatmap(train.isnull(), cmap='viridis')
Cerca de 20% dos dados de idade estão faltando. A proporção de idade que falta é provavelmente pequena o suficiente para que possamos fazer uma substituição razoável com alguma forma de imputação de dados. Olhando para a coluna Cabin, porém, parece que estamos perdendo muito desses dados para fazermos o mesmo. Provavelmente vamos descartar essa coluna na construção do modelo.
sns.set_style('whitegrid')
sns.countplot(x='Survived', data=train)
Vimos por esse gráfico que a maioria das pessoas morreram.
sns.set_style('whitegrid')
sns.countplot(x='Survived', hue= 'Sex',data=train)
Dentre as pessoas que morreram, a maioria é homem e entre as que sobreviveram a maioria é mulher. Isso corrobora com o que vimos no filme, onde mulheres e crianças tinha prioridade de embarca no barco salva vidas.
sns.set_style(style='whitegrid')
sns.countplot(x='Survived', hue='Pclass', data=train)
Por esse outro gráfico, vimos que a maioria das pessoas que morreram pertenciam a terceira classe, mas isso se deve pela maioria das pessoas pertenceram a essa classe, como vemos no gráfico seguinte.
sns.set_style('whitegrid')
sns.countplot(x='Pclass', data=train)
sns.distplot(train['Age'].dropna(), kde=False, color='darkblue', bins=30)
Com esse outro gráfico da idade dos passageiros, podemos ver que a maioria das pessoas tinham entre 20 e 30 anos.
sns.countplot(x='SibSp',data=train)
Por esse outro gráfico, podemos ver que a maioria das pessoas a bordo do Titanic estavam sozinhas, sem acompanhante.
Agora que já conhecemos melhor nossos dados, precisamos tratar os dados faltantes. Comecemos pela idade, se simplesmente excluirmos essas dados, perderemos muita informação importante. Por isso, uma forma de solucionarmos o problema é fazer uma média de todos os passageiros de acordo com sua classe e preencher os dados faltantes.
plt.figure(figsize=(10,5))
sns.boxplot(x='Pclass', y='Age', data=train)
Esse boxplot nos mostra que as pessoas mais velhas estavam na primeira classe. E pela média, vamos preencher dados faltantes da primeira classe com 37 anos, de segunda classe com 29 anos e de terceira classe com 24 anos.
def add_age(cols):
age = cols[0]
pclass = cols[1]
if pd.isnull(age):
if pclass == 1:
return 37
elif pclass == 2:
return 29
elif pclass == 3:
return 24
else:
return age
# Aplicando a função
train['Age'] = train[['Age','Pclass']].apply(add_age, axis=1)
# Verificando se o tratamento para os dados da idade deu certo
sns.heatmap(train.isnull(), cmap='viridis')
Prontinho, agora não temos mais idade faltante!
Agora vamos deletar a coluna Cabin e a linha em Embarked que falta dado.
# Deletando a coluna Cabin
train.drop('Cabin', axis=1, inplace=True)
train.head()
# Deletando as linhas com dados faltantes em Embarked
train.dropna(inplace=True)
Como podemos ver, não temos mais dados faltantes, todas as linhas das 8 colunas possuem o mesmo tanto de valor.
Precisamos converter características categóricas em variáveis numérica
# Convertendo dados de Sexo e Local de embarcação
sex = pd.get_dummies(train['Sex'],drop_first=True)
embark = pd.get_dummies(train['Embarked'],drop_first=True)
# Excluindo do dataset as colunas que não vamos utilizar
train.drop(['Sex','Embarked','Name','Ticket'],axis=1,inplace=True)
train.info()
# Adicionando as novas colunas de sexo e local de embarcação
train = pd.concat([train,sex,embark],axis=1)
Vejamos agora como ficaram os dados que utilizaremos para a construção no modelo.
train.head()
# Importando biblioteca que splita os dados
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(train.drop('Survived',axis=1),
train['Survived'], test_size=0.30,
random_state=101)
# Importando o módulo de Regressão Logística
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_train,y_train)
# Coeficientes
logreg.coef_
predictions = logreg.predict(X_test)
from sklearn.metrics import classification_report
print(classification_report(y_test, predictions))
print('A acurácia do nosso modelo foi de: {:.2f}'.format(logreg.score(X_test, y_test)))
Matriz de confusão:
from sklearn.metrics import confusion_matrix
confusion_matrix = confusion_matrix(y_test, predictions)
print(['TP FP'])
print(confusion_matrix)
print(['FN TN'])