<jupyter_start><jupyter_text>Titanic: Machine Learning from Disaster  1. Definição do Problema de Negócio O RMS Titanic foi um luxuoso navio de passageiros britânico, na qual sua construção começou no ano de 1909 e foi concluída em 1911, sendo estimada em 7,5 milhões de dólares. O navio tinha 269 metros de comprimento, 28 metros de largura e 53 metros de altura. Operava com uma tripulação de 892 pessoas e poderia levar até 2435 passageiros, distribuídos em três classes. ![800px-Titanic_Starboard_View_1912.gif](attachment:800px-Titanic_Starboard_View_1912.gif) O návio foi projetado para ser o mais luxuoso e seguro da sua época, recebendo inclusive a fama de ser "inafundável". Porém, no ano de 1912, colidiu com um iceberg e, posteriormente, acabou nafragando. Seu naufrágio teve causas naturais e humanas, sendo que matou 1502 pessoas de um total de 2224 passageiros. Um dos motivos pelos quais o naufrágio causou muitas perdas de vida, foi a falta de botes salva-vidas suficientes para os passageiros e tripulantes. Embora a sorte estivesse envolvida na sobrevivência das pessoas, alguns grupos de tinham mais probabilidade de serem salvos do que outras, como mulheres, crianças e primeira classe do navio.   Objetivo Primeiramente será feita uma análise de quais variáveis tiveram uma maior influência na sobrevivência das pessoas. Após a análise dos dados, será proposto um modelo, na qual será responsável por fazer uma previsão de sobrevivência para um passageiro qualquer.  2. Obtenção dos Dados Os dados estão disponibilizados na plataforma do kaggle https://www.kaggle.com/c/titanic/data e estão divididos em dois grupos. - Dataset de treino (train.csv) : Usado para a construção do modelo de Machine Learning. Neste conjunto de dados, é informado se o passageiro sobreviveu ou não - Dataset de teste (test.csv) : Usado como dados que o modelo não conhece. Não é informado se o passageiro sobreviveu ou não.<jupyter_code># Importando os módulos
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline
# Importando os dados
train = pd.read_csv('data/train.csv')
test = pd.read_csv('data/test.csv')<jupyter_output><empty_output><jupyter_text>3. Análise Exploratória dos Dados  Identificando cada variável - PassengerId: Número de identificação do passageiro- Survived: Informa se o passageiro sobreviveu ao desastre        0 = Não        1 = Sim- Pclass: Classe do bilhete        1 = 1ª Classe        2 = 2ª Classe        3 = 3ª Classe- Name: Nome do passageiro- Sex: Sexo do passageiro- Age: Idade do passageiro- SibSp: Quantidade de cônjuges e irmãos a bordo- Parch: Quantidade de pais e filhos a bordo- Ticket: Número da passagem- Fare: Preço da Passagem- Cabin: Número da cabine do passageiro- Embarked: Porto no qual o passageiro embarcou        C = Cherbourg        Q = Queenstown        S = Southampton<jupyter_code># Número de registros (linhas) e features (colunas) 
print('Registros: {}\nFeatures: {}'.format(train.shape[0], train.shape[1]))
# Nome das features
train.columns
# Tipo das features
train.dtypes<jupyter_output><empty_output><jupyter_text>Tipos de cada variável - Categóricas        Pclass        Name        Survived        Sex        Embarked        Ticket        Passengerld        Cabin- Numéricas        - Discretas            SibSp            Parch        - Contínuas            Age            Fare             A variável 'class' é também a nossa variável target, uma vez que queremos prever a probabilidade de um passageiro sobreviver ou não.<jupyter_code># Primeiras colunas do dataset de treino
train.head()<jupyter_output><empty_output><jupyter_text>Dados missing<jupyter_code># Informações sobre os dados
train.info()
print('-' * 50)
test.info()
# Porcentagem de dados de treino faltantes
((train.isnull().sum() / train.shape[0]) * 100).sort_values(ascending=False)<jupyter_output><empty_output><jupyter_text>A variável Cabin possui o maior número de dados missing, 77%. Na sequência, a coluna Age possui quase 20% de dados missing, seguida pela coluna Embarked, que possui menos de 1%.<jupyter_code># Porcentagem de dados de teste faltantes
((test.isnull().sum() / test.shape[0]) * 100).sort_values(ascending = False)<jupyter_output><empty_output><jupyter_text>Novamente a variável Cabin lidera, com 78%. Seguida pela variável Age (20%) e pela variável Fare, com menos de 1%.  Distribuição Estatística dos Dados<jupyter_code>train.describe()
# Histograma das variáveis numéricas
train.hist(figsize = (16,12))<jupyter_output><empty_output><jupyter_text>Grupos de pessoas com mais chances de sobreviver<jupyter_code># Probabilidade de sobrevivência pelo sexo do passageiro
train[['Sex', 'Survived']].groupby(['Sex']).mean().sort_values(by = 'Survived', ascending = False)
# Probabilidade de sobreviência pela classe do passageiro
train[['Pclass', 'Survived']].groupby(['Pclass']).mean().sort_values(by = 'Survived', ascending = False)
# Probabilidade de sobrevivência pelo porto de embarque do passageiro
train[['Embarked', 'Survived']].groupby(['Embarked']).mean().sort_values(by = 'Survived', ascending = False)
# Plotar os gráficos para Survived x Sex, Pclass e Embarked

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize = (12,4))
sns.barplot(x = 'Sex', y = 'Survived', data = train, ax = ax1)
sns.barplot(x = 'Pclass', y = 'Survived', data = train, ax = ax2)
sns.barplot(x = 'Embarked', y = 'Survived', data = train, ax = ax3)<jupyter_output><empty_output><jupyter_text>Através do gráfico acima conseguimos extrair duas suposições. A primeira é de que o sexo feminino possui muito mais chances de sobrevivência do que em relação ao sexo masculino (75% x 18%). A segunda conclusão refere-se a variável Pclass, na qual os passageiros da primeira classe são os que possuem mais chance de sobrevivência, seguidos pelos da segunda classe e, por fim, os passageiros da terceira classe.<jupyter_code># Probabilidade de sobrevivência do passageiro pela quantidade de cônjugues e irmãos 
train[['SibSp', 'Survived']].groupby(['SibSp']).mean().sort_values(by = 'Survived', ascending = False)
# Probabilidade de sobrevivência pela quantidade de pais e filhos
train[['Parch', 'Survived']].groupby(['Parch']).mean().sort_values(by = 'Survived', ascending = False)<jupyter_output><empty_output><jupyter_text>Analisando a probabilidade de sobrevivência pelas variáveis SibSp e Parch, notamos que tais fatores, a princípio, não possuem uma contribuição significativa na sobrevivência dos passageiros.<jupyter_code># Influência da idade na probabilidade de sobrevivência
age_survived = sns.FacetGrid(train, col = 'Survived')
age_survived.map(sns.distplot, 'Age')<jupyter_output><empty_output><jupyter_text>Analisando a distribuição da idade dos sobreviventes, percebe-se que o comportamento dos gráficos são parecidos. Porém, no gráfico dos sobrevivente, nota-se um leve pico para as crianças pequenas. Esse detalhe confirma a hipótese de que mulheres e crianças possuem maior chance de sobrevivência.<jupyter_code># Combinando as variáveis Pclass, Age e Survived em um plot
grid = sns.FacetGrid(train, col = 'Survived', row = 'Pclass')
grid.map(plt.hist, 'Age', bins = 20)<jupyter_output><empty_output><jupyter_text>A partir dos gráficos acima podemos tirar algumas conclusões.- A Pclass 3 foi a classe com o maior número de passageiros e também a que teve o maior número de não sobreviventes.- Em todas as classes crianças tiveram um número considerável de sobreviventes.- A Pclass 1 foi a classe com o menor número de passageiros, porém foi a que teve o maior número de sobreviventes.<jupyter_code># Correlação e heatmap para as variáveis numéricas
correlation = train.corr()
sns.heatmap(correlation, cmap = 'Reds', annot = True)
# Análise descritiva das variáveis categóricas
train.describe(include = ['O'])<jupyter_output><empty_output><jupyter_text>Algumas considerações:- O sexo masculino é o de maior frequência- O porto na qual tiveram mais embarques foi o de Southamptom- As variáveis Cabin e Embarked contém valores missing  4. Preparação dos Dados  Juntando os dados de treino e de teste<jupyter_code># Salvando os índices dos datasets para recupreração posterior
train_id = train.shape[0]
test_id = test.shape[0]

# Salvando a coluna PassengerId para enviar ao kaggle
passengerId = test['PassengerId']

# Extraindo a variável target ('Survived') e excluindo ela do dataset de treino
target = train.Survived.copy()
train.drop(['Survived'], axis = 1, inplace = True)

# Concatenando os datasets de treino e teste para um únido DataFrame
df = pd.concat([train, test], axis = 0).reset_index(drop = True)
# Shape dos dados
df.shape<jupyter_output><empty_output><jupyter_text>Selecionando as features De acordo com a análise exploratória realizada, vamos desconsiderar as variáveis PassegerId, Name, Ticket e Cabin, uma vez que não parecem serem relevantes para as previsões.<jupyter_code>df.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis = 1, inplace = True)
# Variáveis restantes
df.columns<jupyter_output><empty_output><jupyter_text>Valores missing<jupyter_code>df.isnull().sum()
# Porcentagem de dados faltantes
((df.isnull().sum() / df.shape[0]) * 100).sort_values(ascending=False)
# Tratamento dos valores missing

# Age
age_median = df['Age'].median()
df['Age'].fillna(age_median, inplace = True)

# Fare
fare_median = df['Fare'].median()
df['Fare'].fillna(fare_median, inplace = True)

# Embarked
embarked_top = df['Embarked'].value_counts()[0]
df['Embarked'].fillna(embarked_top, inplace = True)<jupyter_output><empty_output><jupyter_text>Para o tratamento das variáveis Age e Fare foi aplicado a mediana. Já para a variável Embarked, aplicou-se o valor com maior frequência.  Feature Engineering<jupyter_code># Convertendo a variável 'Sex' em 0 (masculino) e 1 (feminino)
df['Sex'] = df['Sex'].map({'male':0, 'female':1})
# Criando Dummy Variables para Embarked
embarked_dummy = pd.get_dummies(df['Embarked'], prefix = 'Embarked')
df = pd.concat([df, embarked_dummy], axis = 1)
df.drop('Embarked', axis = 1, inplace = True)
df.head()<jupyter_output><empty_output><jupyter_text>Nesta etapa do processo é preciso rrealizar a conversão das variáveis categóricas em numérica, para que os modelos consigam compreende-las. Para a variável Sex, foi aplicado o valor 0 para as pessoas masculinas e 1 para as femininas. Já para a variável Embarked, foi aplicado o conceito de variáveis dummy.  Separando os dados de treino e teste<jupyter_code>train = df.iloc[:train_id]
test = df.iloc[train_id:]<jupyter_output><empty_output><jupyter_text>5. Modelagem e Avaliação Agora estamos prontos para treinar o modelo e prever a solução necessária. Para isto, vamos utilizar algoritmos de Classificação e Regressão para que possamos investigar as relações existentes entre a variável target (Survived) e as outras features selecionadas. Essa categoria de Machine Learning chama-se Aprendizado Supervisionado, pois estamos treinando nosso modelo com um determinado conjunto de dados. Para avaliar a performance dos nossos modelos será utilizada a métrica da acurácia. Modelos utilizados:- Logistic Regression- KNN - K-Neighbors- SVM - Suport Vector Machine- Decision Tree- Random Forest<jupyter_code># Decision Tree

from sklearn.tree import DecisionTreeClassifier

# Criando e treinando o modelo
decision_tree = DecisionTreeClassifier()
decision_tree.fit(train, target)

# Acurácia
acc_tree = round(decision_tree.score(train, target) * 100, 2)

print('Acurácia do modelo da Árvore de Decisão: {}'.format(acc_tree))
# Logistic Regression

from sklearn.linear_model import LogisticRegression

# Criando e treinando o modelo
log_reg = LogisticRegression()
log_reg.fit(train, target)

# Acurácia
acc_log_reg = round(log_reg.score(train, target) * 100, 2)

print('Acurácia do modelo de Regressão Logística: {}'.format(acc_log_reg))
# KNN

from sklearn.neighbors import KNeighborsClassifier

# Criando e treinando o modelo
knn = KNeighborsClassifier()
knn.fit(train, target)

# Acurácia
acc_knn = round(knn.score(train, target) * 100, 2)

print('Acurácia do modelo KNN: {}'.format(acc_knn))
# SVM

from sklearn.svm import SVC

# Criando e treiando o modelo
svm = SVC()
svm.fit(train, target)

# Acurácia
acc_svm = round(svm.score(train, target) * 100, 2)

print('Acurácia do modelo SVM: {}'.format(acc_svm))
# Random Forest

from sklearn.ensemble import RandomForestClassifier

# Criando e treinando o modelo
random_forest = RandomForestClassifier()
random_forest.fit(train, target)

# Acurácia
acc_random_forest = round(random_forest.score(train, target) * 100, 2)

print('Acurácia do modelo Random Forest: {}'.format(acc_random_forest))
# Rankind dos modelos

models = pd.DataFrame({'Model':['Logistic Regression', 'KNN','SVM', 'Decision Tree', 'Random Forest'],
                       'Score':[acc_log_reg, acc_knn, acc_svm, acc_tree, acc_random_forest]})

models.sort_values(by = 'Score', ascending = False).reset_index(drop = True)<jupyter_output><empty_output><jupyter_text>6. Submission to Kaggle<jupyter_code># Submission Random Forest

# Previsões
Y_pred = random_forest.predict(test)

# Dataframe submission
submission = pd.DataFrame({
    'PassengerId': passengerId,
    'Survived': Y_pred
})

# Arquivo csv
submission.to_csv('./submission_random_forest', index = False)
# Submission Decision Tree

# Previsões
Y_pred = decision_tree.predict(test)

# Dataframe submission
submission = pd.DataFrame({
    'PassengerId': passengerId,
    'Survived': Y_pred
})

# Arquivo csv
submission.to_csv('./submission_decision_tree', index = False)
# Submission Logistic Regression

# Previsões
Y_pred = log_reg.predict(test)

# Dataframe submission
submission = pd.DataFrame({
    'PassengerId': passengerId,
    'Survived': Y_pred
})

# Arquivo csv
submission.to_csv('./submission_log_reg', index = False)
# Submission KNN

# Previsões
Y_pred = knn.predict(test)

# Dataframe submission
submission = pd.DataFrame({
    'PassengerId': passengerId,
    'Survived': Y_pred
})

# Arquivo csv
submission.to_csv('./submission_knn', index = False)
# Submission SVM

# Previsões
Y_pred = svm.predict(test)

# Dataframe submission
submission = pd.DataFrame({
    'PassengerId': passengerId,
    'Survived': Y_pred
})

# Arquivo csv
submission.to_csv('./submission_svm', index = False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09096612296110414, 'fraction_numerical': 0.010246758678377248, 'mean_word_length': 5.311922569291685, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 73, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '49339', 'license': 'MIT', 'n_tokens_mistral': 5115, 'n_tokens_neox': 4883, 'n_words': 1555, 'path': 'titanic.ipynb', 'repo_name': 'otaviosanluz/titanic', 'size': '14346'}