15 geselecteerde klassieke machine learning interviewvragen, gegroepeerd per senioriteitsniveau. Gebruik ze om basisprincipes, praktische afwegingen en redeneringen op seniorniveau voor productieomgevingen door te nemen.
1Wat is het verschil tussen een modelparameter en een hyperparameter in gesuperviseerd leren?
In gesuperviseerd machine learning zijn modelparameters interne variabelen die direct uit trainingsgegevens worden geleerd via een optimalisatie-algoritme (zoals gradient descent of normaalvergelijkingen). Voorbeelden zijn de regressiegewichten en bias in lineaire modellen of splitsingsdrempels in beslissingsbomen. Hyperparameters daarentegen zijn externe configuratie-instellingen die vóór de training worden gespecificeerd en die het leerproces, de modelcapaciteit of de architectuur sturen. Ze kunnen niet direct worden geleerd via standaard minimalisatie van het trainingsverlies, omdat de optimizer anders triviaal overfitting zou veroorzaken (bijvoorbeeld door de boomdiepte oneindig te maken). Voorbeelden zijn de leersnelheid, regularisatiesterkte (lambda/C), het aantal bomen in een forest en de maximale boomdiepte. Hyperparameters worden afgestemd met behulp van validatiegegevens of kruisvalidatie.
from sklearn.linear_model import Ridge
import numpy as np
X = np.array([[1.0], [2.0], [3.0]])
y = np.array([2.0, 4.0, 6.0])
# Hyperparameter: alpha (regularization strength set beforehand)
model = Ridge(alpha=1.0)
# Fitting optimizes internal parameters on training data
model.fit(X, y)
# Learned parameters
print(f"Weight (Parameter): {model.coef_[0]:.4f}")
print(f"Intercept (Parameter): {model.intercept_:.4f}")
2Welke aannames maakt Ordinary Least Squares (OLS) lineaire regressie, en hoe zouden residudiagnostiek schendingen van deze aannames onthullen?
Ordinary Least Squares (OLS) lineaire regressie is gebaseerd op verschillende kern-aannames: 1. Lineariteit: De relatie tussen voorspellers en de uitkomst is lineair in parameters. 2. Onafhankelijkheid van fouten: Waarnemingen en residufouten zijn onderling onafhankelijk (geen autocorrelatie). 3. Homoscedasticiteit: Fouttermen hebben constante variantie over alle niveaus van voorspellers. 4. Normaliteit van residuen: Fouttermen zijn normaal verdeeld (vereist voor geldige betrouwbaarheidsintervallen en hypothesestests). 5. Geen multicollineariteit: Voorspellers zijn niet lineair afhankelijk (de ontwerpmatrix heeft volledige kolomrang). Residudiagnostiek onthult schendingen als volgt: - Residu's versus Voorspelde Waarden-plot: Kromming of niet-willekeurige patronen onthullen niet-lineariteit; een trechter- of waaierachtige vorm onthult heteroscedasticiteit (niet-constante variantie). - Normale Q-Q plot: Systematisch afwijken van de rechte diagonale lijn (bijv. S-curven of zware staarten) onthult niet-normaliteit. - Residu's versus Volgorde/Tijd-plot: Systematische trends of cyclische patronen onthullen autocorrelatie. - Leverage / Cook's Distance-plot: Identificeert outliers met hoge 'leverage' of invloedrijke punten die het aangepaste model onevenredig verschuiven.
import numpy as np
import statsmodels.api as sm
np.random.seed(42)
X = np.linspace(1, 10, 50)
# Quadratic underlying pattern creates a linearity violation
y = 2 * X + 0.5 * (X ** 2) + np.random.normal(0, 2, 50)
X_with_const = sm.add_constant(X)
model = sm.OLS(y, X_with_const).fit()
residuals = model.resid
print(f"Mean Residual: {np.mean(residuals):.4f}")
print(f"Curvature in residuals indicates model misspecification.")
3Hoe modelleert logistische regressie binaire classificatie, en wat is de rol van de sigmoidfunctie?
Logistische regressie modelleert binaire classificatie door de a posteriori klassewaarschijnlijkheid $P(Y=1|X)$ te schatten. Om ervoor te zorgen dat de voorspelde waarschijnlijkheden binnen $(0, 1)$ blijven, modelleert logistische regressie de log-odds (logit) van de positieve klasse als een lineaire functie van de invoer: $\ln\left(\frac{p}{1-p}\right) = w^T x + b$. De sigmoidfunctie (logistische functie), $\sigma(z) = \frac{1}{1 + e^{-z}}$, fungeert als de linkfunctie die elke reële lineaire score $z = w^T x + b \in (-\infty, +\infty)$ eentonig afbeeldt naar een geldige waarschijnlijkheid $p \in (0, 1)$. Discrete klassebeslissingen worden genomen door een beslissingsdrempel $\tau$ toe te passen (meestal 0.5): $\hat{y} = 1$ als $P(Y=1|X) \ge \tau$, anders $0$. Omdat $\sigma(z) = 0.5$ precies optreedt wanneer $z = 0$, is de beslissingsgrens in de feature space het lineaire hypervlak $w^T x + b = 0$, wat standaard logistische regressie een lineaire classifier maakt.
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
w = np.array([1.5, -2.0])
b = 0.5
x = np.array([2.0, 1.0])
z = np.dot(w, x) + b
prob = sigmoid(z)
threshold = 0.5
pred = int(prob >= threshold)
print(f"Log-odds (z): {z:.2f}")
print(f"Probability: {prob:.4f}")
print(f"Class Prediction: {pred}")
4Wat is L2-regularisatie, en hoe verandert Ridge-regressie de doelfunctie en coëfficiëntschattingen?
L2-regularisatie (Ridge-regressie) voegt een boete, evenredig met de som van de gekwadrateerde gewichten, toe aan de verliesfunctie van de gewone kleinste kwadraten (OLS): $$\min_w \|y - Xw\|_2^2 + \lambda \|w\|_2^2$$ Analytisch gezien wijzigt Ridge de normale vergelijkingen door $\lambda I$ toe te voegen aan de grammatrix vóór inversie: $$w_{\text{ridge}} = (X^T X + \lambda I)^{-1} X^T y$$ Belangrijkste effecten op de doelfunctie en coëfficiëntschattingen: 1. Krimp: Coëfficiënten worden naar nul gekrompen in verhouding tot feature-variantie en correlatie, wat de modelcomplexiteit vermindert zonder ze exact naar nul te dwingen. 2. Multicollineariteit en Inverteerbaarheid: Wanneer features collinear zijn of $p > N$, is $X^T X$ singulier of slecht geconditioneerd. Het toevoegen van $\lambda I$ zorgt ervoor dat $(X^T X + \lambda I)$ strikt positief definiet en inverteerbaar is, wat parameterschattingen stabiliseert. 3. Bias-variantie-afweging: Het verhogen van $\lambda$ introduceert opzettelijke bias in coëfficiëntschattingen terwijl de variantie aanzienlijk wordt verminderd, wat resulteert in een lagere verwachte generalisatiefout op ongeziene data. 4. Vereiste voor featureschaal: Omdat de boete alle gewichten gelijk behandelt, zouden features op grotere schalen disproportioneel worden geregulariseerd. Features moeten gestandaardiseerd (nul gemiddelde, eenheidsvariantie) zijn voorafgaand aan het fitten.
import numpy as np
def ridge_regression(X, y, alpha):
X_std = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
n_features = X_std.shape[1]
I = np.eye(n_features)
beta = np.linalg.inv(X_std.T @ X_std + alpha * I) @ X_std.T @ y
return beta
X = np.array([[1.0, 2.0], [2.0, 4.1], [3.0, 5.9], [4.0, 8.2]])
y = np.array([2.1, 4.0, 6.2, 8.1])
weights = ridge_regression(X, y, alpha=1.0)
print('Ridge Weights:', weights)
5Hoe partitioneert een beslissingsboom recursief de kenmerkruimte, en welke criteria worden gebruikt om classificatiesplitsingen te kiezen?
Een beslissingsboom partitioneert de kenmerkruimte via een top-down, gulzig algoritme genaamd **recursieve binaire partitionering**. Beginnend bij het hoofdknooppunt met alle trainingsdata, zoekt het algoritme over alle kenmerken en mogelijke drempelwaarden om de enkele as-georiënteerde splitsing ($X_j \le t$) te vinden die de reductie in onzuiverheid maximaliseert. De dataset wordt gesplitst in twee kindknooppunten, en deze procedure wordt recursief toegepast op elk kindknooppunt totdat een stopcriterium (bijv. maximale diepte, minimum aantal samples per blad of zuivere knooppunten) is bereikt. Omdat splitsingen één kenmerk tegelijk evalueren tegen een drempelwaarde, zijn de resulterende beslissingsgrenzen orthogonale hypervlakken (as-georiënteerde rechthoekige gebieden in de kenmerkruimte). Om de beste splitsing in classificatiebomen te evalueren en te selecteren, worden twee belangrijke onzuiverheidscriteria gebruikt:
1. **Gini-onzuiverheid (gebruikt in CART)**: Meet de waarschijnlijkheid dat een willekeurig gekozen sample verkeerd zou worden geclassificeerd indien willekeurig gelabeld volgens de klassenverdeling van het knooppunt. Voor $K$ klassen met proporties $p_k$: $$I_G = 1 - \sum_{k=1}^K p_k^2$$
2. **Entropie en Informatiewinst (gebruikt in ID3, C4.5)**: Entropie meet de onzekerheid in een knooppunt: $H = -\sum_{k=1}^K p_k \log_2(p_k)$. De splitsing wordt gekozen om de **Informatiewinst** te maximaliseren, wat de entropie van het ouderknooppunt is minus de gewogen gemiddelde entropie van de kindknooppunten: $$IG = H(\text{parent}) - \sum_{c \in \{\text{left, right}\}} \frac{N_c}{N} H(c)$$
Beide metrics bereiken 0 wanneer een knooppunt volledig zuiver is (alle samples behoren tot een enkele klasse) en bereiken hun maximum wanneer klassen gelijk verdeeld zijn.
6Wat is `k-Nearest Neighbors` (kNN) en hoe doet het voorspellingen voor classificatie en regressie?
`k-Nearest Neighbors` (kNN) is een niet-parametrisch, instance-based (`lazy`) gesuperviseerd leeralgoritme. Het traint geen expliciet parametrisch model; in plaats daarvan slaat het de trainingsdataset op en voert het alle berekeningen uit tijdens inferentie.
**Voorspellingsworkflow:**
1. **Afstandsberekening:** Wanneer een `query-instantie` wordt geëvalueerd, berekent het algoritme de afstand tot alle opgeslagen trainingsinstanties met behulp van een gespecificeerde metriek (zoals de Euclidische, Manhattan- of Minkowski-afstand).
2. **Buurselectie:** Het selecteert de $k$ trainingsinstanties met de kleinste afstanden tot de `query-instantie`.
3. **Aggregatie:**
* **Classificatie:** Het wijst de klasse toe via meerderheidsstemming (modus) onder de $k$ buren (of een afstandsgewogen stemming).
* **Regressie:** Het voorspelt de continue doelwaarde door het lokale gemiddelde (gemiddelde of mediaan) te nemen van de doelwaarden van de $k$ buren (of een afstandsgewogen gemiddelde).
Omdat afstandsberekeningen direct afhankelijk zijn van featureschalen, is feature-normalisatie of -standaardisatie essentieel om te voorkomen dat features met grote magnitudes de afstandsberekeningen domineren.
7Formuleer de voorwaardelijke onafhankelijkheidsaanname van naïeve Bayes en leg uit waarom naïeve Bayes nog steeds goed kan werken wanneer deze wordt geschonden.
De voorwaardelijke onafhankelijkheidsaanname van naïeve Bayes stelt dat, gegeven het klasselabel Y = y, alle features X_1, X_2, ..., X_d onderling onafhankelijk zijn: P(X_1, ..., X_d | Y = y) = \prod_{j=1}^d P(X_j | Y = y). Met behulp van de stelling van Bayes is de a-posteriori kans: P(Y = y | X) \propto P(Y = y) \prod_{j=1}^d P(X_j | Y = y), waarbij P(Y = y) de a-priori kans van de klasse is en P(X_j | Y = y) de klasse-conditionele waarschijnlijkheid (bijv. Gaussisch voor continue features, Multinominaal voor tellingen). Naïeve Bayes werkt in de praktijk vaak goed ondanks schendingen van onafhankelijkheid, omdat classificatie berust op de argmax-beslissingsregel (argmax_y P(Y=y | X)) in plaats van nauwkeurige kanscalibratie. Zelfs als feature-correlaties ertoe leiden dat voorspelde kansen overmoedig of vertekend worden, behoudt de juiste klasse vaak de hoogste relatieve rangschikking. Zolang de correlatie de rangschikking van klassewaarschijnlijkheden niet omdraait, blijft de 0-1 classificatiebeslissing accuraat.
from sklearn.naive_bayes import GaussianNB
import numpy as np
X = np.array([[1.0, 1.1], [1.2, 0.9], [-1.0, -1.2], [-0.8, -1.1]])
y = np.array([1, 1, 0, 0])
model = GaussianNB()
model.fit(X, y)
# Prediction uses argmax over class posterior scores
print("Predicted class:", model.predict([[1.1, 1.0]]))
8Leid de gesloten-vorm OLS (Ordinary Least Squares)-oplossing af of leg deze uit, en vermeld wanneer deze uniek bestaat.
De OLS (Ordinary Least Squares)-doelfunctie minimaliseert de som van de kwadraten van de residuen: $S(\beta) = \|y - X\beta\|^2 = (y - X\beta)^T (y - X\beta) = y^T y - 2\beta^T X^T y + \beta^T X^T X \beta$. Door de gradiënt met betrekking tot $\beta$ op nul te zetten, krijgen we: $$\nabla_\beta S(\beta) = -2 X^T y + 2 X^T X \beta = 0 \implies X^T X \beta = X^T y$$ Dit zijn de normale vergelijkingen. Wanneer $X^T X$ niet-singulier (invertibel) is, is de unieke gesloten-vorm oplossing: $$\hat{\beta} = (X^T X)^{-1} X^T y$$ Geometrisch gezien representeert $\hat{y} = X\hat{\beta} = X(X^T X)^{-1} X^T y = H y$ de orthogonale projectie van de doelvector $y$ op de kolomruimte van de ontwerpmatrix $X$, waarbij $H$ de projectie ('hat')-matrix is. De oplossing bestaat uniek als en slechts als $X^T X$ invertibel is, wat vereist dat de $N \times P$ ontwerpmatrix $X$ een volledige kolomrang heeft ($Rank(X) = P$). Dit vereist $N \ge P$ en geen exacte multicollineariteit (geen enkele feature is een lineaire combinatie van andere). Als $X$ rang-deficiënt is, is $X^T X$ singulier, wat leidt tot oneindig veel oplossingen, vaak aangepakt via regularisatie of de Moore-Penrose pseudoinverse $X^+ y$.
import numpy as np
# Design matrix X (with intercept column) and target y
X = np.array([[1, 1], [1, 2], [1, 3], [1, 4]])
y = np.array([2.1, 3.9, 6.2, 8.0])
# Normal equations: (X^T X)^(-1) X^T y
beta_hat = np.linalg.inv(X.T @ X) @ X.T @ y
H = X @ np.linalg.inv(X.T @ X) @ X.T
y_hat = H @ y
print(f"Beta: {beta_hat}")
print(f"Predictions: {y_hat}")
9Wat is maximale aannemelijkheidschatting (Maximum Likelihood Estimation) en hoe leidt dit tot de cross-entropy doelfunctie van logistische regressie?
Maximale Aannemelijkheidschatting (MLE) is een methode voor het schatten van modelparameters $\theta$ door waarden te kiezen die de aannemelijkheid $L(\theta) = P(\mathcal{D}|\theta)$ van de waargenomen dataset maximaliseren. In binaire logistische regressie wordt elk label $y_i \in \{0, 1\}$ gemodelleerd als een onafhankelijke Bernoulli-toevalsvariabele geconditioneerd op $x_i$, met een succeswaarschijnlijkheid $p_i = \sigma(w^T x_i + b)$. De waarschijnlijkheidsmassafunctie voor waarneming $i$ is $P(y_i|x_i) = p_i^{y_i} (1 - p_i)^{1 - y_i}$. Ervan uitgaande van onafhankelijke en identiek verdeelde (i.i.d.) steekproeven, is de gezamenlijke aannemelijkheid:
$$L(w, b) = \prod_{i=1}^N p_i^{y_i} (1 - p_i)^{1 - y_i}$$
Het nemen van de natuurlijke logaritme converteert het product naar een computationeel hanteerbare som van log-aannemelijkheden:
$$\ell(w, b) = \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$
Omdat optimalisatiealgoritmen standaard worden geformuleerd als minimalisatieproblemen, negeren we de log-aannemelijkheid en normaliseren we met de steekproefgrootte $N$, wat de Negatieve Log-Aannemelijkheid (NLL) oplevert, die exact de Binaire Cross-Entropy (log loss) doelfunctie is:
$$J(w, b) = -\frac{1}{N} \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$
Deze doelfunctie is convex ten opzichte van de lineaire logits/gewichten, zodat geschikte numerieke oplossers een globale doelfunctie optimaliseren. Strikte convexiteit en een eindige unieke MLE vereisen aanvullende voorwaarden, zoals voldoende feature-rang, regularisatie en geen perfecte klassescheiding.
10Hoe optimaliseert gradiëntdaling een klassiek ML-doel, en hoe beïnvloeden leersnelheid, convergentie en convexiteit de training?
Gradiëntdaling minimaliseert een empirische verliesfunctie door iteratief modelparameters bij te werken in de tegenovergestelde richting van de gradiënt van de objectieffunctie ten opzichte van die parameters: $\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)$. Belangrijke factoren die de training beïnvloeden zijn: 1. Leersnelheid ($\eta$): Bepaalt de stapgrootte. Indien te klein ingesteld, is de convergentie buitengewoon traag en kan de training stagneren. Indien te groot ingesteld, zullen updates het minimum voorbijschieten, wat oscillatie of numerieke divergentie veroorzaakt. 2. Convergentie: Wordt bepaald door het monitoren van stopcriteria zoals een kleine gradiëntnorm ($||\nabla L(\theta)|| \le \epsilon$), minimale parameterverschuiving, of een plateau van het verlies over opeenvolgende iteraties. 3. Convexiteit: Bij convexe doelstellingen (bijv. standaard OLS lineaire regressie of logistische regressie) is elk lokaal minimum gegarandeerd een globaal minimum, waardoor gradiëntdaling betrouwbaar kan convergeren met passende stapgroottes. Bij niet-convexe doelstellingen (bijv. meerlaagse neurale netwerken) bevat het verlieslandschap meerdere lokale minima, zadelpunten en plateaus, waardoor de uiteindelijke oplossing gevoelig is voor initialisatie. 4. Optimalisatie versus generalisatie: Convergentie op het trainingsverlies weerspiegelt optimalisatiesucces, terwijl validatieverlies generalisatie evalueert. Het bereiken van een laag trainingsverlies met een hoge validatiefout duidt op overfitting in plaats van een optimalisatiefout.
import numpy as np
def gradient_descent(X, y, lr=0.01, max_iters=1000, tol=1e-6):
n_samples, n_features = X.shape
theta = np.zeros(n_features)
prev_loss = float('inf')
for i in range(max_iters):
predictions = X @ theta
error = predictions - y
loss = (1 / (2 * n_samples)) * np.dot(error, error)
if abs(prev_loss - loss) < tol:
print(f'Converged at iteration {i}')
break
prev_loss = loss
grad = (1 / n_samples) * (X.T @ error)
theta -= lr * grad
return theta
11Vergelijk L1-, L2- en ElasticNet-regularisatie wat betreft sparsiteit, gecorreleerde features en praktische modelselectie.
L1 (Lasso), L2 (Ridge) en ElasticNet-regularisatie verschillen in strafformulering, beperkingsgeometrie, sparsiteit en de omgang met gecorreleerde predictoren:
1. Sparsiteit & Geometrie:
- L1 gebruikt een absolute waardestraf ($\lambda \|w\|_1$). De beperkingsgrens is een ruit/polytoop met scherpe hoekpunten op de coördinaatassen. Wanneer de verliescontouren deze hoeken snijden, worden gewichten naar exact nul gedreven, wat leidt tot geautomatiseerde feature-selectie.
- L2 gebruikt een gekwadrateerde Euclidische normstraf ($\lambda \|w\|_2^2$). De beperkingsgrens is een gladde hypersfeer zonder hoeken, die gewichten asymptotisch naar nul krimpt, maar ze zelden exact nul maakt.
2. Gecorreleerde Features:
- Bij sterke collineariteit heeft L1 de neiging willekeurig één feature uit een groep gecorreleerde predictoren te kiezen en de overige coëfficiënten op nul te zetten, wat resulteert in onstabiele schattingen over resamplingen.
- L2 behoudt alle gecorreleerde features, verdeelt gewichten ertussen en krimpt ze samen.
3. ElasticNet:
- Combineert beide straffen: $\lambda_1 \|w\|_1 + \lambda_2 \|w\|_2^2$ (vaak geparameteriseerd met $\alpha$ en $l_1\_\text{ratio}$).
- Levert de sparsiteit en feature-selectie van Lasso terwijl het groeperingseffect van Ridge behouden blijft, waarbij clusters van gecorreleerde predictoren samen worden geselecteerd. Het is bijzonder nuttig wanneer $p > N$ of bij ernstige multicollineariteit.
12Wat is op hoofdlijnen het verschil tussen Ridge-regressie, Principal Component Regression (PCR) en Partial Least Squares (PLS)?
Ridge-regressie, Principal Component Regression (PCR) en Partial Least Squares (PLS) zijn drie lineaire technieken die worden gebruikt om multicollineariteit en hoge dimensionaliteit aan te pakken, maar ze verschillen in hoe ze de variatie verminderen en of de reductie continu of gesuperviseerd is:
1. Ridge-regressie: Behoudt alle originele $p$ features en past continue krimp toe op de coëfficiëntmagnitudes via een L2-straf. Het construeert geen lager-dimensionale latente componenten of verwerpt geen feature-dimensies; in plaats daarvan krimpt het de variatie langs richtingen met lage eigenwaarde van $X^T X$.
2. Principal Component Regression (PCR): Een tweestaps, niet-gesuperviseerde dimensionaliteitsreductiemethode. Het past eerst Principal Component Analysis (PCA) strikt toe op de predictor-matrix $X$ om orthogonale richtingen van maximale variatie te vinden, behoudt de top $k$ hoofdcomponenten, en past een OLS (Ordinary Least Squares)-regressie toe op die $k$ componenten. Omdat PCA de doelvariabele $y$ negeert, riskeert PCR componenten te verwerpen die een lage variatie hebben in $X$ maar een hoge voorspellende kracht voor $y$.
3. Partial Least Squares (PLS): Een gesuperviseerde dimensionaliteitsreductiemethode. Het construeert $k$ orthogonale latente componenten door lineaire combinaties van $X$ te vinden die de covariantie tussen $X$ en de respons $y$ maximaliseren. Door expliciet target-informatie op te nemen, identificeert PLS componenten die zowel feature-variatie als respons-variatie verklaren.
from sklearn.linear_model import Ridge, LinearRegression
from sklearn.decomposition import PCA
from sklearn.cross_decomposition import PLSRegression
from sklearn.pipeline import make_pipeline
# 1. Ridge: Regularized full feature space
ridge = Ridge(alpha=1.0)
# 2. PCR: Unsupervised PCA followed by OLS
pcr = make_pipeline(PCA(n_components=2), LinearRegression())
# 3. PLS: Supervised latent component projection and regression
pls = PLSRegression(n_components=2)
13Hoe optimaliseren moderne gradiënt-boosting-implementaties zoals XGBoost, LightGBM en CatBoost de training of verwerken ze tabulaire kenmerken anders?
Moderne GBDT-frameworks verschillen aanzienlijk in hun split-zoekalgoritmen, boomgroeistrategieën en verwerking van tabulaire/categorische kenmerken:
1. **XGBoost**: Vertrouwt traditioneel op exacte gierige of benaderende kwantielschets split-finding (en later Fast Hist), gebruikt niveau-gewijze (diepte-gewijze) boomgroei en behandelt ontbrekende waarden door een optimale standaardtakrichting te leren tijdens het zoeken naar splitsingen.
2. **LightGBM**: Maakt gebruik van op histogram gebaseerde split-finding (het groeperen van continue kenmerken in discrete buckets, meestal 256), blad-gewijze (best-first) boomgroei voor snellere verliesreductie, Gradient-based One-Side Sampling (GOSS) om instanties met grote gradiënten te behouden terwijl die met kleine gradiënten worden gesampled, en Exclusive Feature Bundling (EFB) om wederzijds exclusieve schaarse kenmerken samen te voegen. Voor categorische variabelen vindt het optimale splitsingen door categorische histogram-bins te sorteren ($O(K \log K)$).
3. **CatBoost**: Gebruikt oblivious (symmetrische) beslissingsbomen waarbij alle knooppunten op een gegeven diepte exact dezelfde splitsing delen, wat snelle gevectoriseerde CPU/GPU-scoring mogelijk maakt. De primaire innovatie is Ordered Target Statistics en geordende boosting, die doelstatistieken berekent over willekeurige permutaties van trainingsgegevens om target leakage en prediction shift te voorkomen.
14Hoe zou u beslissen of een aangepaste verliesfunctie geschikt is voor een gradient boosting-model onder asymmetrische bedrijfskosten?
Beslissen of een aangepaste verliesfunctie moet worden geïmplementeerd in gradient boosting onder asymmetrische bedrijfskosten, vereist een evaluatie of de asymmetrie stroomafwaarts kan worden afgehandeld via waarschijnlijkheidskalibratie en drempelinstelling, of dat het het optimalisatielandschap tijdens boominferentie fundamenteel verandert: 1. Drempelinstelling versus Aangepaste Verliesfunctie: Voor classificatietaken met asymmetrische foutkosten (bijv. valse negatieven $10\times$ duurder dan valse positieven) is standaard cross-entropie een juiste scoringsregel die probeert achterafwaarschijnlijkheden $P(y=1|x)$ te schatten, maar kalibratie moet worden gecontroleerd en, indien nodig, gecorrigeerd op validatiegegevens. Het verschuiven van de classificatiebeslissingsdrempel op basis van de bedrijfskostenmatrix $\tau = \frac{C_{FP}}{C_{FP} + C_{FN}}$ of het toepassen van steekproefgewichten is vaak schoner en vermijdt aangepaste afgeleiden. Echter, voor asymmetrische regressie (bijv. asymmetrische pinball-verliesfunctie voor voorraadbehoeften) of niet-lineaire bedrijfssancties waarbij standaarddoelstellingen geen leidraad kunnen bieden voor het vinden van splitsingen, is een aangepaste verliesfunctie gerechtvaardigd. 2. Wiskundige vereisten voor GBDT (Gradient Boosting Decision Trees): In second-order boosters (XGBoost, LightGBM) vereist een aangepaste verliesfunctie $L(y, \hat{y})$ normaal gesproken berekenbare eerste-orde gradiënten ($g_i = \partial L / \partial \hat{y}_i$) en geldige tweede-orde kromming/Hessian-waarden ($h_i = \partial^2 L / \partial \hat{y}_i^2$) voor split gain en bladgewichtberekeningen ($w^* = -\sum g_i / (\sum h_i + \lambda)$). Hessians moeten niet-negatief zijn of veilig worden benaderd/afgekapt voor numerieke stabiliteit; sommige implementaties ondersteunen eerste-orde of benaderende doelstellingen, dus de vereiste is framework-specifiek. Niet-differentieerbare of discontinue bedrijfscijfers moeten worden vervangen door vloeiende surrogaatbenaderingen (bijv. Huberized of log-cosh varianten).
import numpy as np
import xgboost as xgb
def asymmetric_mse_objective(preds, dtrain):
labels = dtrain.get_label()
residual = preds - labels
# Penalize underestimation (residual < 0) 5x more heavily than overestimation
penalty = np.where(residual < 0, 5.0, 1.0)
grad = 2.0 * penalty * residual
hess = 2.0 * penalty
return grad, hess
# Usage:
# model = xgb.train(params, dtrain, obj=asymmetric_mse_objective)
15Wat is LambdaMART, en hoe past het gradiënt boosting aan voor Learning-to-Rank (LTR)-doelstellingen?
LambdaMART is een Learning-to-Rank (LTR) algoritme dat MART (Multiple Additive Regression Trees / Gradiënt Boosting) combineert met het LambdaRank framework. Bij rangschikking zijn doelmetrieken zoals NDCG (Normalized Discounted Cumulative Gain) en MAP (Mean Average Precision) afhankelijk van de discrete sorteervolgorde (rangen), waardoor ze bijna overal vlak zijn en niet-differentieerbaar ten opzichte van continue modelscores. LambdaMART omzeilt dit door virtuele gradiënten, genaamd 'lambda-gradiënten' ($\lambda_{ij}$), te construeren voor paren van items $(i, j)$ binnen dezelfde query. De basis paarsgewijze gradiënt komt van een logistische verliesfunctie op scoreverschillen ($s_i - s_j$). LambdaMART schaalt deze gradiënt met de exacte verandering in de doelrangschikkingsmetriek ($|\Delta \text{NDCG}_{ij}|$) die zou optreden als de posities van document $i$ en document $j$ zouden worden verwisseld: $$\lambda_{ij} = \frac{-\sigma}{1 + e^{\sigma(s_i - s_j)}} |\Delta \text{NDCG}_{ij}|$$ Voor elk individueel document $i$ wordt de netto gradiënt berekend door paarsgewijze lambda's te aggregeren over alle paren waarbij document $i$ betrokken is: $\lambda_i = \sum_{j: j \succ i} \lambda_{ij} - \sum_{k: i \succ k} \lambda_{ki}$. Standaard regressiebomen in het boosting-ensemble passen vervolgens deze samengestelde lambda-gradiënten per document aan bij elke boosting-iteratie, waardoor lijstgewijze rangschikkingsmetrieken direct worden geoptimaliseerd.
import lightgbm as lgb
import numpy as np
# Simulated query-grouped data: 2 queries with 3 docs each
X = np.random.randn(6, 10)
y = np.array([3, 1, 0, 2, 0, 1]) # Relevance grades (0-3)
group = [3, 3] # Query group sizes
train_data = lgb.Dataset(X, label=y, group=group)
params = {
'objective': 'lambdarank',
'metric': 'ndcg',
'ndcg_eval_at': [1, 3],
'learning_rate': 0.1,
'n_estimators': 50
}
ranker = lgb.train(params, train_data)