Pular para o conteúdo principal

Tutorial Kaggle: EDA e machine learning

Neste tutorial do Kaggle, você vai aprender como abordar e construir modelos de aprendizado supervisionado com a ajuda de análise exploratória de dados (EDA) usando os dados do Titanic.
· 10 min leer

Explore com IA

No início deste mês, fiz uma sessão de Live Code no Facebook em que eu (e todo mundo que programou junto) construí vários algoritmos, cada vez mais complexos, para prever se um passageiro do Titanic sobreviveu ou não, usando dados como a tarifa paga, o porto de embarque e a idade.

Neste post, você vai rever alguns dos pontos que cobrimos na sessão. Se quiser reassistir ou acompanhar o post junto com o vídeo, é só dar o play aqui:

Em especial, talvez você lembre que construímos modelos de aprendizado supervisionado.

Aprendizado supervisionado é a área de Machine Learning (ML) que envolve prever rótulos, como "Survived" ou "Not". Esses modelos aprendem com dados rotulados — ou seja, dados que indicam se um passageiro sobreviveu (o chamado "treinamento do modelo") — e depois fazem previsões em dados sem rótulo.

No Kaggle, uma plataforma de competições de modelagem preditiva e analytics, esses conjuntos são chamados de train e test porque

  • você quer treinar um modelo que aprenda padrões no conjunto de treino e
  • depois usar o modelo para prever no conjunto de teste.

O Kaggle então informa a porcentagem de acertos: isso é conhecido como a acurácia do seu modelo.

Como começar com aprendizado supervisionado

Como você já deve saber, uma boa maneira de abordar aprendizado supervisionado é a seguinte:

  • faça uma análise exploratória de dados (EDA) no seu conjunto de dados;
  • construa um modelo rápido, um baseline, que sirva de comparação para os modelos seguintes que você vai criar;
  • itere esse processo. Faça mais EDA e construa outro modelo;
  • faça engenharia de atributos (features): pegue as features que já tem, combine-as ou extraia mais informações delas até chegar ao último ponto, que é
  • obter um modelo que tenha melhor desempenho.

Nesta sessão de code along, você fez — ou vai fazer — todas essas etapas!

Observação: também temos cursos para você começar com machine learning no dataset do Titanic em Python e R.

Importe seus dados e dê uma olhada

O primeiro passo é sempre importar os dados para entender rapidamente com o que você vai trabalhar. Aqui, você vai importar o pacote pandas e usar a função read_csv() para ler os dados:

Observação: nos blocos de código abaixo, outros pacotes e módulos como matplotlib, sklearn e seaborn já foram importados. Você vai usá-los mais à frente para visualização (estatística) de dados e para machine learning!

Você também usa o comando mágico do IPython %matplotlib inline para que os gráficos apareçam dentro do notebook. E adiciona sns.set() para aplicar o estilo base do Seaborn às visualizações:

# Import modules
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import tree
from sklearn.metrics import accuracy_score

# Figures inline and set visualization style
%matplotlib inline
sns.set()

Sem mais demora, vamos importar os dados e dar o primeiro passo na exploração:

# Import test and train datasets
df_train = pd.read_csv('../data/train.csv')
df_test = pd.read_csv('../data/test.csv')

# View first lines of training data
df_train.head(n=4)
 PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S

Se quiser ver o que cada feature representa, confira a documentação dos dados no Kaggle aqui.

Antes de seguir, vale alinhar a terminologia:

  • a variável-alvo (target) é aquela que você está tentando prever;
  • as outras variáveis são as "features" (ou "variáveis preditoras", usadas para prever a variável-alvo).

Com isso em mente, você pode continuar explorando os dados usando, por exemplo, a função head(), que exibe as cinco primeiras linhas do seu dataset:

# View first lines of test data
df_test.head()
 PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS

Note que o DataFrame df_test não tem a coluna 'Survived', porque é justamente o que você vai prever!

  • Você também pode usar o método .info() do DataFrame para ver tipos de dados, valores ausentes e mais (de df_train).
df_train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB

Neste caso, dá para ver que há apenas 714 valores não nulos na coluna 'Age' em um DataFrame com 891 linhas. Isso significa que existem 177 valores nulos ou ausentes.

  • Também use o método .describe() do DataFrame para ver estatísticas descritivas das colunas numéricas (de df_train).
df_train.describe()
 PassengerIdSurvivedPclassAgeSibSpParchFare
count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
max891.0000001.0000003.00000080.0000008.0000006.000000512.329200

EDA visual e seu primeiro modelo

Agora que você tem uma ideia do formato dos dados e conferiu algumas estatísticas, é hora de visualizar com a ajuda do seaborn:

  • por exemplo, use seaborn para criar um gráfico de barras da sobrevivência no Titanic, que é sua variável-alvo.
sns.countplot(x='Survived', data=df_train);

bar chart

Conclusão: no conjunto de treino, menos pessoas sobreviveram do que não sobreviveram. Vamos então construir um primeiro modelo que prevê que ninguém sobreviveu.

Esse é um modelo ruim, porque sabemos que houve sobreviventes. Mas ele nos dá um baseline: qualquer modelo futuro precisa superar esse desempenho.

Você pode fazer assim:

  • crie uma coluna 'Survived' em df_test que codifique "não sobreviveu" para todas as linhas;
  • salve as colunas 'PassengerId' e 'Survived' de df_test em um .csv e envie ao Kaggle.
df_test['Survived'] = 0
df_test[['PassengerId', 'Survived']].to_csv('data/predictions/no_survivors.csv', index=False)

Qual foi a acurácia? No Kaggle, a acurácia é de 62,7.

kaggle

Nada mal!

Nota essencial! Você também vai querer usar métricas além de acurácia!

EDA nas variáveis de feature

Agora que você criou um modelo "rápido e sujo", é hora de iterar: vamos fazer mais análise exploratória e logo construir outro modelo!

  • Use o seaborn para criar um gráfico de barras da feature 'Sex' do Titanic (de df_train).
sns.countplot(x='Sex', data=df_train);

bar plot

  • Também use seaborn para criar gráficos de barras de 'Survived' segmentados (facetados) por 'Sex'.
sns.factorplot(x='Survived', col='Sex', kind='count', data=df_train);

bar plot

Conclusão: mulheres tinham mais chance de sobreviver do que homens.

  • Com essa descoberta, você pode usar pandas para ver quantas mulheres e quantos homens sobreviveram:
df_train.groupby(['Sex']).Survived.sum()
Sex
female    233
male      109
Name: Survived, dtype: int64
  • Use pandas para calcular a proporção de mulheres que sobreviveram e a proporção de homens:
print(df_train[df_train.Sex == 'female'].Survived.sum()/df_train[df_train.Sex == 'female'].Survived.count())
print(df_train[df_train.Sex == 'male'].Survived.sum()/df_train[df_train.Sex == 'male'].Survived.count())
0.742038216561
0.188908145581

74% das mulheres sobreviveram, enquanto 19% dos homens sobreviveram.

Agora vamos construir um segundo modelo e prever que todas as mulheres sobreviveram e todos os homens não. De novo, é um modelo irrealista, mas fornece um baseline para comparar os próximos.

  • Crie a coluna 'Survived' em df_test codificando a previsão acima.
  • Salve as colunas 'PassengerId' e 'Survived' de df_test em um .csv e envie ao Kaggle.
df_test['Survived'] = df_test.Sex == 'female'
df_test['Survived'] = df_test.Survived.apply(lambda x: int(x))
df_test.head()
 PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedSurvived
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ0
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS1
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ0
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS0
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS1
df_test[['PassengerId', 'Survived']].to_csv('../data/predictions/women_survive.csv', index=False)

E qual foi a acurácia desse modelo ao enviar para o Kaggle?

No Kaggle, a acurácia é de 76,6%:

kaggle

Com esse envio, você subiu cerca de 2.000 posições no ranking! Além disso, melhorou sua pontuação — ótimo trabalho!

Explore ainda mais seus dados

  • Use seaborn para criar gráficos de barras de 'Survived' segmentados (facetados) por 'Pclass' no dataset do Titanic.
sns.factorplot(x='Survived', col='Pclass', kind='count', data=df_train);

bar plot

Conclusão: passageiros de primeira classe tinham mais chance de sobreviver. Já os da terceira classe tinham menos chance.

  • Use seaborn para criar gráficos de barras de 'Survived' segmentados (facetados) por 'Embarked'.
sns.factorplot(x='Survived', col='Embarked', kind='count', data=df_train);

bar plot

Conclusão: passageiros que embarcaram em Southampton tinham menos chance de sobreviver.

EDA com variáveis numéricas

  • Use seaborn para plotar um histograma da coluna 'Fare' de df_train.
sns.distplot(df_train.Fare, kde=False);

histogram

Conclusão: a maioria dos passageiros pagou menos de 100 para viajar no Titanic.

  • Use um método de plotagem do pandas para plotar a coluna 'Fare' para cada valor de 'Survived' no mesmo gráfico.
df_train.groupby('Survived').Fare.hist(alpha=0.6);

bar plot

Conclusão: parece que quem pagou mais teve maior chance de sobreviver.

  • Use seaborn para plotar um histograma da coluna 'Age' de df_train. Primeiro, elimine os valores nulos.
df_train_drop = df_train.dropna()
sns.distplot(df_train_drop.Age, kde=False);

histogram

  • Plote um strip plot e um swarm plot de 'Fare' com 'Survived' no eixo x.
sns.stripplot(x='Survived', y='Fare', data=df_train, alpha=0.3, jitter=True);

strip plot

sns.swarmplot(x='Survived', y='Fare', data=df_train);

swarm plot

Conclusão: a tarifa (Fare) parece estar, de fato, correlacionada com a sobrevivência no Titanic.

  • Use o método .describe() para ver estatísticas descritivas de 'Fare' em função de 'Survived'.
df_train.groupby('Survived').Fare.describe()
 countmeanstdmin25%50%75%max
Survived        
0549.022.11788731.3882070.07.854210.526.0263.0000
1342.048.39540866.5969980.012.475026.057.0512.3292
  • Use seaborn para fazer um scatter plot de 'Age' contra 'Fare', colorido por 'Survived'.
sns.lmplot(x='Age', y='Fare', hue='Survived', data=df_train, fit_reg=False, scatter_kws={'alpha':0.5});

scatter plot

Conclusão: parece que quem sobreviveu ou pagou bem mais pela passagem, ou era mais jovem.

  • Use seaborn para criar um pairplot de df_train, colorido por 'Survived'. Um pairplot é ótimo para exibir, em uma única grade, boa parte do que você já descobriu.
sns.pairplot(df_train_drop, hue='Survived');

plots

Da EDA ao modelo de machine learning

Neste tutorial, você:

  • carregou os dados e deu uma olhada inicial;
  • explorou visualmente a variável-alvo e fez suas primeiras previsões;
  • explorou algumas features visualmente e fez previsões melhores com base na EDA;
  • fez uma EDA mais aprofundada de variáveis categóricas e numéricas.

No próximo post, você vai dedicar um tempo para construir alguns modelos de Machine Learning, com base no que aprendeu aqui na EDA. Vamos fazer isso no próximo post deste projeto (lançamento em 27 de dezembro).

Temas

Relacionado