Datavoorbereiding en verkennende data-analyse
U laadt een onbewerkte dataset, brengt verdelingen en correlaties in kaart, identificeert problemen met de datakwaliteit en documenteert uw bevindingen in een reproduceerbare Jupyter-notebook.
Datavoorbereiding en verkennende data-analyse is een gratis Machine Learning Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Machine Learning Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Machine Learning Academy bevat in totaal 4 lessen.
Wat is verkennende gegevensanalyse?
Exploratory Data Analysis (EDA) is het in kaart brengen van een gegevensverzameling voordat je modellen bouwt, om de structuur, verdelingen, verbanden en kwaliteitsproblemen ervan te begrijpen. De term is bedacht door John Tukey. EDA volgt een eenvoudig principe: laat de gegevens spreken. EDA overslaan en direct modellen bouwen is, na een slechte probleembepaling, de meest voorkomende reden waarom ML-projecten mislukken. EDA voorkomt dat je modellen bouwt op gebrekkige fundamenten.
Gegevens laden en voor het eerst inspecteren
Begin altijd met een structurele inspectie: hoeveel rijen en kolommen zijn er, en welke gegevenstypen hebben ze? Gebruik df.shape, df.dtypes, df.head() en df.info(). Let op kolommen die numeriek lijken maar als object (tekenreeksen) zijn opgeslagen, en op kolommen die categorisch lijken maar als gehele getallen zijn gecodeerd. Niet-overeenkomende gegevenstypen veroorzaken later stille fouten wanneer scikit-learn een als geheel getal gecodeerde categorie behandelt als een continue variabele.
import pandas as pd
import numpy as np
# Load dataset
df = pd.read_csv('customer_churn.csv')
print('Shape:', df.shape)
print('\nData types:')
print(df.dtypes)
print('\nFirst 5 rows:')
print(df.head())
print('\nSummary info:')
df.info()Univariate analyse: verdelingen
Univariate analyse onderzoekt telkens één variabele. Maak voor numerieke kenmerken histogrammen en bereken samenvattende statistieken (gemiddelde, mediaan, standaardafwijking, scheefheid). Sterk scheve verdelingen (scheefheid > 2) zijn vaak gebaat bij een logtransformatie voordat je modellen bouwt. Maak voor categorische kenmerken staafdiagrammen van de waardeaantallen. Categorieën die in minder dan 1% van de rijen voorkomen, kunnen problemen veroorzaken bij one-hotcodering en gestratificeerd splitsen.
import matplotlib.pyplot as plt
import seaborn as sns
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# Numeric: histogram of account age
df['account_age_days'].hist(bins=40, ax=axes[0])
axes[0].set_title('Account age distribution')
axes[0].set_xlabel('Days')
# Categorical: churn rate by plan type
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')
plt.tight_layout()
plt.savefig('univariate.png', dpi=150)Tabel met samenvattende statistieken
df.describe() produceert voor elke numerieke kolom het aantal waarden, gemiddelde, standaardafwijking, minimum, kwartielen en maximum. Bekijk dit zorgvuldig: een maximumwaarde die ordes van grootte boven het 99e percentiel ligt, wijst op uitschieters. Een minimum van nul in een kolom met ‘dagen sinds de laatste aankoop’ kan betekenen dat de klant vandaag heeft gekocht — of het kan een aanduiding voor ontbrekende gegevens zijn. Als je deze randgevallen begrijpt, voorkom je stille fouten in latere voorbewerking.
stats = df.describe(percentiles=[0.01, 0.25, 0.5, 0.75, 0.99])
print(stats.T) # transpose for readability
# Flag suspicious columns
for col in df.select_dtypes(include='number').columns:
skew = df[col].skew()
pct99 = df[col].quantile(0.99)
max_val = df[col].max()
if max_val > 5 * pct99:
print(f'OUTLIER WARNING: {col} — max ({max_val:.1f}) >> 99th pct ({pct99:.1f}), skew={skew:.2f}')Analyse van ontbrekende waarden
Breng ontbrekende waarden in kaart voordat je beslissingen neemt over imputatie. Bereken het percentage nullen per kolom met df.isnull().mean(). Kolommen met meer dan 50% ontbrekende waarden moeten mogelijk volledig worden verwijderd. Begrijp het mechanisme achter de ontbrekende waarden: zijn ze volledig willekeurig ontbrekend (MCAR), of zijn ze niet-willekeurig ontbrekend (MNAR) — bijvoorbeeld omdat klanten die vertrokken hun accountgegevens hebben verwijderd? MNAR-ontbrekende waarden bevatten op zichzelf informatie en moeten als binaire indicator worden gecodeerd.
missing = df.isnull().mean().sort_values(ascending=False)
missing_pct = missing[missing > 0] * 100
print('Missing value percentages:')
print(missing_pct.round(1))
import matplotlib.pyplot as plt
missing_pct.plot(kind='barh', figsize=(8, 5))
plt.xlabel('% missing')
plt.title('Missing values by column')
plt.tight_layout()
plt.savefig('missing.png', dpi=150)Bivariate analyse: correlaties
Bivariate analyse onderzoekt verbanden tussen paren variabelen. Bereken voor relaties tussen numerieke variabelen een correlatiematrix en visualiseer die als een heatmap met seaborn.heatmap. Correlaties boven 0.95 tussen twee kenmerken wijzen op multicollineariteit — beide kenmerken bevatten vrijwel dezelfde informatie, dus één ervan kan worden verwijderd zonder voorspellende kracht te verliezen. Bereken ook punt-biseriële correlaties tussen numerieke kenmerken en het binaire doel, om vooraf de meest voorspellende kenmerken te identificeren.
import seaborn as sns
import matplotlib.pyplot as plt
numeric_df = df.select_dtypes(include='number')
corr = numeric_df.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0)
plt.title('Correlation matrix')
plt.tight_layout()
plt.savefig('corr_heatmap.png', dpi=150)
# Highest corr pairs (excluding self-correlation)
high_corr = (
corr.where(np.triu(np.ones(corr.shape), k=1).astype(bool))
.stack().abs().sort_values(ascending=False)
)
print('Top correlated pairs:')
print(high_corr.head(5))Analyse van de doelvariabele
Analyseer de doelvariabele altijd afzonderlijk. Bereken bij binaire classificatie het percentage van de positieve klasse (df['churned'].mean()). Percentages onder 5% of boven 95% wijzen op een ernstige scheefheid die de keuze van het algoritme en de evaluatiemaatstaven beïnvloedt. Controleer bij regressiedoelen de normaliteit — scheve doelen zijn vaak gebaat bij een logtransformatie vóór het trainen, vooral bij boomgebaseerde modellen die hiervoor ongevoelig zijn, maar ook bij lineaire regressie van groot belang is.
target = 'churned'
class_dist = df[target].value_counts(normalize=True)
print('Class distribution:')
print(class_dist)
print(f'\nPositive class rate: {df[target].mean():.3f}')
print(f'Imbalance ratio: {class_dist.max() / class_dist.min():.1f}:1')
# Visual
df[target].value_counts().plot(kind='bar')
import matplotlib.pyplot as plt
plt.title('Target class distribution')
plt.ylabel('Count')
plt.xticks([0, 1], ['Retained', 'Churned'], rotation=0)
plt.tight_layout()
plt.savefig('target_dist.png', dpi=150)Uitschieters detecteren en behandelen
Uitschieters kunnen het trainen van modellen vertekenen, vooral bij afstandsgebaseerde modellen (KNN, SVM) en lineaire regressie. Gebruik voor een eerste detectie de IQR-methode (waarden buiten [Q1 - 1.5·IQR, Q3 + 1.5·IQR] markeren) of de z-score (waarden met |z| > 3 markeren). Onderzoek elke gemarkeerde uitschieter: is het een invoerfout, een legitieme extreme waarde of een defecte sensor? Legitieme extreme waarden moet je behouden; fouten moet je corrigeren of verwijderen.
def iqr_outliers(series):
Q1, Q3 = series.quantile(0.25), series.quantile(0.75)
IQR = Q3 - Q1
lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
outlier_mask = (series < lower) | (series > upper)
return outlier_mask, lower, upper
for col in df.select_dtypes(include='number').columns:
mask, lo, hi = iqr_outliers(df[col])
n_out = mask.sum()
if n_out > 0:
print(f'{col}: {n_out} outliers ({n_out/len(df)*100:.1f}%), '
f'valid range=[{lo:.2f}, {hi:.2f}]')Grafieken van relaties tussen kenmerken en doel
Visualiseer bij classificatietaken hoe de verdeling van elk numeriek kenmerk verschilt tussen klassen met een vioolplot of boxplot, gegroepeerd op basis van het doel. Kenmerken waarvan de verdelingen tussen de twee klassen sterk verschillen, zijn waarschijnlijk voorspellend. Maak voor categorische kenmerken een gegroepeerd staafdiagram van het vertrekpercentage per categoriewaarde, om snel te zien welke categorieën samenhangen met een hoger risico.
import seaborn as sns
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# Numeric feature vs target: violin plot
sns.violinplot(
data=df, x='churned', y='account_age_days',
palette=['#2196F3', '#F44336'], ax=axes[0]
)
axes[0].set_xticklabels(['Retained', 'Churned'])
axes[0].set_title('Account age by churn status')
# Categorical feature vs target: bar plot
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')
plt.tight_layout()
plt.savefig('feature_target.png', dpi=150)EDA-bevindingen documenteren
EDA-bevindingen moeten worden gedocumenteerd in een reproduceerbaar Jupyter-notebook dat met het team wordt gedeeld. Documenteer minimaal: welke kolommen zijn verwijderd en waarom, beslissingen over imputatie per kolom, behandeling van uitschieters, de omvang van de scheefheid tussen klassen, de belangrijkste voorspellende kenmerken en eventuele problemen met de gegevenskwaliteit die aan het data-engineeringteam zijn gemeld. Dit notebook wordt het gedeelte over gegevenskwaliteit van de uiteindelijke modelkaart en is van onschatbare waarde bij het opsporen van regressies in productie, maanden later.
# EDA findings summary (add as a markdown cell in the notebook)
findings = {
'dropped_columns': ['customer_id (identifier)', 'last_login_ip (PII, not predictive)'],
'imputation': {
'days_since_support_contact': 'median (12% missing, MCAR)',
'contract_end_days': 'mode (3% missing)'
},
'outliers': 'total_spend: 14 values > $50k capped at 99th percentile ($48,200)',
'class_imbalance': '8.3% churn rate — use SMOTE or class_weight=balanced',
'top_features': ['days_since_last_purchase', 'total_spend_90d', 'support_tickets'],
'escalations': ['contract_type column has 847 unmapped legacy codes — check with engineering']
}
for key, val in findings.items():
print(f'{key}: {val}')Geautomatiseerde hulpmiddelen voor EDA
Bij grote gegevensverzamelingen met honderden kenmerken is handmatige EDA onpraktisch. ydata-profiling (voorheen pandas-profiling) genereert met één functieaanroep een interactief HTML-rapport met verdelingen, correlaties, ontbrekende waarden en waarschuwingen voor uitschieters voor elke kolom. sweetviz maakt vergelijkingsrapporten voor splitsingen in trainings- en testgegevens of segmenten van doelklassen. Gebruik deze hulpmiddelen als uitgangspunt, maar vul ze altijd aan met aangepaste grafieken die specifiek zijn voor het domein en gericht op de belangrijkste kenmerken.
# ydata-profiling: one line EDA report
# pip install ydata-profiling
from ydata_profiling import ProfileReport
profile = ProfileReport(
df,
title='Customer Churn EDA Report',
explorative=True
)
profile.to_file('eda_report.html')
print('Report saved to eda_report.html')
# sweetviz: compare train vs test distribution
# pip install sweetviz
import sweetviz as sv
report = sv.analyze(df, target_feat='churned')
report.show_html('sweetviz_report.html')Korte controle
Toets je begrip van de concepten uit deze les over Machine Learning with Python.
Samenvatting van de les
In deze les heb je geleerd dat EDA verdelingen, verbanden, ontbrekende waarden en uitschieters in kaart brengt voordat je modellen bouwt, dat bivariate analyse (correlaties en grafieken van kenmerken en doel) de meest voorspellende kenmerken identificeert, en dat EDA-bevindingen in een reproduceerbaar notebook moeten worden gedocumenteerd om beslissingen over voorbewerking te ondersteunen en als dossier voor de gegevenskwaliteit te dienen. Hierna voeren we een toernooi voor modelselectie uit om vijf algoritmen op dezelfde verwerkte gegevensverzameling te vergelijken.
Leer Python met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “Datavoorbereiding en verkennende data-analyse” gratis?
Ja — de volledige tekst van “Datavoorbereiding en verkennende data-analyse” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Machine Learning Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Machine Learning Academy bevat in totaal 4 lessen.
Wat leer ik in “Datavoorbereiding en verkennende data-analyse”?
U laadt een onbewerkte dataset, brengt verdelingen en correlaties in kaart, identificeert problemen met de datakwaliteit en documenteert uw bevindingen in een reproduceerbare Jupyter-notebook. Je oefent met Machine Learning Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Machine Learning Academy te beginnen?
Ervaring vooraf is niet nodig. Machine Learning Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.
Hoe lang duurt de les “Datavoorbereiding en verkennende data-analyse”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Machine Learning Academy?
Ja. Elke les over Machine Learning Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Projectafbakening: het probleem en de succescriteria definiëren
- Datavoorbereiding en verkennende data-analyse
- Toernooi voor modelselectie: vijf algoritmen vergelijken
- Het uiteindelijke model verpakken, documenteren en presenteren