Ga naar hoofdinhoud

Kaggle-tutorial: EDA & Machine Learning

In deze Kaggle-tutorial leer je hoe je met behulp van exploratieve data-analyse (EDA) benaderde leermodellen bouwt op de Titanic-data.
· 10 min lezen

Verken met AI

Eerder deze maand deed ik een Facebook Live Code Along-sessie waarin ik (en iedereen die meekodeerde) verschillende algoritmes bouwde, van oplopende complexiteit, die voorspellen of een passagier op de Titanic overleefde of niet, gegeven gegevens zoals het tarief dat ze betaalden, waar ze aan boord gingen en hun leeftijd.

In deze post loop je door een aantal van de dingen die we in die sessie hebben behandeld. Als je de video opnieuw wilt bekijken of deze post wilt volgen samen met de video, kun je hem hier bekijken:

Specifiek herinner je je misschien nog dat we supervised learning-modellen bouwden.

Supervised learning is de tak van Machine Learning (ML) die labels voorspelt, zoals 'Overleefd' of 'Niet'. Zulke modellen leren van gelabelde data, oftewel data waarin staat of een passagier overleefde (dit heet "modeltraining"), en doen daarna voorspellingen op ongelabelde data.

Op Kaggle, een platform voor voorspellende modellen en analytics-wedstrijden, heten deze train- en testsets omdat

  • Je een model wilt bouwen dat patronen leert in de trainingsset, en
  • Je het model vervolgens gebruikt om voorspellingen te doen op de testset.

Kaggle vertelt je daarna het percentage dat je goed had: dit staat bekend als de nauwkeurigheid (accuracy) van je model.

Hoe begin je met Supervised Learning

Zoals je misschien al weet, is de volgende aanpak een goede manier om met supervised learning te starten:

  • Voer een Exploratory Data Analysis (EDA) uit op je dataset;
  • Bouw een snel en eenvoudig model, of een baseline-model, dat kan dienen als vergelijking met latere modellen die je bouwt;
  • Herhaal dit proces. Je doet meer EDA en bouwt nog een model;
  • Engineeer features: neem de features die je al hebt en combineer ze of haal er meer informatie uit om uiteindelijk tot het laatste punt te komen, namelijk
  • Krijg een model dat beter presteert.

In deze code along-sessie deed of doe je al deze stappen!

Let op dat we ook cursussen hebben die je op weg helpen met machine learning voor de Titanic-dataset in Python en R.

Importeer je data en kijk ernaar

Een eerste stap is altijd je data importeren om snel te bekijken met welke gegevens je gaat werken. In dit geval importeer je het pakket pandas en gebruik je de functie read_csv() om de data in te lezen:

Let op dat in de onderstaande codeblokken andere pakketten en modules zoals matplotlib, sklearn en seaborn al zijn geïmporteerd. Je gaat deze later uitgebreider gebruiken voor (statistische) datavisualisatie en machine learning!

Je gebruikt ook de IPython-magicopdracht %matplotlib inline zodat je grafieken inline in je notebook verschijnen. Je voegt ook sns.set() toe aan je codeblok om de visualisatiestijl te wijzigen naar een basis-Seaborn-stijl:

# 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()

Zonder verder oponthoud, laten we de data importeren en alvast de eerste stap zetten in het onderzoeken van je data:

# 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

Als je wilt zien wat al deze features zijn, bekijk dan de Kaggle-datadocumentatie hier.

Voordat je verdergaat, is het goed om het volgende qua terminologie in gedachten te houden:

  • De targetvariabele is de variabele die je probeert te voorspellen;
  • Andere variabelen staan bekend als "features" (of "predictorvariabelen", de features die je gebruikt om de targetvariabele te voorspellen).

Met dit in het achterhoofd kun je je data verder verkennen met bijvoorbeeld de functie head(), waarmee je de eerste vijf rijen van je dataset kunt opvragen:

# 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

Let op dat de DataFrame df_test geen kolom 'Survived' heeft, want dat is juist wat je gaat voorspellen!

  • Je kunt ook de DataFrame-methode .info() gebruiken om datatypen, ontbrekende waarden en meer te bekijken (van 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

In dit geval zie je dat er maar 714 non-null waarden zijn voor de kolom 'Age' in een DataFrame met 891 rijen. Dat betekent dat er 177 null of ontbrekende waarden zijn.

  • Gebruik ook de DataFrame-methode .describe() om samenvattende statistieken van numerieke kolommen te bekijken (van 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

Visuele Exploratory Data Analysis (EDA) en je eerste model

Nu je een idee hebt van hoe je data eruitziet en wat statistieken hebt bekeken, is het tijd om je data ook te visualiseren met behulp van het pakket seaborn:

  • Gebruik bijvoorbeeld seaborn om een staafdiagram te maken van overleving op de Titanic, jouw targetvariabele.
sns.countplot(x='Survived', data=df_train);

bar chart

Conclusie: in de trainingsset overleefden minder mensen dan niet. Laten we dan een eerste model bouwen dat voorspelt dat niemand overleefde.

Dit is een slecht model, want je weet dat er mensen overleefden. Maar het geeft ons een baseline: elk model dat we later bouwen, moet beter presteren dan dit.

Je kunt dit doen door deze stappen te volgen:

  • Maak een kolom 'Survived' voor df_test die 'niet overleefd' codeert voor alle rijen;
  • Sla de kolommen 'PassengerId' en 'Survived' van df_test op naar een .csv en dien in bij Kaggle.
df_test['Survived'] = 0
df_test[['PassengerId', 'Survived']].to_csv('data/predictions/no_survivors.csv', index=False)

Welke nauwkeurigheid leverde dit op? De nauwkeurigheid op Kaggle is 62,7.

kaggle

Niet slecht!

Belangrijke noot! Je wilt ook andere metrics dan accuracy gebruiken!

EDA op featurevariabelen

Nu je een snel-en-vies model hebt gemaakt, is het tijd om te herhalen: laten we wat meer Exploratory Data Analysis doen en gauw nog een model bouwen!

  • Je kunt seaborn gebruiken om een staafdiagram te maken van de Titanic-feature 'Sex' (van df_train).
sns.countplot(x='Sex', data=df_train);

bar plot

  • Gebruik ook seaborn om staafdiagrammen te maken van de Titanic-feature 'Survived', opgesplitst (gefacet) naar de feature 'Sex'.
sns.factorplot(x='Survived', col='Sex', kind='count', data=df_train);

bar plot

Conclusie: Vrouwen hadden een grotere overlevingskans dan mannen.

  • Met deze conclusie kun je met pandas uitzoeken hoeveel vrouwen en hoeveel mannen overleefden:
df_train.groupby(['Sex']).Survived.sum()
Sex
female    233
male      109
Name: Survived, dtype: int64
  • Gebruik pandas om het aandeel vrouwen dat overleefde te bepalen, samen met het aandeel mannen:
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% van de vrouwen overleefde, terwijl 19% van de mannen overleefde.

Laten we nu een tweede model bouwen en voorspellen dat alle vrouwen overleefden en alle mannen niet. Ook dit is een onrealistisch model, maar het biedt een baseline om toekomstige modellen mee te vergelijken.

  • Maak een kolom 'Survived' voor df_test die bovenstaande voorspelling codeert.
  • Sla de kolommen 'PassengerId' en 'Survived' van df_test op naar een .csv en dien in bij 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)

Welke nauwkeurigheid gaf dit model je toen je het bij Kaggle indiende?

De nauwkeurigheid op Kaggle is 76,6%:

kaggle

Met deze inzending steeg je ongeveer 2.000 plaatsen op het leaderboard! Ook heb je je score verbeterd, dus goed gedaan!

Verken je data verder!

  • Gebruik seaborn om staafdiagrammen te maken van de Titanic-feature 'Survived', opgesplitst (gefacet) naar de feature 'Pclass'.
sns.factorplot(x='Survived', col='Pclass', kind='count', data=df_train);

bar plot

Conclusie: Passagiers die in de eerste klasse reisden, hadden meer kans om te overleven. Aan de andere kant was het voor passagiers in de derde klasse onwaarschijnlijker dat ze overleefden.

  • Gebruik seaborn om staafdiagrammen te maken van de Titanic-feature 'Survived', opgesplitst (gefacet) naar de feature 'Embarked'.
sns.factorplot(x='Survived', col='Embarked', kind='count', data=df_train);

bar plot

Conclusie: Passagiers die in Southampton aan boord gingen, hadden minder kans om te overleven.

EDA met numerieke variabelen

  • Gebruik seaborn om een histogram te plotten van de kolom 'Fare' van df_train.
sns.distplot(df_train.Fare, kde=False);

histogram

Conclusie: De meeste passagiers betaalden minder dan 100 om met de Titanic te reizen.

  • Gebruik een pandas-plotmethode om de kolom 'Fare' voor elke waarde van 'Survived' in dezelfde plot te zetten.
df_train.groupby('Survived').Fare.hist(alpha=0.6);

bar plot

Conclusie: Het lijkt erop dat degenen die meer betaalden een grotere overlevingskans hadden.

  • Gebruik seaborn om een histogram te plotten van de kolom 'Age' van df_train. Je moet eerst null-waarden verwijderen.
df_train_drop = df_train.dropna()
sns.distplot(df_train_drop.Age, kde=False);

histogram

  • Plot een stripplot & een swarmplot van 'Fare' met 'Survived' op de x-as.
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

Conclusie: Fare lijkt zeker te correleren met overleven aan boord van de Titanic.

  • Gebruik de DataFrame-methode .describe() om samenvattende statistieken van 'Fare' te bekijken als functie van overleven.
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
  • Gebruik seaborn om een scatterplot te maken van 'Age' tegen 'Fare', ingekleurd op 'Survived'.
sns.lmplot(x='Age', y='Fare', hue='Survived', data=df_train, fit_reg=False, scatter_kws={'alpha':0.5});

scatter plot

Conclusie: Het lijkt erop dat degenen die overleefden ofwel behoorlijk wat voor hun ticket betaalden of jong waren.

  • Gebruik seaborn om een pairplot te maken van df_train, ingekleurd op 'Survived'. Een pairplot is een geweldige manier om het meeste van de informatie die je al hebt ontdekt in één raster van plots te tonen.
sns.pairplot(df_train_drop, hue='Survived');

plots

Van EDA naar Machine Learning-model

In deze tutorial heb je met succes:

  • onze data geladen en ernaar gekeken.
  • onze targetvariabele visueel verkend en je eerste voorspellingen gedaan.
  • enkele van onze featurevariabelen visueel verkend en betere voorspellingen gedaan op basis van onze EDA.
  • serieus EDA gedaan op featurevariabelen, zowel categorisch als numeriek.

In de volgende post neem je de tijd om enkele Machine Learning-modellen te bouwen, gebaseerd op wat je hier uit je EDA hebt geleerd. We doen dit in de volgende post over dit project (verschijnt op 27 december).

Onderwerpen

Gerelateerd