Explorando o Dataset do Titanic para Machine Learning — Parte2

Michael Douglas Barbosa Araujo
6 min readApr 23, 2024

--

Caso não tenha visto a parte 1, recomendo a leitura.

Imagem do titanic com uma mistura de conceitos de IA

Aqui na segunda parte daremos continuidade em nossa exploração do DataSet do Titanic. A ideia é que, no final da série de posts, nós sejamos capazes de realizar uma análise e escolher o melhor algoritmo de machine learning para o nosso dataset. Nós iremos explorar os seguintes algoritmos:

  • DummyClassifier
  • LogisticRegression
  • DecisionTreeClassifier
  • KNeighborsClassifier
  • GaussianNB
  • SVC
  • RandomForestClassifier
  • xgboost.XGBClassifier

Iremos executar uma curva AUC e também ROC para medir e mensurar a nossa decisão de modelo de Machine Learning.

Continuado com a nossa análise

Para iniciar vamos juntos analisar algumas variáveis do nosso dataset que contêm valores de categoria do tipo object. Para isso, usaremos o método: .value_counts() ele nós ajuda a examinar a contagem dos valores em cada coluna e o nosso foco de análise será:

  • sex
  • embarked

Não faremos isso para as outras colunas do tipo object porque nosso foco está nas variáveis mencionadas. Isso porque, inicialmente, podemos querer chegar à conclusão analítica de que o sexo e o local de embarque do passageiro no Titanic podem influenciar nosso algoritmo. No entanto, repare que não estamos dizendo que apenas essas variáveis poderiam influenciar, mas sim que elas devem receber atenção para não enviesar nosso algoritmo. Execute então o comando:

titanic_df.dtypes

E você terá como retorno:

Retorno da nossa execução

Agora que executamos essa análise, podemos então verificar as variáveis foco do nosso estudo, que serão sex e embarked. Inicialmente, vamos olhar para a variável sex e para isso execute então:

titanic_df['sex'].value_counts(dropna=False)

Repare que você obterá com essa execução o total encontrado e também colocamos uma opção ao contar o total de que desejamos a remoção dos valores faltantes:

Total de passageiros

Agora faremos o mesmo para embarked, sendo assim, execute o comando:

titanic_df['embarked'].value_counts(dropna=False)

E ao executarmos, teremos como retorno os locais de embarque dos passageiros, e isso é importante, pois podemos pensar em uma análise aqui de que o local de embarque e o sexo poderiam influenciar em uma pessoa ficar viva na tragédia ou não. Mas lembre-se que estamos olhando para os dados com uma visão analítica, então qualquer hipótese aqui é válida para os fins do nosso estudo sobre os dados. E ao executar, teremos o seguinte retorno:

Retorno da nossa execução

Caso não venha a entender o retorno pela sigla, saiba que cada uma representa o local de embarque do passageiro:

  • S: Southampton
  • C: Cherbourg
  • Q: Queenstown

A partir dessa análise, podemos então continuar para a criação de atributos dos nossos dados. Sendo assim, vamos excluir as colunas que não variam em nosso modelo.

Um exemplo é a coluna name. Além disso, também excluiremos essa coluna para evitar vazamento de informações sobre se o passageiro sobreviveu ou não. Isso é importante para que nosso modelo não leve em consideração essa informação do nome. As colunas que pretendemos tirar serão:

  • name
  • ticket
  • home.dest
  • boat
  • body
  • cabin

A título de curiosidade, vamos olhar em detalhes o que contém a variável `name` e executar a função head() que irá devolver os 5 primeiros nomes da nossa matriz. Para isso, execute então:

name = titanic_df['name']

name.head()

E você terá como retorno:

Retorno da execução

Caso queira executar o mesmo em cada variável mencionada, sinta-se à vontade, mas para o nosso caso, já irei remover essas variáveis, pois para o fim que desejamos, elas não indicam uma curvatura que pende em nossa decisão final. Sendo assim execute o comando:

titanic_df = titanic_df.drop(columns=[
"name",
"ticket",
"home.dest",
"boat",
"body",
"cabin"
])

titanic_df.head()

E você terá como retorno:

Retorno da execução

Repare comigo e note que temos algumas variáveis categóricas em nosso conjunto de dados, o que “pode” ser problemático para o nosso modelo.

Bom, para lidar com isso, vamos criar variáveis do tipo dummy (Variáveis ​​fictícias ou indicadoras que são usadas para representar dados categóricos) para essas colunas. Isso significa que vamos transformar nossas variáveis categóricas em variáveis numéricas, o que permitirá que nosso modelo as utilize de maneira mais eficaz e precisa durante a análise.

Para isso, utilizaremos a função get_dummies() do Pandas. Execute então o seguinte comando:

titanic_df = pd.get_dummies(titanic_df)

Para ter certeza de que foram criadas, vamos executar o comando columns e verificar quais colunas foram criadas durante esse processo:

titanic_df.columns

E então você terá como retorno:

Index(['pclass', 'survived', 'age', 'sibsp', 'parch', 'fare', 'sex_female',
'sex_male', 'embarked_C', 'embarked_Q', 'embarked_S'],
dtype='object')

E para que fique melhor a visualização do nosso *dataset*, execute o comando head():

titanic_df.head()

E teremos o seguinte retorno:

Retorno da nossa execução

Agora faremos a remoção de algumas colunas e o motivo é note que as colunas sex_male e sex_female têm uma correlação inversa. Sendo assim, vamos removê-las para evitar problemas de multicolinearidade, que podem afetar a interpretação da importância de nossos atributos. Para isso execute então:

titanic_df = titanic_df.drop(columns="sex_male")

titanic_df = pd.get_dummies(titanic_df, drop_first=True)

titanic_df.columns

Por fim, teremos estas colunas:

Index(['pclass', 'survived', 'age', 'sibsp', 'parch', 'fare', 'sex_female',
'embarked_C', 'embarked_Q', 'embarked_S'],
dtype='object')

Já estamos chegando ao final da parte 2 e para finalizar vamos criar uma série (y) com os rótulos, para que possamos realizar o treinamento e o teste dos nossos dados.

Como a variável que queremos prever é survived, vamos separá-la do conjunto de dados principal e utilizaremos a biblioteca Janitor para facilitar a limpeza e preparação dos nossos dados. Com o pacote Janitor, podemos simplificar a manipulação dos nossos dados. E para isso execute então:

import janitor as jn

X, y = jn.ml.get_features_targets(titanic_df, target_columns="survived")

E caso queira saber o resultado, basta executar o comando head(). Aqui irei deixar a execução do head sobre x e y:

X.head()
Retorno da execução
y.head()
Retorno da execução

Por fim, faremos a separação da nossa amostra e faremos isso porque desejamos avaliar o desempenho dos nossos modelos. E isso é crucial porque precisamos desses dados para realizar os nossos testes.

Utilizaremos a função train_test_split do pacote scikit-learn para dividir nossos dados em conjuntos de treinamento e teste. Sendo assim, deixe o código da seguinte maneira:

from sklearn.model_selection import train_test_split

# Dividimos os dados X e y, sendo X os atributos e y os rótulos.
# Test_size=0.3 indica que 30% dos dados serão usados para testes.
# Random_state=42 é definido para garantir a reprodutibilidade dos resultados.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

Em nosso código anterior, X representa os atributos do nosso conjunto de dados e y representa os rótulos. Dividimos X e y em X_train e y_train, que são os conjuntos de treinamento, e X_test e y_test, que são os nossos conjuntos de teste.

O parâmetro test_size=0.3 indica que 30% dos nossos dados serão usados para teste, enquanto random_state=42 é definido para garantir que a divisão dos dados seja sempre a mesma, permitindo a comparação justa entre nossos diferentes modelos.

Na parte 3 daremos continuidade na imputação de dados faltantes, normalização e funções auxiliares. Por enquanto é isso, um grande abraço do MD!

Ilustração gráfica engraçada de Albert Einstein

--

--