Hoofdstuk 28 — Data voorbereiden: preprocessing, Pipelines en ColumnTransformer
Let op: De tekst is in het Nederlands; alle Python codevoorbeelden zijn in het Engels.
Doelen:
- Standaardiseren, normaliseren en omgaan met missende waarden via transformers.
- Categorische variabelen encoderen met OneHotEncoder.
- Samengestelde preprocessing met ColumnTransformer en Pipelines.
Installatie:
pip install scikit-learn pandas numpy
28.1 Veelgebruikte transformers
- Imputers:
SimpleImputer,KNNImputer. - Schalen/normaliseren:
StandardScaler,MinMaxScaler,RobustScaler. - Encoders:
OneHotEncoder,OrdinalEncoder. - Feature selectors:
SelectKBest,VarianceThreshold.
28.2 Voorbeeld dataset en missende waarden
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
rng = np.random.default_rng(42)
N = 200
X = pd.DataFrame({
'age': rng.integers(18, 80, size=N),
'income': rng.normal(50000, 15000, size=N),
'city': rng.choice(['Ams', 'Rtm', 'Utr'], size=N),
'owns_house': rng.choice([0, 1], size=N)
})
# introduceer missend
X.loc[rng.choice(X.index, size=20, replace=False), 'income'] = np.nan
y = (X['age'] + (X['income'].fillna(50000)/1000) + 10*X['owns_house'] > 90).astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)
28.3 Kolommen scheiden in numeriek en categorisch
num_cols = ['age', 'income']
cat_cols = ['city', 'owns_house'] # owns_house als categorie (0/1)
28.4 ColumnTransformer met Pipelines
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
numeric_pipeline = Pipeline([
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
categorical_pipeline = Pipeline([
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
preprocess = ColumnTransformer([
('num', numeric_pipeline, num_cols),
('cat', categorical_pipeline, cat_cols)
])
clf = Pipeline([
('preprocess', preprocess),
('model', LogisticRegression(max_iter=1000))
])
clf.fit(X_train, y_train)
print('Accuracy (test):', clf.score(X_test, y_test))
28.5 Alternatieven en tips
- Voor robuustheid bij outliers:
RobustScaler. - Voor hoge cardinaliteit: overweeg target encoding (niet in scikit‑learn core) of hashing (
FeatureHasher). remainder='passthrough'inColumnTransformerom niet‑gespecificeerde kolommen door te laten.
28.6 Lekken voorkomen
- Fit alle preprocessing uitsluitend binnen de pipeline op
X_train. - Gebruik
cross_val_scoreop de volledige pipeline i.p.v. op voorbewerkte arrays.
28.7 Samenvatting
- Combineer Imputer/Scaler/Encoder per kolomgroep in Pipelines.
- Verbind deze met ColumnTransformer en sluit aan op een eindmodel.
- Train/evalueer altijd de gehele pipeline.