Você quer fazer a análise do titanic para colocar no seu portfólio de Ciências de Dados? Acompanhe comigo o passo a passo do projeto!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Fala Impressionadores! Hoje vamos dar início a mais um projeto real para portfólio de Ciência de Dados!
O projeto de hoje é a Análise do Titanic que também é um dataset do Kaggle para competição!
Para essa análise nós vamos dividir as aulas, e nessa primeira aula vamos fazer uma análise mais simples desses dados e submeter ao Kaggle para avaliar os nossos resultados.
Vamos utilizar a árvore de classificação, KNN e a Regressão Logística para essas análises iniciais.
Para a próxima aula a ideia é definir uma acurácia de 85%, então vamos melhorar esse projeto completo de ciência de dados para te mostrar o que pode ser feito para melhorar os resultados!
Titanic – Machine Learning from Disaster
Vamos utilizar os dados disponíveis no Kaggle, este é um dataset de competição e o resultado é avaliado através da acurácia:
“Sua pontuação é a porcentagem de passageiros que você prevê corretamente. Isso é conhecido como acurácia.”
Se quiser saber mais sobre modelos de avaliação clique nesta aula!
Este projeto é bom por ser sobre um assunto conhecido, o que torna a compreensão mais fácil do que desafios sobre áreas muito específicas, além disso, existe muita informação disponível na internet que podemos usar a nosso favor.
Então, esta é a primeira aula de introdução – Análise do Titanic.
Vamos começar a entender a base?
No Kaggle vamos ter diversas informações como a quantidade de passageiros, seus nomes, idades, etc.
O que vamos fazer é tentar prever se os passageiros na base de teste sobreviveram ou não.
Podemos utilizar o ydata-profiling (antigo Pandas Profiling) para começar a entender essa base
https://github.com/ydataai/ydata-profiling
# Importando o Pandas
import pandas as pd
# Visualizando a base de treino
treino = pd.read_csv('train.csv')
treino.head(3)
Observe que estamos trabalhando com as informações dos passageiros, temos seus nomes, gênero, idade, etc.
Nesta aula vamos fazer uma aula mais básica sem se aprofundar muito em cada coluna, nas próximas aulas vamos aos poucos nos aprofundando mais.
# Importando o ProfileReport do ydata-profiling
from ydata_profiling import ProfileReport
# Gerando a visualização
profile = ProfileReport(treino, title="titanic_treino")
# Criando o relatório
profile.to_file("titanic_treino.html")
Summarize dataset: 0%| | 0/5 [00:00<?, ?it/s]
Generate report structure: 0%| | 0/1 [00:00<?, ?it/s]
Render HTML: 0%| | 0/1 [00:00<?, ?it/s]
Export report to file: 0%| | 0/1 [00:00<?, ?it/s]
Agora vamos analisar essa base
# Verificando as informações da base
treino.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
# Verificando o tipo dos dados
treino.dtypes.value_counts()
int64 5
object 5
float64 2
dtype: int64
# E os valores nulos
treino.isnull().sum().sort_values(ascending=False).head(5)
Cabin 687
Age 177
Embarked 2
PassengerId 0
Survived 0
dtype: int64
Agora vamos visualizar a base de teste, a base em que iremos fazer a previsão.
# Visualizando a base de teste
teste = pd.read_csv('test.csv')
teste.head(3)
# Verificando as informações da base
teste.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 418 non-null int64
1 Pclass 418 non-null int64
2 Name 418 non-null object
3 Sex 418 non-null object
4 Age 332 non-null float64
5 SibSp 418 non-null int64
6 Parch 418 non-null int64
7 Ticket 418 non-null object
8 Fare 417 non-null float64
9 Cabin 91 non-null object
10 Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
# Analisando os valores nulos
teste.isnull().sum().sort_values(ascending=False).head(5)
Cabin 327
Age 86
Fare 1
PassengerId 0
Pclass 0
dtype: int64
Temos colunas que possuem valores vazios na base de teste que não estão vazias na base de treino (nesse caso, precisaríamos tratar essas colunas apenas na base de teste).
Podemos começar tratando os valores vazios
# Verificando novamente valores vazios para a base de treino
treino.isnull().sum().sort_values(ascending=False).head(5)
Cabin 687
Age 177
Embarked 2
PassengerId 0
Survived 0
dtype: int64
# Retornando o shape da base
treino.shape
(891, 12)
# Visualizando novamente a base
treino.head(4)
Existe na nossa base muitas colunas com alta cardinalidade, o que torna o modelo menos generalizável, e não é isso que queremos.
Por este motivo vamos verificar a cardinalidade dos dados para fazer o tratamento do nosso modelo.
# Verificando a cardinalidade dos dados
treino.nunique().sort_values(ascending=False)
PassengerId 891
Name 891
Ticket 681
Fare 248
Cabin 147
Age 88
SibSp 7
Parch 7
Pclass 3
Embarked 3
Survived 2
Sex 2
dtype: int64
Colunas com alta cardinalidade como nome, número do ticket e até mesmo o código da cabine não vão ajudar o modelo, pois podem torná-lo menos generalizável. Nesse caso, vamos eliminar essas colunas
# Eliminando para a base de treino
treino = treino.drop(['Name','Ticket','Cabin'],axis=1)
# Também eliminando para a base de teste
teste = teste.drop(['Name','Ticket','Cabin'],axis=1)
Agora precisamos tratar a coluna Age, que possui valores vazios tanto no treino quanto no teste e isso não faz sentido afinal todos tinham sua idade, esta coluna não deveria ter valores vazios.
Como essa coluna possui a idade dos passageiros, podemos utilizar a média das idades para substituir os valores vazios
# Verificando a média das idades para a base de treino
treino.Age.mean()
29.69911764705882
# Podemos agora selecionar as colunas com idade vazia e substituir por essa média
treino.loc[treino.Age.isnull(),'Age'] = treino.Age.mean()
# E fazendo o mesmo para a base de teste
teste.loc[teste.Age.isnull(),'Age'] = teste.Age.mean()
Para a base de treino, ainda temos 2 valores vazios na coluna Embarked
Podemos verificar todos os valores nessa coluna e substituir os valores vazios pela moda
# Verificando os valores na coluna Embarked
treino.Embarked.value_counts()
S 644
C 168
Q 77
Name: Embarked, dtype: int64
# Selecionando a moda dessa coluna
treino.Embarked.mode()[0]
'S'
# Substituindo os valores vazios
treino.loc[treino.Embarked.isnull(),'Embarked'] = treino.Embarked.mode()[0]
Para finalizar, para a base de teste ainda temos 1 valor vazio em Fare
Podemos utilizar a mesma lógica que fizemos para a coluna Age e substituir pela moda.
# Verificando a média da coluna Fare para a base de teste
teste.loc[teste.Fare.isnull(),'Fare'] = teste.Fare.mean()
Verificando novamente os valores vazios
# Para a base de treino
treino.isnull().sum().sort_values(ascending=False).head(5)
PassengerId 0
Survived 0
Pclass 0
Sex 0
Age 0
dtype: int64
# Para a base de teste
teste.isnull().sum().sort_values(ascending=False).head(5)
PassengerId 0
Pclass 0
Sex 0
Age 0
SibSp 0
dtype: int64
Todas as colunas com valores vazios já foram tratados!
Agora vamos trabalhar considerando apenas as colunas que não são de texto
# Verificando as colunas de texto na base de treino
col_treino_nr = treino.columns[treino.dtypes != 'object']
col_treino_nr
Index(['PassengerId', 'Survived', 'Pclass', 'Age', 'SibSp', 'Parch', 'Fare'], dtype='object')
# Selecionando apenas os valores numéricos da base de treino
treino_nr = treino.loc[:,col_treino_nr]
# E para a base de teste
col_teste_nr = teste.columns[teste.dtypes != 'object']
col_teste_nr
Index(['PassengerId', 'Pclass', 'Age', 'SibSp', 'Parch', 'Fare'], dtype='object')
# e os valores numéricos da base de teste
teste_nr = teste.loc[:,col_teste_nr]
Podemos selecionar um modelo para classificar esses dados. Para começar, vamos testar entre:
Árvore de classificação
https://scikit-learn.org/stable/modules/tree.html#classification
Classificação dos vizinhos mais próximos
Regressão Logística
Antes de usar os algoritmos, precisamos separar a base de treino em treino e validação. Vamos fazer isso utilizando o train_test_split.
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
# Importando o train_test_split
from sklearn.model_selection import train_test_split
# Separando a base de treino em X e y
X = treino_nr.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
# Separando em treino e validação
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=42)
Para a árvore de classificação
# Fazendo a importação
from sklearn import tree
# Criando o classificador
clf_ac = tree.DecisionTreeClassifier(random_state=42)
# Fazendo o fit com os dados
clf_ac = clf_ac.fit(X_train,y_train)
# Fazendo a previsão
y_pred_ac = clf_ac.predict(X_val)
Para o KNeighborsClassifier
# Importando
from sklearn.neighbors import KNeighborsClassifier
# Criando o classificador
clf_knn = KNeighborsClassifier(n_neighbors=3)
# Fazendo o fit com os dados
clf_knn = clf_knn.fit(X_train,y_train)
# Fazendo a previsão
y_pred_knn = clf_knn.predict(X_val)
E para a Regressão Logística
# Importando
from sklearn.linear_model import LogisticRegression
# Criando o classificador
clf_rl = LogisticRegression(random_state=42)
# Fazendo o fit com os dados
clf_rl = clf_rl.fit(X_train,y_train)
# Fazendo a previsão
y_pred_rl = clf_rl.predict(X_val)
E, para finalizar, vamos avaliar esses modelos. Para fazer essa análise, podemos usar:
Acurácia (método de avaliação usado na competição):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
Matriz de confusão (ajuda a visualizar a distribuição dos erros):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html
Avaliando a acurácia
# Importando
from sklearn.metrics import accuracy_score
# Para a árvore
accuracy_score(y_val, y_pred_ac)
0.6169491525423729
# Para o knn
accuracy_score(y_val, y_pred_knn)
0.6542372881355932
# Para a regressão logística
accuracy_score(y_val, y_pred_rl)
0.7254237288135593
A regressão logística é o melhor modelo dentre os três analisados.
Avaliando a matriz de confusão
# Importando
from sklearn.metrics import confusion_matrix
# Para a árvore
confusion_matrix(y_val, y_pred_ac)
array([[125, 50],
[ 63, 57]], dtype=int64)
# Para o knn
confusion_matrix(y_val, y_pred_knn)
array([[133, 42],
[ 60, 60]], dtype=int64)
# Para a regressão logística
confusion_matrix(y_val, y_pred_rl)
array([[156, 19],
[ 62, 58]], dtype=int64)
Fazendo a previsão para os dados de teste, vamos usar o modelo com melhor precisão para fazer o predict na base de teste
# Visualizando o X_train
X_train.head(3)
# Visualizando a base de teste (apenas com valores numéricos)
teste_nr.head(3)
# Para a base de teste ser igual a base de treino, precisamos eliminar a coluna de id
X_teste = teste_nr.drop("PassengerId",axis=1)
# Utilizando a regressão logística na base de teste
y_pred = clf_rl.predict(X_teste)
# Criando uma coluna com a previsão na base de teste
teste['Survived'] = y_pred
# Selecionando apenas a coluna de Id e Survived para fazer o envio
base_envio = teste[['PassengerId','Survived']]
Desta forma o resultado fica pronto para envio.
# Exportando para um csv
base_envio.to_csv('resultados2.csv',index=False)
Feito isso, arraste o arquivo para submeter no Kaggle.
Nessa aula nós vamos fazer o tratamento de colunas de texto para verificar como esse tratamento vai influenciar na acurácia do nosso modelo.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Fala Impressionadores! Hoje vamos para aula 2 da nossa Análise do Titanic que é mais um Projeto de Ciência de Dados para o seu portfólio de projetos.
Você deve lembrar que na primeira aula nós não fizemos muitos tratamentos, mas já conseguimos uma acurácia de 66%.
A ideia agora é fazer o tratamento das informações de texto para verificar se incluindo essas informações nós conseguimos aumentar a acurácia do modelo.
Vamos utilizar os mesmos modelos que utilizamos na aula anterior, mas agora com o tratamento nas colunas de texto para verificar como isso afeta o nosso resultado!
Titanic – Machine Learning from Disaster
Vamos utilizar os dados disponíveis no Kaggle e o resultado é avaliado através da acurácia:
“Sua pontuação é a porcentagem de passageiros que você prevê corretamente. Isso é conhecido como acurácia.”
Dica: É importante deixar claro em seu portifólio que está é a parte dois do projeto, uma tentativa de diminuir o erro e deixar também a linha de raciocínio usada.
Se você quiser ver a primeira parte do projeto no GitHub é só acessar o link abaixo:
https://github.com/lucaslealx/Titanic/blob/main/Parte1.ipynb
Importando novamente as bases e fazendo o tratamento dos dados
# Importando o pandas
import pandas as pd
# Visualizando a base de treino
treino = pd.read_csv('train.csv')
treino.head(3)
# Visualizando a base de teste
teste = pd.read_csv('test.csv')
teste.head(3)
Fazendo o mesmo tratamento inicial que fizemos na aula anterior
# Eliminando as colunas com elevada cardinalidade
treino = treino.drop(['Name','Ticket','Cabin'],axis=1)
teste = teste.drop(['Name','Ticket','Cabin'],axis=1)
# Usando a média para substituir valores nulos na coluna de idade
treino.loc[treino.Age.isnull(),'Age'] = treino.Age.mean()
teste.loc[teste.Age.isnull(),'Age'] = teste.Age.mean()
# Tratando a coluna Embarked da base de treino usando a moda
treino.loc[treino.Embarked.isnull(),'Embarked'] = treino.Embarked.mode()[0]
# E também a coluna Fare da base de teste usando a média
teste.loc[teste.Fare.isnull(),'Fare'] = teste.Fare.mean()
Na última aula retiramos as colunas de textos, nesta aula vamos trabalhar e entender essas colunas
# Verificando as colunas de texto na base de treino
treino.columns[treino.dtypes == 'object']
Index(['Sex', 'Embarked'], dtype='object')
# Verificando os valores na coluna Sex
treino.Sex.value_counts()
# e na coluna Embarked
treino.Embarked.value_counts()
Para tratar a coluna “Sex”, podemos criar uma coluna chamada “Male_Check” que vai receber 1 se o gênero for masculino e 0 se o gênero for feminino
# Usando uma lambda function para fazer esse tratamento
treino['MaleCheck'] = treino.Sex.apply(lambda x: 1 if x == 'male' else 0)
# Verificando os valores
treino[['Sex','MaleCheck']].value_counts()
O próximo passo é fazer o mesmo para a base de teste
# Usando uma lambda function para fazer esse tratamento
teste['MaleCheck'] = teste.Sex.apply(lambda x: 1 if x == 'male' else 0)
# Verificando os valores
teste[['Sex','MaleCheck']].value_counts()
Agora, para tratar a coluna Embarked usando o OneHotEncoder que irá criar uma nova coluna para cada um dos rótulos da coluna original
# Importando o OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
# Criando o encoder
ohe = OneHotEncoder(handle_unknown='ignore',dtype='int32')
# Fazendo o fit com os dados
ohe = ohe.fit(treino[['Embarked']])
# Fazendo a transformação
ohe.transform(treino[['Embarked']]).toarray()
# Transformando esse resultado em um DataFrame
ohe_df = pd.DataFrame(ohe.transform(treino[['Embarked']]).toarray(),columns=ohe.get_feature_names_out())
ohe_df.head(3)
# Podemos agora adicionar essa coluna na nossa base de treino
treino = pd.concat([treino,ohe_df],axis=1)
# Verificando os valores
treino[['Embarked','Embarked_C','Embarked_Q','Embarked_S']].value_counts()
Agora precisamos fazer o mesmo para a base de teste usando o encoder ohe que criamos acima.
# Transformando esse resultado em um DataFrame
ohe_df = pd.DataFrame(ohe.transform(teste[['Embarked']]).toarray(),columns=ohe.get_feature_names_out())
# Adicionando o resultado na base de teste
teste = pd.concat([teste,ohe_df],axis=1)
# Verificando também os valores
teste[['Embarked','Embarked_C','Embarked_Q','Embarked_S']].value_counts()
Todas as colunas de texto já foram tratadas, vamos usar essa nova base no modelo
# Visualizando a base
treino.head(3)
# Podemos então apagar essas duas colunas que já tratamos
treino = treino.drop(['Sex','Embarked'],axis=1)
teste = teste.drop(['Sex','Embarked'],axis=1)
Antes de usar os algoritmos, precisamos separar a base de treino em treino e validação
Vamos fazer isso utilizando o train_test_split
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
# Importando o train_test_split
from sklearn.model_selection import train_test_split
# Separando a base de treino em X e y
X = treino.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
# Separando em treino e validação
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=42)
Para a árvore de classificação
# Fazendo a importação
from sklearn import tree
# Criando o classificador
clf_ac = tree.DecisionTreeClassifier(random_state=42)
# Fazendo o fit com os dados
clf_ac = clf_ac.fit(X_train,y_train)
# Fazendo a previsão
y_pred_ac = clf_ac.predict(X_val)
Para o KNeighborsClassifier
# Importando
from sklearn.neighbors import KNeighborsClassifier
# Criando o classificador
clf_knn = KNeighborsClassifier(n_neighbors=3)
# Fazendo o fit com os dados
clf_knn = clf_knn.fit(X_train,y_train)
# Fazendo a previsão
y_pred_knn = clf_knn.predict(X_val)
E para a Regressão Logística
# Importando
from sklearn.linear_model import LogisticRegression
# Criando o classificador
clf_rl = LogisticRegression(random_state=42,max_iter=1000)
# Fazendo o fit com os dados
clf_rl = clf_rl.fit(X_train,y_train)
# Fazendo a previsão
y_pred_rl = clf_rl.predict(X_val)
Vamos novamente avaliar os modelos
Avaliando a acurácia
# Importando
from sklearn.metrics import accuracy_score
# Para a árvore
accuracy_score(y_val, y_pred_ac)
0.7491525423728813
# Para o knn
accuracy_score(y_val, y_pred_knn)
0.7152542372881356
# Para a regressão logística
accuracy_score(y_val, y_pred_rl)
0.8169491525423729
Avaliando a matriz de confusão
# Importando
from sklearn.metrics import confusion_matrix
# Para a árvore
confusion_matrix(y_val, y_pred_ac)
# Para o knn
confusion_matrix(y_val, y_pred_knn)
# Para a regressão logística
confusion_matrix(y_val, y_pred_rl)
Fazendo a previsão para os dados de teste
Vamos usar o modelo com melhor precisão para fazer o Predict na base de teste
# Visualizando o X_train
X_train.head(3)
# Visualizando a base de teste
teste.head(3)
# Para a base de teste ser igual a base de treino, precisamos eliminar a coluna de id
X_teste = teste.drop('PassengerId',axis=1)
# Utilizando a regressão logística na base de teste
y_pred = clf_rl.predict(X_teste)
# Criando uma nova coluna com a previsão na base de teste
teste['Survived'] = y_pred
# Selecionando apenas a coluna de Id e Survived para fazer o envio
base_envio = teste[['PassengerId','Survived']]
# Exportando para um csv
base_envio.to_csv('resultados4.csv',index=False)
Após importar para csv podemos salvar e subir no portifólio como na aula anterior, você pode acrescentar comentários que expliquem a linha de raciocínio usada para este teste.
Acurácia de 0.76
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Fala Impressionadores! Hoje vamos para aula 3 da nossa Análise do Titanic que é mais um Projeto de Ciência de Dados para o seu portfólio de projetos.
Nessa aula nós vamos falar sobre Engenharia de Dados, ou seja, vamos fazer mais tratamentos na nossa base para verificar se conseguimos melhorar a nossa pontuação.
Vocês vão notar que nem todo tratamento vai trazer um resultado positivo, então não basta fazer diversos tratamentos e pensar que tudo vai melhorar e nossa acurácia vai aumentar.
A ideia é sempre ir testando e ter um objetivo, assim você não vai precisar ficar fazendo esses tratamentos de forma indeterminada.
Vou continuar utilizando os mesmos modelos, mas vou fazer diferentes tratamentos nas bases de dados para que você entenda como vamos fazer essa análise e se cada um desses tratamentos está ou não melhorando o nosso resultado!
Titanic – Machine Learning from Disaster
Vamos utilizar os dados disponíveis no Kaggle – Este é um dataset de competição
O resultado é avaliado através da acurácia:
“Sua pontuação é a porcentagem de passageiros que você prevê corretamente. Isso é conhecido como acurácia.”
Importando novamente as bases e fazendo o tratamento dos dados
Vamos apenas replicar o que fizemos no primeiro e no segundo arquivo dessa análise (para visualizar os arquivos completos, visite esse link)
Hoje vamos evoluir um pouco mais fazendo a limpeza de recursos e engenharia de dados, assim você pode ir atualizando seu portifólio aos poucos e mostrando o seu conhecimento para os recrutadores.
Nas últimas aulas começamos a entender e fazer alguns tratamentos nessa base, agora nosso objetivo é se aprofundar nesses tratamentos, para isso vamos executar novamente as primeiras linhas para visualizar os dados:
# Importando o pandas
import pandas as pd
# Visualizando a base de treino
treino = pd.read_csv('train.csv')
treino.head(3)
# Visualizando a base de teste
teste = pd.read_csv('test.csv')
teste.head(3)
Fazendo o mesmo tratamento inicial que fizemos nas aulas anteriores
# Eliminando as colunas com elevada cardinalidade
treino = treino.drop(['Name','Ticket','Cabin'],axis=1)
teste = teste.drop(['Name','Ticket','Cabin'],axis=1)
# Usando a média para substituir valores nulos na coluna de idade
treino.loc[treino.Age.isnull(),'Age'] = treino.Age.mean()
teste.loc[teste.Age.isnull(),'Age'] = teste.Age.mean()
# Tratando a coluna Embarked da base de treino usando a moda
treino.loc[treino.Embarked.isnull(),'Embarked'] = treino.Embarked.mode()[0]
# E também a coluna Fare da base de teste usando a média
teste.loc[teste.Fare.isnull(),'Fare'] = teste.Fare.mean()
# Usando uma lambda function para tratar a coluna "Sex"
treino['MaleCheck'] = treino.Sex.apply(lambda x: 1 if x == 'male' else 0)
teste['MaleCheck'] = teste.Sex.apply(lambda x: 1 if x == 'male' else 0)
E vamos usar o OneHotEncoder para tratar a coluna Embarked
# Criando o encoder e fazendo o fit com os dados
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(handle_unknown='ignore',dtype='int32')
ohe = ohe.fit(treino[['Embarked']])
# Atualizando a base de treino com os novos valores
ohe_df = pd.DataFrame(ohe.transform(treino[['Embarked']]).toarray(),columns=ohe.get_feature_names_out())
treino = pd.concat([treino,ohe_df],axis=1)
# e a base de teste
ohe_df = pd.DataFrame(ohe.transform(teste[['Embarked']]).toarray(),columns=ohe.get_feature_names_out())
teste = pd.concat([teste,ohe_df],axis=1)
# Podemos então apagar essas duas colunas que já tratamos
treino = treino.drop(['Sex','Embarked'],axis=1)
teste = teste.drop(['Sex','Embarked'],axis=1)
Visualizando a base resultante
# Visualizando a base de treino
treino.head(3)
Podemos já utilizar essa base no modelo para efeitos de comparação com as melhorias que vamos fazer abaixo
Vamos fazer alguns ajustes nos dados para melhorar o resultado do nosso modelo
Vamos rodar todo o código novamente linha a linha como fizemos na aula anterior, feito isso volte para esta parte para visualizar a escala dos dados.
Lembrando que todo esse material está disponível para baixar nesta aula!
1º – Analisando a escala dos dados
As colunas “Age” e “Fare” estão em uma escala muito diferente das outras, podemos começar fazendo um ajuste nessas escalas
Vamos usar os ajustes de escala do próprio Scikit-Learn
Como essas colunas possuem outliers, podemos começar tentando utilizar o RobustScaler
# Visualizando a escala desses dados
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(15,5))
ax.boxplot(treino.iloc[:,1:11])
ax.set_xticks(range(1,treino.iloc[:,1:11].shape[1]+1),treino.iloc[:,1:11].columns)
plt.show()
Quando visualizamos os dados conseguimos perceber claramente que a coluna de idade e a coluna de taxa tem uma diferença gigantesca.
Para fazer o tratamento destas variáveis vamos usar toda a parte de processamentos dos dados do Scikit-Learn, como a padronização a normalização.
Usando o RobustScaler
[ ]
# Importando o RobustScaler
from sklearn.preprocessing import RobustScaler
# Criando o scaler
transformer = RobustScaler().fit(treino[['Age','Fare']])
# Fazendo o transformação dos dados
treino[['Age','Fare']] = transformer.transform(treino[['Age','Fare']])
# Fazendo o mesmo para a base de teste
transformer = RobustScaler().fit(teste[['Age','Fare']])
teste[['Age','Fare']] = transformer.transform(teste[['Age','Fare']])
# Visualizando novamente os dados
fig, ax = plt.subplots(figsize=(15,5))
ax.boxplot(treino.iloc[:,1:11])
ax.set_xticks(range(1,treino.iloc[:,1:11].shape[1]+1),treino.iloc[:,1:11].columns)
plt.show()
Obs. Tudo que estamos usando está disponível na documentação.
Observe que agora todas as escalas estão mais próximas!
Poderíamos nos aprofundar ainda mais nas colunas, mas nosso objetivo principal é mostrar para o recrutador que sabemos trabalhar com valores vazios, conseguimos fazer um ponta a ponta, conseguimos tratar colunas de texto e agora estamos demonstrando como fazer a escala nos dados!
Podemos já utilizar essa base no modelo para verificar o resultado
2º – Entendendo as colunas SibSp e Parch
Agora podemos entender as colunas SibSp e Parch:
Podemos verificar quantas pessoas sobreviveram em cada um dos valores dessa coluna.
Será que casais viajando possuem mais chances de sobreviver do que famílias com filhos? Podemos analisar nesses dados se existe algum padrão nessas informações. Sabemos que mulheres tiveram prioridade para se salvar, podemos buscar informações sobre o acidente e usar como base para analisar os dados.
Vamos começar agrupando esses dados? Assim tiramos a média desses sobreviventes.
# Verificando a sobrevivência para SibSp
SibSp_df = treino.groupby('SibSp')['Survived'].agg(['sum','count','mean']).reset_index()
SibSp_df.columns = ['SibSp','sobrev','total','tx_sobrev']
SibSp_df
O resultado mostra que 608 pessoas estavam viajando sozinhas e que dessas pessoas somente 210 sobreviveram, no código acima fizemos um DataFrame com os dados e renomeando o nome das colunas
# Verificando a sobrevivência para Parch
Parch_df = treino.groupby('Parch')['Survived'].agg(['sum','count','mean']).reset_index()
Parch_df.columns = ['Parch','sobrev','total','tx_sobrev']
Parch_df
Na tabela acima estamos verificando a mesma taxa de sobrevivência, mas dessa vez não entre cônjuges, mas entre pais e filhos usando o Parch_df
Observe que com 3 filhos a taxa de sobrevivência aumentou em relação a quem viajou sozinho.
Isso pode ter relação com a posição social da pessoa, pode ser que quem teve dinheiro para levar toda a família em uma viagem, tenha também recebido algum privilégio. Sabemos que houve privilégio para classes mais abonadas.
# Visualizando essas informações graficamente
fig, ax = plt.subplots(ncols=2,nrows=2,figsize=(10,6))
ax[0,0].plot(SibSp_df.SibSp, SibSp_df.sobrev)
ax[0,0].plot(SibSp_df.SibSp, SibSp_df.total)
ax[0,0].set_title('sobreviventes por nº de irmãos/cônjuges', fontsize=10)
labels1 = ax[0,1].bar(SibSp_df.SibSp, SibSp_df.tx_sobrev)
ax[0,1].bar_label(labels1,fmt="%.02f")
ax[0,1].set(ylim=(0,0.6))
ax[0,1].set_title('taxa de sobrevivência por nº de irmãos/cônjuges', fontsize=10)
ax[1,0].plot(Parch_df.Parch, Parch_df.sobrev)
ax[1,0].plot(Parch_df.Parch, Parch_df.total)
ax[1,0].set_title('sobreviventes por nº de pais/filhos', fontsize=10)
labels2 = ax[1,1].bar(Parch_df.Parch, Parch_df.tx_sobrev)
ax[1,1].bar_label(labels2,fmt="%.02f")
ax[1,1].set(ylim=(0,0.7))
ax[1,1].set_title('taxa de sobrevivência por nº de pais/filhos', fontsize=10)
plt.subplots_adjust(hspace=0.5)
plt.show()
Passageiros viajando sozinho tiveram um menor percentual de sobrevivência, pessoas que viajaram acompanhadas de mais uma pessoa tiveram uma maior taxa e depois o gráfico segue decrescendo.
Podemos criar uma coluna para identificar se o passageiro está viajando sozinho.
O que chama mais atenção neste gráfico é o baixo percentual de chance de sobrevivência de quem viaja sozinho. Posso usar essa informação para criar uma coluna e marcar essa pessoa, talvez isso ajude no nosso modelo pois estamos criando recursos e novas variáveis.
Vamos criar uma função simples que vai retornar 1 se a pessoa estiver viajando sozinha e 0 se estiver acompanhada.
Nossa função vai se chamar “sozinho”.
Após gerar os dados e colocar os resultados das colunas, vamos ver que não teve uma melhora na acurácia, ao contrário, o resultado piorou, vamos retornar ao ponto de partida para fazer novas verificações.
Isso não significa que essas colunas são inúteis, mas sim que precisamos usá-las de uma forma melhor -> Selecionando os melhores recursos.
# Criando uma função para verificar se os dois valores são vazios
def sozinho(a,b):
if (a == 0 and b == 0):
return 1
else:
return 0
# Aplicando essa função na base de treino
treino['Sozinho'] = treino.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
# Verificando os valores nessa coluna
treino.groupby('Sozinho')[['SibSp','Parch']].mean()
# Fazendo o mesmo para a base de teste
teste['Sozinho'] = teste.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
Podemos também criar uma coluna “Familiares” verificando o total de familiares a bordo
# Criando para a base de treino
treino['Familiares'] = treino.SibSp + treino.Parch
# E para a base de teste
teste['Familiares'] = treino.SibSp + treino.Parch
# Verificando a sobrevivência para Familiares
Familiares_df = treino.groupby('Familiares')['Survived'].agg(['sum','count','mean']).reset_index()
Familiares_df.columns = ['Familiares','sobrev','total','tx_sobrev']
Familiares_df
Observe que novamente 3 familiares tem um percentual de sobrevivência maior no modelo, este é um aspecto que também podemos observar.
Lucas, todos esses aspectos vão melhorar o modelo?
Não necessariamente, todo esse processo e engenharia de recursos são processos que temos que testar, gerar resultados, porém, muitos deles vamos abandonar pelo caminho por entender que não faz sentido ou não serve para o modelo.
O principal neste exercício é se acostumar a pensar nessa engenharia e explorar as possibilidades com o maior número de formas para garantir o melhor modelo.
Mas, quando sabemos que é hora de parar?
Você vai parar quando chegar no seu objetivo, lembra do que expliquei nas aulas anteriores a esta?
Você sempre tem que estabelecer uma nova meta para chegar em cima da última que você conseguiu, assim, de teste em teste você vai se tornar cada vez mais assertivo.
Da última aula até esta já aumentamos 10 pontos percentuais de acerto, se aumentarmos mais 10% já chegamos em 87%.
# Visualizando a informação de familiares
fig, ax = plt.subplots(ncols=2,figsize=(10,3))
ax[0].plot(Familiares_df.Familiares, Familiares_df.sobrev)
ax[0].plot(Familiares_df.Familiares, Familiares_df.total)
ax[0].set_title('sobreviventes por nº de familiares', fontsize=10)
labels1 = ax[1].bar(Familiares_df.Familiares, Familiares_df.tx_sobrev)
ax[1].bar_label(labels1,fmt="%.02f")
ax[1].set(ylim=(0,0.8))
ax[1].set_title('taxa de sobrevivência por nº de familiares', fontsize=10)
plt.show()
Podemos já utilizar essa base no modelo para verificar o resultado.
Selecionando os melhores recursos.
Primeiramente precisamos analisar qual a correlação entre as variáveis e verificar se não existem variáveis que estão basicamente “dizendo o mesmo”
# Visualizando a base
treino.head(3)
# Analisando a correlação entre as variáveis
treino.corr()
# Tornando a correlação mais visual
import seaborn as sns
fig, ax = plt.subplots(figsize=(10,5))
sns.heatmap(treino.corr(), annot=True, fmt=".2f")
plt.show()
Entendendo a relação entre Pclass e Fare, podemos ver no gráfico acima que existe uma correlação muito forte entre essas duas colunas.
Será que um passageiro de primeira classe pagou mais pelos seus ingressos?
Temos que verificar se esta linha de raciocínio faz sentido, para isso temos que verificar os dados!
# Visualizando a relação entre essas variáveis
fig, ax = plt.subplots(figsize=(10,3))
sns.boxplot(data=treino,x='Pclass',y='Fare',hue='Survived')
ax.set_title('Pclass x Fare', fontsize=10)
plt.show()
Assim que geramos o gráfico percebemos que existem pessoas na primeira classe que pagaram muito barato pelos seus ingressos, elas pagaram um valor equivalente a pessoas da 3ª classe.
A probabilidade de pessoas da segunda e terceira classe sobreviverem aqui é muito próxima porque os dados são muito próximos, mas comparado a primeira classe a diferença é grande. O gráfico mostra que pessoas da primeira classe tem mais chances de sobreviver.
Vamos verificar a taxa de sobrevivência em cada uma das classes
# Verificando a taxa de sobrevivência em cada uma das classes
treino.groupby('Pclass')['Survived'].mean()
Pclass
1 0.629630
2 0.472826
3 0.242363
Name: Survived, dtype: float64
# Entendendo a relação entre Pclass x Fare
treino.groupby(['Pclass','Survived'])['Fare'].agg(['min','mean','max'])
Nesse momento pode surgir a pergunta do motivo de termos pessoas pagando o mesmo preço em classes diferentes
Procurando no Kaggle, essa resposta ajuda a explicar um pouco:
“Se você conseguiu economizar e guardar todo o seu dinheiro para uma viagem para mudar sua vida e ir para a América, você é uma terceira classe, um imigrante que precisa trazer sua própria comida a bordo e ter em mente como suas provisões se sustentariam. A segunda classe era formada por trabalhadores de colarinho branco que podiam se dar ao luxo de viajar com um pouco de lazer, sem se preocupar com algo tão comum como comida. Primeira classe significa que você nasceu com dinheiro e não precisa sujar as mãos com o trabalho. Eles não eram separados apenas pelo custo, eles também eram separados por onde poderiam ir e o que recebiam.”
Também tem um link do Reddit que detalha bem essa questão de classe x preço
Podemos pensar em direcionar uma análise relacionando ao preço da cabine, porém essa variável possui 77.1% dos valores vazios
Entendendo sobre as colunas de embarque
Inicialmente pensamos não existir relação de ordem entre a coluna de embarque, mas pesquisando nesse artigo percebemos que existe, sim, essa correlação
“O Titanic deixou o porto de Southampton…Em seguida ele foi para Cherbourg-Octeville na França…em sua maioria da primeira classe. O Titanic então rumou para Queenstown na Irlanda…principalmente imigrantes da terceira classe que pretendiam tentar a vida nos Estados Unidos.”
Outro ponto importante que pode explicar o porquê pessoas pagaram pouco e ainda sim estavam na 1ª classe, é que uma empregada poderia ter uma passagem mais barata por viajar com seus patrões, filhos podiam pagar menos por estarem em uma viajem com os pais, pessoas que embarcaram nas últimas paradas do titanic podem ter pagado menos porque o trajeto também era menor a partir daquele ponto de embarque, existem diversas explicações possíveis.
No titanic não existiu um padrão de valor para 1ª,2ª e 3ª classe como acontece nos voos, neste caso devemos tomar cuidado porque não houve este padrão.
# Podemos importar novamente as bases para "recuperar" a coluna de embarque
treino2 = pd.read_csv('train.csv')
teste2 = pd.read_csv('test.csv')
treino2.head(3)
# Como temos valores vazios, podemos novamente fazer o tratamento dos dados
treino2['Embarked'] = treino2['Embarked'].fillna('S')
O que podemos fazer agora é colocar o porto em ordem de embarque (S depois C e depois Q)
Podemos fazer isso através do OrdinalEncoder, clique no link e veja a documentação.
Vamos organizar e identificar a ordem os portos que o titanic passou, vamos identificar como S, C e Q.
# Importando
from sklearn.preprocessing import OrdinalEncoder
# Criando o encoder
categorias = ['S','C','Q']
enc = OrdinalEncoder(categories=[categorias],dtype='int32')
# Fazendo o fit com os dados
enc = enc.fit(treino2[['Embarked']])
# Podemos então adicionar essa coluna na base de treino original
treino['Embarked'] = enc.transform(treino2[['Embarked']])
# E fazer o fit com os dados de teste
enc = enc.fit(teste2[['Embarked']])
# E adicionar na base de teste original
teste['Embarked'] = enc.transform(teste2[['Embarked']])
# Agora podemos eliminar as colunas desnecessárias
treino = treino.drop(['Embarked_C','Embarked_Q','Embarked_S'],axis=1)
teste = teste.drop(['Embarked_C','Embarked_Q','Embarked_S'],axis=1)
# Visualizando novamente a correlação
fig, ax = plt.subplots(figsize=(10,5))
sns.heatmap(treino.corr(), annot=True, fmt=".2f")
plt.show()
Entendendo agora as colunas de família
Podemos usar a regressão logística e a árvore de classificação para verificar a importância de cada uma dessas colunas
# Separando X e y
X = treino.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
# Usando a regressão logística nos dados
clf_rl = LogisticRegression(random_state=42,max_iter=1000).fit(X,y)
# Verificando a importância
clf_rl.coef_[0]
array([-1.03314773, -0.49645712, -0.26819737, 0.01690958, 0.04398615,
-2.5345877 , -0.73233826, -0.25128778, 0.23866778])
# Agora usando a árvore de classificação
clf_ac = tree.DecisionTreeClassifier(random_state=42).fit(X,y)
# Verificando a importância
clf_ac.feature_importances_
array([0.10901775, 0.22826711, 0.01907221, 0.0272942 , 0.23870173,
0.30933519, 0.00397775, 0.04365035, 0.02068372])
# Criando um DataFrame
imp = pd.DataFrame({
'colunas': X.columns,
'reg. log.': clf_rl.coef_[0],
'arvore': clf_ac.feature_importances_
})
imp
# Podemos apenas manter as colunas mais relevantes
treino = treino.drop(['SibSp','Parch'],axis=1)
teste = teste.drop(['SibSp','Parch'],axis=1)
# Visualizando a base
treino.head(3)
Podemos selecionar os mesmos modelos que vimos anteriormente (consulte arquivo da parte 1)
Árvore de classificação
https://scikit-learn.org/stable/modules/tree.html#classification
Classificação dos vizinhos mais próximos
Regressão Logística
Antes de usar os algoritmos, precisamos separar a base de treino em treino e validação
Vamos fazer isso utilizando o train_test_split
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
# Importando o train_test_split
from sklearn.model_selection import train_test_split
# Separando a base de treino em X e y
X = treino.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
# Separando em treino e validação
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=42)
Para a árvore de classificação
# Fazendo a importação
from sklearn import tree
# Criando o classificador
clf_ac = tree.DecisionTreeClassifier(random_state=42)
# Fazendo o fit com os dados
clf_ac = clf_ac.fit(X_train,y_train)
# Fazendo a previsão
y_pred_ac = clf_ac.predict(X_val)
# Importando
from sklearn.neighbors import KNeighborsClassifier
# Criando o classificador
clf_knn = KNeighborsClassifier(n_neighbors=3)
# Fazendo o fit com os dados
clf_knn = clf_knn.fit(X_train,y_train)
# Fazendo a previsão
y_pred_knn = clf_knn.predict(X_val)
# Importando
from sklearn.linear_model import LogisticRegression
# Criando o classificador
clf_rl = LogisticRegression(random_state=42,max_iter=1000)
# Fazendo o fit com os dados
clf_rl = clf_rl.fit(X_train,y_train)
# Fazendo a previsão
y_pred_rl = clf_rl.predict(X_val)
Vamos novamente avaliar os modelos
Acurácia (método de avaliação usado na competição):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
Matriz de confusão (ajuda a visualizar a distribuição dos erros):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html
Avaliando a acurácia
# Importando
from sklearn.metrics import accuracy_score
# Para a árvore
as_ac = accuracy_score(y_val, y_pred_ac)
as_ac
0.7491525423728813
# Para o knn
as_knn = accuracy_score(y_val, y_pred_knn)
as_knn
0.8
# Para a regressão logística
as_rl = accuracy_score(y_val, y_pred_rl)
as_rl
0.8169491525423729
A única diferença aqui é que estamos salvando cada informação dos modelos em uma nova variável, fazemos isso para poder guardar os valores que depois vamos reescrever.
Podemos salvar esses valores em um DataFrame para visualizarmos nossa evolução
# Criando primeiramente o DataFrame
# as_df = pd.DataFrame({
# 'modelos': ['arvore','knn','reg. log.'],
# 'inicial': [as_ac,as_knn,as_rl]
# })
#
# as_df
Por hora não estamos fazendo nada, apenas organizando os dados para poder comparar posteriormente.
# Adicionando novas colunas no DafaFrame
# as_df['escala'] = [as_ac,as_knn,as_rl]
# as_df['pessoas'] = [as_ac,as_knn,as_rl]
# as_df['colunas'] = [as_ac,as_knn,as_rl]
# Visualizando
as_df
O melhor modelo que temos é o modelo de regressão logística, podemos fazer a submissão
# Importando
from sklearn.metrics import confusion_matrix
# Para a árvore
confusion_matrix(y_val, y_pred_ac)
array([[138, 37],
[ 37, 83]], dtype=int64)
# Para o knn
confusion_matrix(y_val, y_pred_knn)
array([[152, 23],
[ 36, 84]], dtype=int64)
# Para a regressão logística
confusion_matrix(y_val, y_pred_rl)
array([[153, 22],
[ 32, 88]], dtype=int64)
Sempre que quisermos, podemos voltar e continuar fazendo os ajustes necessários na nossa base, até aqui tudo que rodamos foi visto na última aula, a partir de agora vamos ver mais sobre engenharia de recursos.
Fazendo a previsão para os dados de teste
Vamos usar o modelo com melhor precisão para fazer o predict na base de teste
# Visualizando o X_train
X_train.head(3)
# Visualizando a base de teste
teste.head(3)
# Para a base de teste ser igual à base de treino, precisamos eliminar a coluna de id
X_teste = teste.drop('PassengerId',axis=1)
# Utilizando a regressão logística na base de teste
y_pred = clf_rl.predict(X_teste)
# Criando uma nova coluna com a previsão na base de teste
teste['Survived'] = y_pred
# Selecionando apenas a coluna de Id e Survived para fazer o envio
base_envio = teste[['PassengerId','Survived']]
# Exportando para um csv
base_envio.to_csv('resultados_escala.csv',index=False)
# Exportando para um csv
base_envio.to_csv('resultados_escala.csv',index=False)
Resultado = 0.77
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Fala Impressionadores! Hoje vamos para aula 4 da nossa Análise do Titanic que é mais um Projeto de Ciência de Dados para o seu portfólio de projetos.
A ideia dessa aula é fazer uma seleção de novos algoritmos para melhorar a nossa pontuação, ou seja, vamos querer um resultado com uma acurácia maior do que já tínhamos nos exemplos anteriores.
Para isso nós vamos continuar usando a Regressão Logística, mas vamos acrescentar tanto o Random Forest quanto o MLPClassifier.
Feito isso nós vamos utilizar também o KFold e GridSeachCV para avaliar essas métricas.
Então o que nós vamos fazer é testar novos modelos e melhorar os parâmetros para melhorar nossos resultados!
Titanic – Machine Learning from Disaster
Vamos utilizar os dados disponíveis no Kaggle, este é um dataset de competição.
O resultado é avaliado através da acurácia:
“Sua pontuação é a porcentagem de passageiros que você prevê corretamente. Isso é conhecido como acurácia.”
Importando novamente as bases e fazendo o tratamento dos dados
Vamos apenas replicar o que fizemos no primeiro, segundo e terceiro arquivo dessa análise.
Depois vamos selecionar novos algoritmos para potencializar nosso modelo. A ideia é manter o resultado do algoritmo com melhor resultado na aula passada e acrescentar os modelos novos.
# Importando o pandas
import pandas as pd
# Visualizando a base de treino
treino = pd.read_csv('train.csv')
treino.head(3)
# Visualizando a base de teste
teste = pd.read_csv('test.csv')
teste.head(3)
Fazendo o mesmo tratamento inicial que fizemos nas colunas vazias
# Eliminando as colunas com elevada cardinalidade
treino = treino.drop(['Name','Ticket','Cabin'],axis=1)
teste = teste.drop(['Name','Ticket','Cabin'],axis=1)
# Usando a média para substituir valores nulos na coluna de idade
treino.loc[treino.Age.isnull(),'Age'] = treino.Age.mean()
teste.loc[teste.Age.isnull(),'Age'] = teste.Age.mean()
# Tratando a coluna Embarked da base de treino usando a moda
treino.loc[treino.Embarked.isnull(),'Embarked'] = treino.Embarked.mode()[0]
# E também a coluna Fare da base de teste usando a média
teste.loc[teste.Fare.isnull(),'Fare'] = teste.Fare.mean()
E fazendo a engenharia de variáveis dos nossos dados
# Usando uma lambda function para tratar a coluna "Sex"
treino['MaleCheck'] = treino.Sex.apply(lambda x: 1 if x == 'male' else 0)
teste['MaleCheck'] = teste.Sex.apply(lambda x: 1 if x == 'male' else 0)
# Fazendo o RobustScaler das colunas Age e Fare
from sklearn.preprocessing import RobustScaler
transformer = RobustScaler().fit(treino[['Age','Fare']])
treino[['Age','Fare']] = transformer.transform(treino[['Age','Fare']])
# e para a base de teste
transformer = RobustScaler().fit(teste[['Age','Fare']])
teste[['Age','Fare']] = transformer.transform(teste[['Age','Fare']])
# Adicionando a coluna sozinho
def sozinho(a,b):
if (a == 0 and b == 0):
return 1
else:
return 0
treino['Sozinho'] = treino.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
teste['Sozinho'] = teste.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
# E criando a coluna de familiares
treino['Familiares'] = treino.SibSp + treino.Parch
teste['Familiares'] = treino.SibSp + treino.Parch
# Fazendo o OrdinalEncoder para a coluna Embarked
from sklearn.preprocessing import OrdinalEncoder
categorias = ['S','C','Q']
enc = OrdinalEncoder(categories=[categorias],dtype='int32')
enc = enc.fit(treino[['Embarked']])
treino['Embarked'] = enc.transform(treino[['Embarked']])
teste['Embarked'] = enc.transform(teste[['Embarked']])
# Apagando as colunas de texto
treino = treino.drop('Sex',axis=1)
teste = teste.drop('Sex',axis=1)
Visualizando a base resultante
# Visualizando a base de treino
treino.head(3)
Podemos utilizar outros modelos para fazer a previsão
Podemos selecionar algoritmos diferentes dos que vimos nas partes anteriores (consulte arquivo da parte 1) considerando os outros algoritmos disponíveis no scikit-learn
Regressão Logística
Random Forest
MLPClassifier (Redes Neurais)
Antes de usar os algoritmos, precisamos separar a base de treino em treino e validação. Vamos fazer isso utilizando o train_test_split:
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
# Importando o train_test_split
from sklearn.model_selection import train_test_split
# Separando a base de treino em X e y
X = treino.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
Na base de treino o X será toda a base exceto as colunas PassengerID e Survived. Estamos usando o axis=1 para eliminar a coluna inteira.
# Separando em treino e validação
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=42)
Para a Regressão Logística
# Importando
from sklearn.linear_model import LogisticRegression
# Criando o classificador
clf_rl = LogisticRegression(random_state=42)
# Fazendo o fit com os dados
clf_rl = clf_rl.fit(X_train,y_train)
# Fazendo a previsão
y_pred_rl = clf_rl.predict(X_val)
Para o Random Forest
# Importando
from sklearn.ensemble import RandomForestClassifier
# Criando o classificador
clf_rf = RandomForestClassifier(random_state=42)
# Fazendo o fit com os dados
clf_rf = clf_rf.fit(X_train,y_train)
# Fazendo a previsão
y_pred_rf = clf_rf.predict(X_val)
E para o MLPClassifier (Redes Neurais)
# Importando
from sklearn.neural_network import MLPClassifier
# Criando o classificador
clf_mlp = MLPClassifier(random_state=42,max_iter=5000)
# Fazendo o fit com os dados
clf_mlp = clf_mlp.fit(X_train,y_train)
Quando fizer o fit com os dados vai notar que teremos um erro usando o parâmetro max, esse erro acontece porque o parâmetro chegou no máximo e não conseguiu convergir o modelo, ou seja, ele não conseguiu chegar no momento de parada.
Então devemos aumentar o valor na linha acima do classificador max_iter até que o parâmetro consiga rodar.
# Fazendo a previsão
y_pred_mlp = clf_mlp.predict(X_val)
Vamos novamente avaliar os modelos
Acurácia (método de avaliação usado na competição):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
Matriz de confusão (ajuda a visualizar a distribuição dos erros):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html
Avaliando a acurácia
# Importando
from sklearn.metrics import accuracy_score
# Para a Regressão Logística
accuracy_score(y_val, y_pred_rl)
0.8067796610169492
# Para o Random Forest
accuracy_score(y_val, y_pred_rf)
0.7898305084745763
# Para o MLPClassifier (Redes Neurais)
accuracy_score(y_val, y_pred_mlp)
0.8305084745762712
Avaliando a matriz de confusão para visualizar os erros
# Importando
from sklearn.metrics import confusion_matrix
# Para a Regressão Logística
confusion_matrix(y_val, y_pred_rl)
array([[152, 23],
[ 34, 86]], dtype=int64)
# Para o Random Forest
confusion_matrix(y_val, y_pred_rf)
array([[148, 27],
[ 35, 85]], dtype=int64)
# Para o MLPClassifier (Redes Neurais)
confusion_matrix(y_val, y_pred_mlp)
array([[160, 15],
[ 35, 85]], dtype=int64)
Fazendo a previsão para os dados de teste
Vamos usar o modelo com melhor precisão para fazer o predict na base de teste
# Visualizando o X_train
X_train.head(3)
# Visualizando a base de teste
teste.head(3)
# Para a base de teste ser igual à base de treino, precisamos eliminar a coluna de id
X_teste = teste.drop('PassengerId',axis=1)
# Utilizando o melhor modelo na base de teste
y_pred = clf_mlp.predict(X_teste)
# Criando uma coluna com a previsão na base de teste
teste['Survived'] = y_pred
# Selecionando apenas a coluna de Id e Survived para fazer o envio
base_envio = teste[['PassengerId','Survived']]
# Exportando para um csv
base_envio.to_csv('resultados8.csv',index=False)
Resultado: 0.698
Após exportar para um csv podemos submeter o resultado no Kaggle, podemos observar que o resultado piorou.
O resultado pode piorar?
Sim, isso pode acontecer, o importante é que você como cientista de dados saiba explicar o porquê da piora
Neste caso pode ter acontecido um Overfitting, neste caso o modelo está funcionando muito bem nos dados de treino e avaliação, mas não está funcionando nos dados de teste.
O que temos que fazer agora é garantir formas de não haver overfitting no modelo, vamos considerar o que fizemos até agora como parte 4 e abaixo vamos melhorar o modelo, vamos chamar de parte 5.
Importando novamente as bases e fazendo o tratamento dos dados
Vamos apenas replicar o que fizemos no primeiro, segundo e terceiro arquivo dessa análise (para visualizar os arquivos completos, visite esse link)
# Importando o pandas
import pandas as pd
# Visualizando a base de treino
treino = pd.read_csv('train.csv')
treino.head(3)
# Visualizando a base de teste
teste = pd.read_csv('test.csv')
teste.head(3)
Fazendo o mesmo tratamento inicial que fizemos nas colunas vazias
# Eliminando as colunas com elevada cardinalidade
treino = treino.drop(['Name','Ticket','Cabin'],axis=1)
teste = teste.drop(['Name','Ticket','Cabin'],axis=1)
# Usando a média para substituir valores nulos na coluna de idade
treino.loc[treino.Age.isnull(),'Age'] = treino.Age.mean()
teste.loc[teste.Age.isnull(),'Age'] = teste.Age.mean()
# Tratando a coluna Embarked da base de treino usando a moda
treino.loc[treino.Embarked.isnull(),'Embarked'] = treino.Embarked.mode()[0]
# E também a coluna Fare da base de teste usando a média
teste.loc[teste.Fare.isnull(),'Fare'] = teste.Fare.mean()
E fazendo a engenharia de variáveis dos nossos dados
# Usando uma lambda function para tratar a coluna "Sex"
treino['MaleCheck'] = treino.Sex.apply(lambda x: 1 if x == 'male' else 0)
teste['MaleCheck'] = teste.Sex.apply(lambda x: 1 if x == 'male' else 0)
# Fazendo o RobustScaler das colunas Age e Fare
from sklearn.preprocessing import RobustScaler
transformer = RobustScaler().fit(treino[['Age','Fare']])
treino[['Age','Fare']] = transformer.transform(treino[['Age','Fare']])
# e para a base de teste
transformer = RobustScaler().fit(teste[['Age','Fare']])
teste[['Age','Fare']] = transformer.transform(teste[['Age','Fare']])
# Adicionando a coluna sozinho
def sozinho(a,b):
if (a == 0 and b == 0):
return 1
else:
return 0
treino['Sozinho'] = treino.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
teste['Sozinho'] = teste.apply(lambda x: sozinho(x.SibSp,x.Parch),axis=1)
# E criando a coluna de familiares
treino['Familiares'] = treino.SibSp + treino.Parch
teste['Familiares'] = treino.SibSp + treino.Parch
# Fazendo o OrdinalEncoder para a coluna Embarked
from sklearn.preprocessing import OrdinalEncoder
categorias = ['S','C','Q']
enc = OrdinalEncoder(categories=[categorias],dtype='int32')
enc = enc.fit(treino[['Embarked']])
treino['Embarked'] = enc.transform(treino[['Embarked']])
teste['Embarked'] = enc.transform(teste[['Embarked']])
# Apagando as colunas de texto
treino = treino.drop('Sex',axis=1)
teste = teste.drop('Sex',axis=1)
Visualizando a base resultante
# Visualizando a base de treino
treino.head(3)
Podemos utilizar outros modelos para fazer a previsão
Podemos selecionar algoritmos diferentes dos que vimos nas partes anteriores (consulte arquivo da parte 1) considerando os (outros algoritmos disponíveis no scikit-learn](https://scikit-learn.org/stable/supervised_learning.html#supervised-learning)
Regressão Logística
Random Forest
MLPClassifier (Redes Neurais)
Agora, além do train_test_split:
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
Vamos usar também o grid_search para estimar os melhores parâmetros e tentar evitar o overfitting
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html
# Importando o train_test_split
from sklearn.model_selection import train_test_split
# Separando a base de treino em X e y
X = treino.drop(['PassengerId','Survived'],axis=1)
y = treino.Survived
# Separando em treino e validação
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
Observe que diminuímos o tamanho da base de teste para 0.2
Para a Regressão Logística
# Importando
from sklearn.linear_model import LogisticRegression
# Criando o classificador
clf_rl = LogisticRegression(random_state=42)
# Definindo os parâmetros
parametros_rl = {
'penalty': ['l1','l2'],
'C': [0.01,0.1,1,10],
'solver': ['lbfgs','liblinear','saga'],
'max_iter': [100,1000,5000,10000]
}
A parte de definir os parâmetros é a parte mais demorada do processo, temos que ir testando porque não podemos escolher todos ou o processo iria se tornar muito demorado, então vou deixar nos códigos os parâmetros que eu já havia testado.
Se você quiser se aprofundar. Pode pegar os outros parâmetros para ir testando um a um e conhecer melhor a biblioteca.
Você vai observar nos testes abaixo que quanto mais parâmetros usamos mais demora a rodar o código, então você deve escolher bem o parâmetro que vai utilizar
Para o Random Forest
# Importando
from sklearn.ensemble import RandomForestClassifier
# Criando o classificador
clf_rf = RandomForestClassifier(random_state=42)
# Definindo os parâmetros
parametros_rf = {
'n_estimators': [100,200,500,1000],
'criterion': ['gini','entropy','log_loss'],
'max_depth': [2,4,6,8,None],
'max_features': ['sqrt','log2',None]
}
E para o MLPClassifier (Redes Neurais)
# Importando
from sklearn.neural_network import MLPClassifier
# Criando o classificador
clf_mlp = MLPClassifier(random_state=42)
# Definindo os parâmetros
parametros_mlp = {
'solver': ['lbfgs','sgd','adam'],
'alpha': [10.0**(-1),10.0**(-5),10.0**(-7),10.0**(-10)],
'max_iter': [200,500,1000,5000]
}
Fazendo o grid_search
# Ignorando os avisos
import warnings
warnings.filterwarnings('ignore')
# Importando o datetime para visualizar a hora atual
from datetime import datetime
def hora_atual():
agora = datetime.now()
print(str(agora.hour)+':'+str(agora.minute)+":"+str(agora.second))
# Importando o KFold e o GridSearchCV
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold
# Para a Regressão Logística
hora_atual()
kfold_rl = KFold(shuffle=True,random_state=42,n_splits=8)
grid_search_rl = GridSearchCV(clf_rl, parametros_rl,scoring='accuracy',cv=kfold_rl)
grid_search_rl = grid_search_rl.fit(X_train,y_train)
hora_atual()
18:19:36
18:19:41
# Para o RandomForest
hora_atual()
kfold_rf = KFold(shuffle=True,random_state=42,n_splits=8)
grid_search_rf = GridSearchCV(clf_rf, parametros_rf,scoring='accuracy',cv=kfold_rf)
grid_search_rf = grid_search_rf.fit(X_train,y_train)
hora_atual()
18:20:16
18:31:5
# Para o MLPClassifier
hora_atual()
kfold_mlp = KFold(shuffle=True,random_state=42,n_splits=8)
grid_search_mlp = GridSearchCV(clf_mlp, parametros_mlp,scoring='accuracy',cv=kfold_mlp)
grid_search_mlp = grid_search_mlp.fit(X_train,y_train)
hora_atual()
18:31:5
18:37:36
Verificando os melhores scores
# Verificando o melhor score da regressão logística
grid_search_rl.best_score_
0.8089887640449438
# Para o RandomForest
grid_search_rf.best_score_
0.8314606741573034
# e para o MLPClassifier
grid_search_mlp.best_score_
0.8174157303370786
E os melhores parâmetros
# Verificando os melhores parâmetros da regressão logística
grid_search_rl.best_params_
{'C': 0.1, 'max_iter': 100, 'penalty': 'l2', 'solver': 'lbfgs'}
# Para o RandomForest
grid_search_rf.best_params_
{'criterion': 'entropy',
'max_depth': 6,
'max_features': 'sqrt',
'n_estimators': 100}
# e para o MLPClassifier
grid_search_mlp.best_params_
{'alpha': 0.1, 'max_iter': 200, 'solver': 'adam'}
Fazendo a previsão nos dados de validação com cada um dos melhores modelo
# Para a regressão logística
clf_best_rl = grid_search_rl.best_estimator_
y_pred_rl = clf_best_rl.predict(X_val)
# Para o RandomForest
clf_best_rf = grid_search_rf.best_estimator_
y_pred_rf = clf_best_rf.predict(X_val)
# e para o MLPClassifier
clf_best_mlp = grid_search_mlp.best_estimator_
y_pred_mlp = clf_best_mlp.predict(X_val)
Vamos novamente avaliar os modelos
Acurácia (método de avaliação usado na competição):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
Matriz de confusão (ajuda a visualizar a distribuição dos erros):
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html
Avaliando a acurácia
# Importando
from sklearn.metrics import accuracy_score
# Para a Regressão Logística
accuracy_score(y_val, y_pred_rl)
0.8044692737430168
# Para o Random Forest
accuracy_score(y_val, y_pred_rf)
0.8100558659217877
# Para o MLPClassifier (Redes Neurais)
accuracy_score(y_val, y_pred_mlp)
0.8100558659217877
Avaliando a matriz de confusão
# Importando
from sklearn.metrics import confusion_matrix
# Para a Regressão Logística
confusion_matrix(y_val, y_pred_rl)
array([[91, 14],
[21, 53]], dtype=int64)
# Para o Random Forest
confusion_matrix(y_val, y_pred_rf)
array([[93, 12],
[22, 52]], dtype=int64)
# Para o MLPClassifier (Redes Neurais)
confusion_matrix(y_val, y_pred_mlp)
array([[92, 13],
[21, 53]], dtype=int64)
Fazendo a previsão para os dados de teste
Vamos usar o modelo com melhor precisão para fazer o predict na base de teste
# Visualizando o X_train
X_train.head(3)
# Visualizando a base de teste
teste.head(3)
# Para a base de teste ser igual à base de treino, precisamos eliminar a coluna de id
X_teste = teste.drop('PassengerId',axis=1)
# Utilizando o melhor modelo na base de teste
y_pred = clf_best_rf.predict(X_teste)
# Criando uma nova coluna com a previsão na base de teste
teste['Survived'] = y_pred
# Selecionando apenas a coluna de Id e Survived para fazer o envio
base_envio = teste[['PassengerId','Survived']]
# Exportando para um csv
base_envio.to_csv('resultados10.csv',index=False)
Vamos submeter o resultado no Kaggle e verificar se houve melhora
Resultado = 0,7823
Conseguimos chegar em 0,78 que já é um bom resultado comparado ao inicial, pode ser que agora tentar aumentar esse valor vá exigir um esforço desproporcional e você deve avaliar se vale a pena.
Eu fico por aqui! Até a próxima aula!
Agora que fizemos a primeira avaliação deste teste recomendo que você trace uma meta para aumentar a assertividade do seu modelo.
Vamos fazer mais aulas como continuação desta e a cada aula desta série vamos tentar aumentar a assertividade do nosso modelo, cada vez nos aprofundando mais.
Lembrando que este desafio está sendo feito para que você possa colocar no seu portfólio, como muitas pessoas podem usá-lo, procure colocar sua linha de raciocínio escrita para que os recrutadores entendam que você conhece a lógica e sabe fazer as comparações.
Nas próximas aulas vamos nos aprofundar mais em cada coluna, recomendo que você também comece pelo básico e só depois vá propondo desafios que te façam entender um pouco a mais a cada dia.
Eu fico por aqui! Até a próxima!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Fala Impressionadores! Hoje vamos para aula 5 (última aula) da nossa Análise do Titanic que é mais um Projeto de Ciência de Dados para o seu portfólio de projetos.
Nessa aula eu quero te mostrar como fazer a apresentação do Projeto de Ciência de Dados, ou seja, vou te mostrar o passo a passo de como você vai montar essa apresentação.
Vamos criar um repositório no GitHub, vamos fazer o upload tanto dos arquivos utilizados quanto das imagens que serão utilizadas para apresentar o projeto.
Vou te ensinar como editar o arquivo Readme para que você possa explicar de forma detalhada cada parte do seu projeto, o que fez, como fez, quais os resultados em cada uma das partes.
Como fazer a edição desse arquivo de forma visual para realçar palavras-chave, colocar link dos seus arquivos, das imagens, do seu portfólio, e até mesmo de artigos que você tiver sobre o assunto.
Com tudo isso detalhado, o recrutador vai conseguir visualizar melhor o que você sabe e ainda tem fontes para pesquisar o que estiver com dúvida ou quiser se aprofundar no assunto!
Como o GitHub é uma ótima maneira de se destacar no mercado de trabalho atual, vou te mostrar os passos necessários para criar um projeto organizado no GitHub e como apresentar esse projeto da melhor forma no LinkedIn, Medium.
Passo 1: Criando um repositório no GitHub
O primeiro passo é acessar o site do GitHub e criar um repositório.
Você pode dar um nome para o repositório, por exemplo, “TitanicAula”, na descrição você pode informar que se trata de um repositório criado para a competição do Kaggle sobre o desastre que ocorreu no Titanic.
Lembre-se, o repositório deve estar público, pois seu objetivo é mostrar para outras pessoas.
Selecione também a opção do arquivo README para poder explicar passo a passo o que você desenvolveu em todo o processo.
Passo 2: Adicione os arquivos do projeto
Agora é o momento de adicionar os arquivos do projeto no seu repositório, aqui, você pode simplesmente arrastar os arquivos e fazer o upload para o GitHub.
Durante esse processo, você pode adicionar comentários para explicar o que está fazendo, por exemplo -> “adicionando os arquivos do projeto”.
Passo 3: Link os arquivos e crie uma apresentação
Após adicionar os arquivos, você pode começar a linkar e criar uma explicação clara sobre o projeto.
Você pode colocar um link para a competição do Kaggle e até mesmo adicionar imagens ao seu portfólio.
Por exemplo, se você já tem resultados em forma de gráficos, pode criar uma pasta para guardar as imagens e adicioná-las ao seu projeto por meio de tags de imagem. Isso tornará seu portfólio mais visual e atraente aos olhos dos recrutadores.
Para colocar o link você deve colocar a frase entre colchetes e dentro dos parênteses colocar o link da página que você quer mostrar.
Se você quiser destacar mais, coloque em negrito, basta colocar dois asteriscos em cada lado, se preferir itálico coloque apenas um asterisco ou se quiser negrito e itálico coloque 3 asteriscos.
Quando terminar, veja o resultado clicando em Preview.
Também é possível colocar imagens como este gráfico que fiz no PowerPoint
Podemos criar uma pasta no nosso portifólio -> add file -> creat new file -> o nome da pasta será -> IMG/ e vamos acrescentar a esta página um arquivo Readme. Feito isso, podemos arrastar as imagens para dentro desta pasta.
Para utilizar a imagem temos que usar o código:
<img src=” “ />
O código da imagem deve ser colocado entre as aspas do código acima.
Passo 4: Destacando as etapas do projeto
Na descrição do projeto, você pode destacar as etapas realizadas apresentando um histórico dos resultados.
Você pode adicionar links para as etapas específicas do projeto, de forma que o recrutador possa acessar cada uma delas caso tenha interesse em ver mais detalhes.
Para fazer esse destaque podemos colocar um link para cada etapa, como fizemos anteriormente.
Vamos escrever etapa 1 e colocar entre colchetes, nos parênteses colocamos o link do arquivo que subimos referente a etapa 1.
Note como está sendo ajustado o código do texto abaixo, para formatar o texto além de usar o asterisco para deixar as palavras em negrito ou itálico também podemos colocar o traço no início da frase para organizar as seções.
Resultado
Agora crie uma etapa para cada faze do seu projeto, além de colocar o link do Kaggle você ainda pode referenciar artigos que usou para uma base teórica, assim recrutadores e colegas interessados no seu projeto vão ver um portifólio organizado e de fácil compreensão.
Passo 5: Compartilhando seu projeto
Agora que o seu projeto está organizado e apresentável, é hora de compartilhá-lo com o mundo. Você pode divulgar o link do seu projeto no LinkedIn, no Medium e até mesmo enviar diretamente para os recrutadores que estão buscando profissionais na sua área de atuação.
Lembre-se de utilizar uma linguagem clara e objetiva ao fazer a apresentação do projeto, destacando seus pontos fortes e os resultados obtidos.
Utilizar o GitHub como uma forma de mostrar seus conhecimentos e habilidades é uma estratégia eficaz para se destacar no mercado de trabalho. Criar um projeto organizado, linkar os arquivos e apresentá-lo de forma clara e atrativa pode impressionar os recrutadores e aumentar suas chances de ser chamado para entrevistas e oportunidades profissionais.
Ficamos por aqui e até a próxima! Espero que tenham gostado dessa Série.
Para acessar outras publicações de Ciência de Dados, clique aqui!
Expert em conteúdos da Hashtag Treinamentos. Auxilia na criação de conteúdos de variados temas voltados para aqueles que acompanham nossos canais.