Vorbereitung auf klassische ML-Interviews

Klassische Machine-Learning-Ingenieur-Interviewfragen

15 ausgewählte klassische Machine-Learning-Interviewfragen, gruppiert nach Erfahrungsstufe. Nutzen Sie diese zur Überprüfung von Grundlagen, praktischen Abwägungen und dem produktionsrelevanten Denken auf Senior-Niveau.

Klassisches ML KI-Interview startenKeine Kreditkarte erforderlich. 1 kostenlose Sitzung verfügbar.
Technisches Interview-Training auf EnglischEin Modus, in dem Nicht-Muttersprachler technische Interviews üben können.

Junior-Fragen

1Was unterscheidet einen Modellparameter von einem Hyperparameter beim überwachten Lernen?

Modellparameter sind interne Variablen, die ein Optimierungsverfahren wie Gradientenabstieg oder Normalgleichungen direkt aus Trainingsdaten bestimmt. Beispiele sind Regressionsgewichte und Konstantglied linearer Modelle oder Teilungsschwellen von Entscheidungsbäumen. Hyperparameter sind dagegen vor dem Training festgelegte Konfigurationen für Lernprozess, Modellkapazität oder Architektur. Sie werden normalerweise außerhalb der inneren Parameterschätzung gewählt. Manche lassen sich durch validierungsbasierte oder andere äußere Optimierungsschleifen bestimmen; die Unterscheidung bedeutet nicht, dass sie mathematisch unlernbar wären. Alleinige Minimierung des Trainingsfehlers kann übermäßige Kapazität begünstigen und schätzt keine Generalisierung. Beispiele sind Lernrate, Regularisierungsstärke lambda/C, Anzahl der Bäume im Zufallswald und maximale Baumtiefe. Ihre Abstimmung erfolgt mit Validierungsdaten oder Kreuzvalidierung.

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}")
Diese Frage mit einem KI-Coach beantworten

2Welche Annahmen macht die lineare Regression mit gewöhnlichen kleinsten Quadraten, und wie zeigen Residuenanalysen Verletzungen dieser Annahmen?

Die Methode der gewöhnlichen kleinsten Quadrate (OLS) minimiert quadrierte Residuen; zur Berechnung einer Anpassung sind normalverteilte Fehler nicht erforderlich. Für einen eindeutigen Koeffizientenvektor braucht die Designmatrix vollen Spaltenrang: Exakte lineare Abhängigkeit ist ausgeschlossen, nicht jede Korrelation zwischen Prädiktoren. Für die übliche Interpretation als unverzerrtes lineares Modell wird ein korrekt spezifizierter bedingter Mittelwert E[y|X] = X beta angenommen, gleichbedeutend mit E[epsilon|X] = 0. Homoskedastische, unkorrelierte Fehler liefern die klassische Gauss-Markov-Effizienzaussage und Standard-Kovarianzformel. Bedingte Normalverteilung ermöglicht zusätzlich exakte t-/F-Inferenz in endlichen Stichproben. Geeignete asymptotische oder robuste Methoden können unter eigenen Annahmen darauf verzichten. Geschätzte Residuen sind Fehlerschätzer und im Allgemeinen korreliert, selbst wenn die zugrunde liegenden Fehler unabhängig sind. Stellen Sie Residuen gegen angepasste Werte dar, um Krümmung und Varianzänderungen zu erkennen, gegen Zeit für Abhängigkeit und im Quantil-Quantil-Diagramm (Q-Q-Plot) für Verteilungsabweichungen. Hebelwerte (Leverage) und Cook-Distanz markieren einflussreiche Beobachtungen. Diese Diagnosen liefern Hinweise, beweisen aber weder Exogenität noch das Fehlen ausgelassener Störgrößen.

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.")
Diese Frage mit einem KI-Coach beantworten

3Wie modelliert die logistische Regression die binäre Klassifikation, und welche Rolle spielt dabei die Sigmoidfunktion?

Die logistische Regression modelliert die binäre Klassifikation, indem sie die A-posteriori-Klassenwahrscheinlichkeit $P(Y=1|X)$ schätzt. Um sicherzustellen, dass die vorhergesagten Wahrscheinlichkeiten im Bereich $(0, 1)$ bleiben, modelliert die logistische Regression die Log-Odds (Logit) der positiven Klasse als lineare Funktion der Eingaben: $\ln\left(\frac{p}{1-p}\right) = w^T x + b$. Die Sigmoid- (logistische) Funktion, $\sigma(z) = \frac{1}{1 + e^{-z}}$, dient als Linkfunktion, die einen beliebigen reellwertigen linearen Score $z = w^T x + b \in (-\infty, +\infty)$ monoton in eine gültige Wahrscheinlichkeit $p \in (0, 1)$ abbildet. Diskrete Klassenentscheidungen werden durch Anwenden einer Entscheidungsschwelle $\tau$ (typischerweise 0,5) getroffen: $\hat{y} = 1$, wenn $P(Y=1|X) \ge \tau$, andernfalls $0$. Da $\sigma(z) = 0.5$ genau dann auftritt, wenn $z = 0$, ist die Entscheidungsgrenze im Merkmalsraum die lineare Hyperebene $w^T x + b = 0$, was die Standard-Logistische Regression zu einem linearen Klassifikator macht.

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}")
Diese Frage mit einem KI-Coach beantworten

4Was ist L2-Regularisierung, und wie verändert Ridge-Regression die Zielfunktion und Koeffizientenschätzungen?

L2-Regularisierung beziehungsweise Ridge ergänzt die Verlustfunktion der gewöhnlichen kleinsten Quadrate (OLS) um die Summe quadrierter Gewichte: min_w ||y − Xw||₂² + λ||w||₂². In den Normalgleichungen wird λI zur Gram-Matrix addiert: w_ridge = (XᵀX + λI)^{-1}Xᵀy. 1. Schrumpfung: Koeffizienten werden abhängig von Merkmalsvarianzen und Korrelationen in Richtung null verkleinert. Das reduziert Komplexität, ohne sie exakt auf null zu setzen. 2. Multikollinearität und Invertierbarkeit: Bei kollinearen Merkmalen oder p > N ist XᵀX singulär beziehungsweise schlecht konditioniert. Für λ > 0 ist XᵀX + λI strikt positiv definit und invertierbar, was die Schätzung stabilisiert. 3. Bias-Varianz-Abwägung: Ein größeres λ führt im üblichen Modell mit festem Design gezielt Verzerrung ein und senkt Varianz. Der Vorhersagenutzen hängt vom Problem und der Stärke ab; wählen Sie diese durch Validierung. 4. Skalierung: Da alle Gewichte gleich bestraft werden, erzielt ein numerisch größeres Merkmal denselben Effekt mit kleinerem und weniger bestraftem Koeffizienten. Standardisierung hilft meist bei vergleichbarer Bestrafung, ist aber eine Modellierungsentscheidung und keine mathematische Voraussetzung. Bestimmen Sie Skalierung nur auf den jeweiligen Trainingsanteilen der Kreuzvalidierung und lassen Sie den Achsenabschnitt gewöhnlich unbestraft.

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)
Diese Frage mit einem KI-Coach beantworten

5Wie unterteilt ein Entscheidungsbaum den Merkmalsraum rekursiv, und welche Kriterien werden verwendet, um Klassifikations-Splits auszuwählen?

Ein Entscheidungsbaum unterteilt den Merkmalsraum durch einen Top-Down-, Greedy-Algorithmus, der als **rekursive binäre Partitionierung** bezeichnet wird. Beginnend am Wurzelknoten mit allen Trainingsdaten sucht der Algorithmus über alle Merkmale und möglichen Schwellenwerte hinweg nach dem einzelnen achsenparallelen Split ($X_j \le t$), der die Reduzierung der Unreinheit maximiert. Der Datensatz wird in zwei Kindknoten aufgeteilt, und dieses Verfahren wird rekursiv auf jeden Kindknoten angewendet, bis ein Abbruchkriterium erreicht ist (z. B. maximale Tiefe, Mindestanzahl an Samples pro Blatt oder reine Knoten). Da Splits jeweils ein Merkmal gegen einen Schwellenwert bewerten, sind die resultierenden Entscheidungsgrenzen orthogonale Hyperebenen (achsenparallele rechteckige Regionen im Merkmalsraum). Zur Bewertung und Auswahl des besten Splits in Klassifikationsbäumen werden zwei Hauptkriterien für die Unreinheit verwendet: 1. **Gini-Unreinheit (verwendet in CART)**: Misst die Wahrscheinlichkeit, dass ein zufällig ausgewähltes Sample falsch klassifiziert würde, wenn es zufällig gemäß der Klassenverteilung des Knotens beschriftet würde. Für $K$ Klassen mit Proportionen $p_k$: $$I_G = 1 - \sum_{k=1}^K p_k^2$$ 2. **Entropie und Informationsgewinn (verwendet in ID3, C4.5)**: Entropie misst die Unsicherheit in einem Knoten: $H = -\sum_{k=1}^K p_k \log_2(p_k)$. Der Split wird so gewählt, dass der **Informationsgewinn** maximiert wird, der der Entropie des Elternknotens abzüglich der gewichteten mittleren Entropie der Kindknoten entspricht: $$IG = H(\text{parent}) - \sum_{c \in \{\text{left, right}\}} \frac{N_c}{N} H(c)$$ Beide Metriken erreichen 0, wenn ein Knoten vollständig rein ist (alle Samples gehören zu einer einzigen Klasse), und ihr Maximum, wenn die Klassen gleichmäßig verteilt sind.

import numpy as np

def gini(labels):
    _, counts = np.unique(labels, return_counts=True)
    p = counts / len(labels)
    return 1.0 - np.sum(p ** 2)

def entropy(labels):
    _, counts = np.unique(labels, return_counts=True)
    p = counts / len(labels)
    return -np.sum(p * np.log2(p + 1e-12))

# Evenly split node (impure) vs single-class node (pure)
impure_node = np.array([0]*10 + [1]*10)
pure_node = np.array([0]*20)

print(f"Impure - Gini: {gini(impure_node):.2f}, Entropy: {entropy(impure_node):.2f}")
print(f"Pure   - Gini: {gini(pure_node):.2f}, Entropy: {entropy(pure_node):.2f}")
Diese Frage mit einem KI-Coach beantworten

6Was ist das Verfahren der k nächsten Nachbarn (kNN), und wie sagt es Klassen oder Zahlenwerte voraus?

kNN ist ein überwachtes, nichtparametrisches Verfahren, das direkt auf gespeicherten Trainingsbeispielen beruht. Es passt vorab kein parametrisches Modell an. Bei einer Anfrage berechnet es die Abstände zu den Trainingsbeispielen, etwa nach euklidischer, Manhattan- oder Minkowski-Distanz, und wählt die $k$ nächstgelegenen aus. Für die Klassifikation nimmt es die häufigste Klasse oder gewichtet Stimmen nach Abstand. Für die Regression verwendet es den Mittelwert oder Median der Zielwerte beziehungsweise einen abstandsgewichteten Mittelwert. Da die Merkmalsmaßstäbe in die Abstände eingehen, werden Merkmale oft normiert oder standardisiert, damit große Zahlenbereiche die Auswahl der Nachbarn nicht beherrschen.

from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
from sklearn.preprocessing import StandardScaler
import numpy as np

X_train = np.array([[1000.0, 1.0], [2000.0, 2.0], [1500.0, 1.5], [5000.0, 5.0]])
y_cls = np.array([0, 0, 0, 1])
y_reg = np.array([10.0, 20.0, 15.0, 50.0])

# Feature scaling is mandatory for distance-based algorithms
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)

# 1. Classification (Majority Vote)
clf = KNeighborsClassifier(n_neighbors=3)
clf.fit(X_scaled, y_cls)

# 2. Regression (Local Average)
reg = KNeighborsRegressor(n_neighbors=3)
reg.fit(X_scaled, y_reg)

query = scaler.transform([[1800.0, 1.8]])
print('Classification:', clf.predict(query))
print('Regression:', reg.predict(query))
Diese Frage mit einem KI-Coach beantworten

7Welche bedingte Unabhängigkeit setzt Naive Bayes voraus, und warum kann das Verfahren auch bei einer Verletzung dieser Annahme gut funktionieren?

Bei gegebenem Klassenlabel $Y=y$ sind die Merkmale $X_1,\ldots,X_d$ nach der Naive-Bayes-Annahme gemeinsam unabhängig: $P(X_1,\ldots,X_d\mid Y=y)=\prod_{j=1}^d P(X_j\mid Y=y)$. Mit dem Satz von Bayes folgt $P(Y=y\mid X)\propto P(Y=y)\prod_{j=1}^d P(X_j\mid Y=y)$. Dabei ist $P(Y=y)$ die A-priori-Wahrscheinlichkeit der Klasse und $P(X_j\mid Y=y)$ die klassenbedingte Likelihood, etwa aus einer Gaußverteilung für stetige Merkmale oder einer Multinomialverteilung für Zählwerte. Für die Klassifikation zählt, welche Klasse die höchste A-posteriori-Wahrscheinlichkeit hat ($\arg\max_y P(Y=y\mid X)$). Korrelationen zwischen Merkmalen können die Wahrscheinlichkeiten verzerren oder zu überhöhter Konfidenz führen. Solange die korrekte Klasse an erster Stelle bleibt, bleibt auch die Klassifikationsentscheidung korrekt.

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]]))
Diese Frage mit einem KI-Coach beantworten

Middle-Fragen

8Leiten Sie die geschlossene Lösung der Kleinste-Quadrate-Methode (OLS) her oder erklären Sie sie, und geben Sie an, wann sie eindeutig existiert.

Die Zielfunktion der Kleinste-Quadrate-Methode (OLS – Ordinary Least Squares) minimiert die Residuenquadratsumme: $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$. Setzt man den Gradienten bezüglich $\beta$ auf null: $$\nabla_\beta S(\beta) = -2 X^T y + 2 X^T X \beta = 0 \implies X^T X \beta = X^T y$$ Dies sind die Normalengleichungen. Wenn $X^T X$ nicht-singulär (invertierbar) ist, ist die eindeutige geschlossene Lösung: $$\hat{\beta} = (X^T X)^{-1} X^T y$$ Geometrisch stellt $\hat{y} = X\hat{\beta} = X(X^T X)^{-1} X^T y = H y$ die orthogonale Projektion des Zielvektors $y$ auf den Spaltenraum der Designmatrix $X$ dar, wobei $H$ die Projektionsmatrix (Hut-Matrix) ist. Die Lösung existiert genau dann eindeutig, wenn $X^T X$ invertierbar ist, was erfordert, dass die $N \times P$-Designmatrix $X$ vollen Spaltenrang ($Rank(X) = P$) hat. Dies wiederum erfordert $N \ge P$ und keine exakte Multikollinearität (kein Feature ist eine Linearkombination anderer). Wenn $X$ rang-defizient ist, ist $X^T X$ singulär, was zu unendlich vielen Lösungen führt, was oft durch Regularisierung oder die Moore-Penrose-Pseudoinverse $X^+ y$ angegangen wird.

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}")
Diese Frage mit einem KI-Coach beantworten

9Was ist die Maximum-Likelihood-Schätzung, und wie ergibt sich daraus die binäre Kreuzentropie als Zielfunktion der logistischen Regression?

Bei der Maximum-Likelihood-Schätzung (MLE) wählt man die Parameter $\theta$ so, dass die Likelihood $L(\theta)=P(\mathcal D\mid\theta)$ der beobachteten Daten maximal wird. In der binären logistischen Regression ist das Label $y_i\in\{0,1\}$ bei gegebenem $x_i$ Bernoulli-verteilt mit Erfolgswahrscheinlichkeit $p_i=\sigma(w^Tx_i+b)$. Die Wahrscheinlichkeit des beobachteten Labels ist $p_i^{y_i}(1-p_i)^{1-y_i}$. Für unabhängige, identisch verteilte Stichproben ergibt sich $L(w,b)=\prod_{i=1}^N p_i^{y_i}(1-p_i)^{1-y_i}$. Der natürliche Logarithmus macht daraus die Summe $\ell(w,b)=\sum_{i=1}^N[y_i\ln p_i+(1-y_i)\ln(1-p_i)]$. Für die Minimierung negiert man die Log-Likelihood und teilt durch $N$. So erhält man die binäre Kreuzentropie (Log-Loss) $J(w,b)=-\frac1N\sum_{i=1}^N[y_i\ln p_i+(1-y_i)\ln(1-p_i)]$. Die Zielfunktion ist in den Gewichten und im Achsenabschnitt konvex und lässt sich mit geeigneten numerischen Verfahren global optimieren. Strikte Konvexität und die Existenz einer endlichen eindeutigen Lösung hängen von weiteren Bedingungen ab, etwa vom Rang der Merkmalsmatrix und von der Trennbarkeit der Klassen. Auch Regularisierung beeinflusst diese Eigenschaften.

import numpy as np

y_true = np.array([1, 0, 1, 1])
y_prob = np.array([0.9, 0.2, 0.8, 0.4])

# Binary cross-entropy (Negative Log-Likelihood)
epsilon = 1e-15  # prevent log(0)
y_prob = np.clip(y_prob, epsilon, 1 - epsilon)
bce_loss = -np.mean(y_true * np.log(y_prob) + (1 - y_true) * np.log(1 - y_prob))

print(f"Binary Cross-Entropy Loss: {bce_loss:.4f}")
Diese Frage mit einem KI-Coach beantworten

10Wie optimiert der Gradientenabstieg ein klassisches ML-Ziel (Machine Learning), und wie beeinflussen Lernrate, Konvergenz und Konvexität das Training?

Der Gradientenabstieg minimiert eine empirische Verlustfunktion, indem er Modellparameter iterativ in die entgegengesetzte Richtung des Gradienten der Zielfunktion in Bezug auf diese Parameter aktualisiert: $\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)$. Wichtige Faktoren, die das Training beeinflussen, sind: 1. Lernrate ($\eta$): Steuert die Schrittgröße. Wenn sie zu klein gewählt wird, ist die Konvergenz extrem langsam und das Training kann stagnieren. Wenn sie zu groß gewählt wird, überschreiten die Aktualisierungen das Minimum, was zu Oszillation oder numerischer Divergenz führt. 2. Konvergenz: Wird durch die Überwachung von Abbruchkriterien wie einer kleinen Gradientennorm ($||\nabla L(\theta)|| \le \epsilon$), minimaler Parameterverschiebung oder einem Verlustplateau über aufeinanderfolgende Iterationen hinweg bestimmt. 3. Konvexität: Bei konvexen Zielen (z.B. Standard-OLS-Linearregression oder logistischer Regression) ist jedes lokale Minimum garantiert auch ein globales Minimum, was dem Gradientenabstieg ermöglicht, mit geeigneten Schrittgrößen zuverlässig zu konvergieren. Bei nicht-konvexen Zielen (z.B. mehrschichtigen neuronalen Netzen) enthält die Verlustlandschaft mehrere lokale Minima, Sattelpunkte und Plateaus, wodurch die endgültige Lösung empfindlich auf die Initialisierung reagiert. 4. Optimierung vs. Generalisierung: Die Konvergenz des Trainingsverlustes spiegelt den Optimierungserfolg wider, während der Validierungsverlust die Generalisierungsfähigkeit bewertet. Ein niedriger Trainingsverlust bei hohem Validierungsfehler deutet auf Overfitting hin und nicht auf einen Optimierungsfehler.

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
Diese Frage mit einem KI-Coach beantworten

11Vergleichen Sie L1-, L2- und Elastic-Net-Regularisierung hinsichtlich dünn besetzter Koeffizienten, korrelierter Merkmale und praktischer Modellwahl.

L1 (Lasso) verwendet den Strafterm $\lambda\|w\|_1$. Die zulässige Menge hat in zwei Dimensionen die Form einer Raute und in höheren Dimensionen die eines Polytops mit Ecken auf den Koordinatenachsen. Trifft eine Niveaulinie der Verlustfunktion eine solche Ecke, werden Koeffizienten exakt null, wodurch Merkmale ausgewählt werden. L2 (Ridge) verwendet $\lambda\|w\|_2^2$. Die glatte Begrenzung ist eine Hypersphäre. Die Koeffizienten werden in Richtung null verkleinert und selten exakt null. Bei stark korrelierten Merkmalen wählt L1 oft eines aus und setzt die übrigen Koeffizienten auf null. Die Wahl kann zwischen Stichproben schwanken. L2 behält korrelierte Merkmale meist gemeinsam bei und verteilt die verkleinerten Gewichte unter ihnen. Elastic Net kombiniert $\lambda_1\|w\|_1+\lambda_2\|w\|_2^2$, häufig mit einer Gesamtstärke $\alpha$ und dem Mischparameter l1_ratio. Es verbindet Merkmalsauswahl mit der Möglichkeit, Gruppen korrelierter Merkmale gemeinsam auszuwählen. Das ist besonders nützlich bei mehr Merkmalen als Beobachtungen ($p>N$) oder starker Multikollinearität.

from sklearn.linear_model import Ridge, Lasso, ElasticNet
import numpy as np

np.random.seed(42)
X1 = np.random.randn(100, 1)
X2 = X1 + np.random.randn(100, 1) * 0.01  # highly correlated
X = np.hstack([X1, X2])
y = 3 * X1.ravel() + np.random.randn(100) * 0.1

ridge = Ridge(alpha=1.0).fit(X, y)
lasso = Lasso(alpha=0.1).fit(X, y)
elastic = ElasticNet(alpha=0.1, l1_ratio=0.5).fit(X, y)

print('Ridge coefs:', ridge.coef_)
print('Lasso coefs:', lasso.coef_)
print('ElasticNet coefs:', elastic.coef_)
Diese Frage mit einem KI-Coach beantworten

12Was ist auf hoher Ebene der Unterschied zwischen Ridge-Regression, Principal Component Regression (PCR) und Partial Least Squares (PLS)?

Ridge-Regression, Principal Component Regression (PCR) und Partial Least Squares (PLS) sind drei lineare Techniken, die zur Handhabung von Multikollinearität und hoher Dimensionalität eingesetzt werden. Sie unterscheiden sich jedoch darin, wie sie die Varianz reduzieren und ob die Reduktion kontinuierlich oder überwacht ist: 1. **Ridge-Regression:** Behält alle ursprünglichen $p$ Merkmale bei und wendet eine kontinuierliche Schrumpfung auf die Koeffizientenbeträge über einen L2-Strafterm an. Sie konstruiert keine niederdimensionalen latenten Komponenten oder verwirft Merkmalsdimensionen; vielmehr schrumpft sie die Varianz entlang der Richtungen mit niedrigen Eigenwerten von $X^T X$. 2. **Principal Component Regression (PCR):** Eine zweistufige, unüberwachte Dimensionsreduktionsmethode. Sie wendet zuerst die Hauptkomponentenanalyse (Principal Component Analysis, PCA) streng auf die Prädiktormatrix $X$ an, um orthogonale Richtungen maximaler Varianz zu finden, behält die Top $k$ Hauptkomponenten bei und passt eine OLS-Regression (Ordinary Least Squares) auf diese $k$ Komponenten an. Da PCA die Zielvariable $y$ ignoriert, besteht das Risiko, Komponenten zu verwerfen, die eine geringe Varianz in $X$ aber eine hohe Vorhersagekraft für $y$ haben. 3. **Partial Least Squares (PLS):** Eine überwachte Dimensionsreduktionsmethode. Sie konstruiert $k$ orthogonale latente Komponenten, indem sie lineare Kombinationen von $X$ findet, die die Kovarianz zwischen $X$ und der Antwort $y$ maximieren. Durch explizite Einbeziehung von Zielinformationen identifiziert PLS Komponenten, die sowohl die Merkmalsvarianz als auch die Antwortvariation erklären.

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)
Diese Frage mit einem KI-Coach beantworten

Senior-Fragen

13Wie unterscheiden sich XGBoost, LightGBM und CatBoost bei der Trainingsoptimierung und der Verarbeitung tabellarischer Merkmale?

XGBoost sucht Aufteilungen je nach Verfahren exakt, näherungsweise per Quantilskizzen oder histogrammbasiert. Klassisches tiefenweises Wachstum erweitert die Bäume Ebene für Ebene. Für fehlende Werte kann XGBoost bei der Suche pro Aufteilung eine Standardrichtung lernen. LightGBM fasst stetige Werte für die Suche in Histogramm-Bins zusammen, typischerweise in rund 256. Es erweitert zuerst das Blatt mit dem größten erwarteten Verlustgewinn. Beim Gradient-based One-Side Sampling (GOSS) behält es Beispiele mit großen Gradienten und zieht eine Teilstichprobe der übrigen. Exclusive Feature Bundling (EFB) bündelt dünn besetzte Merkmale, die selten gleichzeitig aktiv sind. Für Kategorien kann es die Histogramm-Bins sortieren und so in $O(K\log K)$ nach Aufteilungen suchen. CatBoost verwendet typischerweise symmetrische Bäume, bei denen auf derselben Tiefe dieselbe Aufteilungsregel gilt. Das ermöglicht schnelle vektorisierte Vorhersagen auf CPU oder GPU. Geordnete Zielstatistiken verwenden pro Zeile die vorhergehenden Zeilen einer Permutation. Zusammen mit geordnetem Boosting soll dies Target Leakage und Prediction Shift verringern.

from catboost import CatBoostClassifier
import lightgbm as lgb
import pandas as pd

df = pd.DataFrame({
    'city': ['NY', 'LDN', 'NY', 'PAR', 'LDN', 'TOK'],
    'age': [25, 42, 30, 22, 55, 38],
    'target': [1, 0, 1, 0, 1, 0]
})
cat_cols = ['city']
df['city'] = df['city'].astype('category')

# LightGBM handles pandas 'category' dtype natively via integer binning
lgb_clf = lgb.LGBMClassifier(max_depth=3, n_estimators=10)
lgb_clf.fit(df[['city', 'age']], df['target'])

# CatBoost handles categorical column names natively with ordered TS
cb_clf = CatBoostClassifier(iterations=10, cat_features=cat_cols, verbose=False)
cb_clf.fit(df[['city', 'age']], df['target'])
Diese Frage mit einem KI-Coach beantworten

14Wann ist beim Gradient Boosting eine eigene Verlustfunktion für asymmetrische Geschäftskosten sinnvoll?

Bei Klassifikation mit ungleichen Fehlerkosten, etwa wenn ein übersehener positiver Fall zehnmal so teuer ist wie ein Fehlalarm, kann man mit binärer Kreuzentropie zunächst $P(y=1\mid x)$ schätzen und die Kalibrierung auf Validierungsdaten prüfen und bei Bedarf korrigieren. Sind korrekte Entscheidungen kostenfrei, ergibt sich aus den Kosten der Schwellenwert $\tau=C_{FP}/(C_{FP}+C_{FN})$. Eine Schwellenwertanpassung oder eine Gewichtung von Trainingsbeispielen ist oft einfacher als eine eigene Ableitung. Bei asymmetrischer Regression, etwa mit Pinball-Loss für Bestandsmengen, oder bei nichtlinearen Kosten, die die Auswahl von Aufteilungen selbst beeinflussen sollen, kann eine andere Zielfunktion sinnvoll sein. Verfahren zweiter Ordnung benötigen normalerweise Gradienten $g_i=\partial L/\partial\hat y_i$ und Krümmungswerte $h_i=\partial^2 L/\partial\hat y_i^2$. Diese gehen in die Bewertung von Aufteilungen und in Blattgewichte wie $w^*=-\sum_i g_i/(\sum_i h_i+\lambda)$ ein. Die zweiten Ableitungen sollten nichtnegativ sein oder frameworkgerecht stabil angenähert bzw. begrenzt werden. Manche Implementierungen unterstützen Verfahren erster Ordnung oder andere Approximationen. Für nicht differenzierbare oder sprunghafte Geschäftskennzahlen kommt ein glatter Ersatzverlust infrage, etwa eine Huber- oder Log-Cosh-Variante.

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)
Diese Frage mit einem KI-Coach beantworten

15Was ist LambdaMART, und wie passt es Gradient Boosting an Ziele des maschinellen Erlernens von Rangfolgen an?

LambdaMART kombiniert gradientengeboostete Regressionsbäume mit den metrikgewichteten paarweisen Updates von LambdaRank. Für Dokumente i und j derselben Suchanfrage, wobei i relevanter ist, wird der logistische Paarverlust log(1 + exp(−sigma * (s_i − s_j))) verwendet. Verwenden Sie den normalisierten, nach Rangposition abgewerteten kumulierten Relevanzgewinn (NDCG) als Rangmetrik. Definieren Sie a_ij = sigma * abs(Delta NDCG_ij) / (1 + exp(sigma * (s_i − s_j))). Bei negativer Gradientenkonvention trägt das Paar +a_ij für i und −a_ij für j bei und schiebt das bevorzugte Dokument nach oben. Die vorzeichenbehafteten Beiträge ausgewählter Paare werden pro Dokument summiert und zur Anpassung der Boosting-Updates genutzt, oft mit passenden Krümmungsschätzern für Blattwerte. Delta NDCG misst die Änderung der Metrik beim Vertauschen der aktuellen Rangpositionen. Das liefert ein an Rankingqualität ausgerichtetes Surrogatsignal, ist aber keine gewöhnliche Ableitung der diskreten NDCG-Funktion und garantiert kein globales Metrikoptimum. Halten Sie Anfragegruppen bei Training und Evaluation zusammen. Die Auswahl von Paaren, Begrenzung der Metrik auf die ersten Rangplätze und Fälle ohne Relevanzgewinn hängen von der Implementierung ab.

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)
Diese Frage mit einem KI-Coach beantworten

Übe Interviews auf deinem Smartphone: Classical ML

Antworte laut und erhalte KI-Feedback in der Android-App.

EngineerSpeak bei Google Play herunterladen
Zum Download scannen