Příprava na pohovor z klasického ML

Otázky k pohovorům pro inženýry klasického strojového učení

15 vybraných otázek k pohovorům z oblasti klasického strojového učení, seskupených podle úrovně seniority. Použijte je k zopakování základů, praktických kompromisů a úvah pro produkční prostředí na úrovni seniora.

Spustit AI pohovor z klasického MLNení vyžadována platební karta. K dispozici je 1 bezplatná relace.
Příprava na technické pohovory v angličtiněRežim pro lidi, pro které angličtina není rodným jazykem, určený k procvičování technických pohovorů.

Otázky pro Juniory

1Jaký je rozdíl mezi parametrem modelu a hyperparametrem v učení s učitelem (supervised learning)?

V učení s učitelem (supervised machine learning) jsou parametry modelu interní proměnné naučené přímo z tréninkových dat pomocí optimalizačního algoritmu (jako je gradientní sestup nebo normální rovnice). Příklady zahrnují regresní váhy a bias v lineárních modelech nebo prahy rozdělení v rozhodovacích stromech. Naproti tomu hyperparametry jsou externí konfigurační nastavení specifikovaná před tréninkem, která řídí proces učení, kapacitu modelu nebo architekturu. Nemohou být naučeny přímo standardní minimalizací tréninkové ztráty, protože optimalizátor by se triviálně přeucil (např. nastavení hloubky stromu na nekonečno). Příklady zahrnují rychlost učení, sílu regularizace (lambda/C), počet stromů v lese a maximální hloubku stromu. Hyperparametry se ladí pomocí validačních dat nebo křížové validace.

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}")
Zkusit odpovědět na tuto otázku s trenérem AI

2Jaké předpoklady činí lineární regrese metodou nejmenších čtverců (Ordinary Least Squares, OLS) a jak by diagnostika reziduí odhalila porušení těchto předpokladů?

Lineární regrese metodou nejmenších čtverců (OLS) se opírá o několik základních předpokladů: 1. Linearita: Vztah mezi prediktory a výsledkem je lineární v parametrech. 2. Nezávislost chyb: Pozorování a reziduální chyby jsou vzájemně nezávislé (žádná autokorelace). 3. Homoskedasticita: Chybové členy mají konstantní rozptyl napříč všemi úrovněmi prediktorů. 4. Normalita reziduí: Chybové členy jsou normálně rozděleny (nutné pro platné intervaly spolehlivosti a testy hypotéz). 5. Žádná multikolinearita: Prediktory nejsou lineárně závislé (matice návrhu má plnou sloupcovou hodnost). Diagnostika reziduí odhaluje porušení následovně: - Graf reziduí proti předpovídaným hodnotám (Residuals vs. Fitted Values plot): Zakřivení nebo náhodné vzory odhalují nelinearitu; tvar trychtýře nebo vějíře odhaluje heteroskedasticitu (nekontantní rozptyl). - Normal Q-Q graf: Systematické odchylky od přímé diagonální čáry (např. S-křivky nebo tlusté konce) odhalují nenormalitu. - Graf reziduí proti pořadí/času (Residuals vs. Order/Time plot): Systematické trendy nebo cyklické vzory odhalují autokorelované chyby. - Leverage / Cook's Distance graf: Identifikuje odlehlé hodnoty s vysokou pákou nebo vlivné body, které neúměrně posouvají fitovaný model.

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.")
Zkusit odpovědět na tuto otázku s trenérem AI

3Jak logistická regrese modeluje binární klasifikaci a jaká je role sigmoidální funkce?

Logistická regrese modeluje binární klasifikaci odhadováním posteriorní pravděpodobnosti třídy $P(Y=1|X)$. Aby se zajistilo, že předpovídané pravděpodobnosti zůstanou ohraničeny v intervalu $(0, 1)$, logistická regrese modeluje log-šance (logit) pozitivní třídy jako lineární funkci vstupů: $\ln\left(\frac{p}{1-p}\right) = w^T x + b$. Sigmoidální (logistická) funkce, $\sigma(z) = \frac{1}{1 + e^{-z}}$, slouží jako spojovací funkce, která mapuje jakékoli lineární skóre $z = w^T x + b \in (-\infty, +\infty)$ s reálnou hodnotou monotónně na platnou pravděpodobnost $p \in (0, 1)$. Diskrétní rozhodnutí o třídě se provádí aplikací rozhodovacího prahu $\tau$ (typicky 0.5): $\hat{y} = 1$, pokud $P(Y=1|X) \ge \tau$, jinak $0$. Protože $\sigma(z) = 0.5$ nastává přesně, když $z = 0$, rozhodovací hranice v prostoru příznaků je lineární nadrovina $w^T x + b = 0$, což činí standardní logistickou regresi lineárním klasifikátorem.

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}")
Zkusit odpovědět na tuto otázku s trenérem AI

4Co je L2 regularizace a jak Ridge regrese mění účelovou funkci a odhady koeficientů?

L2 regularizace (Ridge regrese) přidává penalizaci úměrnou součtu druhých mocnin vah k chybové funkci metody nejmenších čtverců (Ordinary Least Squares, OLS): $$\min_w \|y - Xw\|_2^2 + \lambda \|w\|_2^2$$ Analyticky Ridge modifikuje normální rovnice přidáním $\lambda I$ k Gramově matici před inverzí: $$w_{\text{ridge}} = (X^T X + \lambda I)^{-1} X^T y$$ Hlavní dopady na účelovou funkci a odhady koeficientů: 1. **Smrštění**: Koeficienty jsou smrštěny směrem k nule úměrně k varianci příznaků a korelaci, což snižuje složitost modelu, aniž by je nutilo k přesné nule. 2. **Multikolinearita a invertovatelnost**: Když jsou příznaky kolineární nebo $p > N$, je $X^T X$ singulární nebo špatně podmíněná. Přidání $\lambda I$ zajišťuje, že $(X^T X + \lambda I)$ je striktně pozitivně definitní a invertovatelná, čímž stabilizuje odhady parametrů. 3. **Kompromis mezi zkreslením a rozptylem (Bias-Variance Trade-off)**: Zvyšování $\lambda$ zavádí záměrné zkreslení do odhadů koeficientů a zároveň významně snižuje rozptyl, což vede k nižší očekávané chybě zobecnění na neviděných datech. 4. **Požadavek na škálování příznaků**: Protože penalizace zachází se všemi váhami stejně, příznaky na větších škálách by byly regularizovány neúměrně. Příznaky musí být před trénováním standardizovány (nulový průměr, jednotková variance).

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)
Zkusit odpovědět na tuto otázku s trenérem AI

5Jak rozhodovací strom rekurzivně rozděluje prostor příznaků a jaká kritéria se používají pro výběr rozdělení pro klasifikaci?

Rozhodovací strom rozděluje prostor příznaků pomocí shora dolů, hladového algoritmu nazývaného **rekurzivní binární rozdělení**. Začíná v kořenovém uzlu se všemi trénovacími daty a algoritmus prohledává všechny příznaky a možné prahové hodnoty, aby nalezl jediné rozdělení zarovnané s osou ($X_j \le t$), které maximalizuje snížení nečistoty. Datová sada je rozdělena do dvou dětských uzlů a tento postup je rekurzivně aplikován na každý dětský uzel, dokud není dosaženo kritéria zastavení (např. maximální hloubka, minimální počet vzorků na list nebo čisté uzly). Protože rozdělení vyhodnocují jeden příznak po druhém proti prahové hodnotě, výsledné rozhodovací hranice jsou ortogonální nadroviny (obdélníkové oblasti v prostoru příznaků zarovnané s osami). Pro vyhodnocení a výběr nejlepšího rozdělení v klasifikačních stromech se používají dvě hlavní kritéria nečistoty: 1. **Giniho nečistota (používaná v CART)**: Měří pravděpodobnost, že náhodně vybraný vzorek by byl chybně klasifikován, pokud by byl náhodně označen podle distribuce tříd uzlu. Pro $K$ tříd s proporcemi $p_k$: $$I_G = 1 - \sum_{k=1}^K p_k^2$$ 2. **Entropie a informační zisk (používané v ID3, C4.5)**: Entropie měří nejistotu v uzlu: $H = -\sum_{k=1}^K p_k \log_2(p_k)$. Rozdělení je vybráno tak, aby maximalizovalo **informační zisk**, což je entropie rodičovského uzlu minus vážený průměr entropie dětských uzlů: $$IG = H(\text{parent}) - \sum_{c \in \{\text{left, right}\}} \frac{N_c}{N} H(c)$$ Obě metriky dosahují 0, když je uzel zcela čistý (všechny vzorky patří do jedné třídy) a dosahují svého maxima, když jsou třídy rovnoměrně rozloženy.

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}")
Zkusit odpovědět na tuto otázku s trenérem AI

6Co je k-nejbližších sousedů (kNN) a jak provádí predikce pro klasifikaci a regresi?

k-nejbližších sousedů (kNN - k-Nearest Neighbors) je neparametrický, instančně založený (líný) algoritmus učení pod dohledem. Netrénuje explicitní parametrický model; místo toho ukládá trénovací datovou sadu a provádí všechny výpočty během inferencí. Průběh predikce: 1. Výpočet vzdálenosti: Při vyhodnocování dotazovací instance algoritmus vypočítá její vzdálenost ke všem uloženým trénovacím instancím pomocí specifikované metriky (jako je Euklidovská, Manhattanova nebo Minkowského vzdálenost). 2. Výběr sousedů: Vybere $k$ trénovacích instancí s nejmenšími vzdálenostmi k dotazovací instanci. 3. Agregace: - Klasifikace: Přiřadí třídu většinovým hlasováním (módem) mezi $k$ sousedy (nebo hlasováním váženým vzdáleností). - Regrese: Predikuje spojitou cílovou hodnotu výpočtem lokálního průměru (střední hodnoty nebo mediánu) cílových hodnot $k$ sousedů (nebo průměru váženého vzdáleností). Protože výpočty vzdálenosti přímo závisí na škálách příznaků, je normalizace nebo standardizace příznaků zásadní, aby se zabránilo dominantnímu vlivu příznaků s velkou magnitudou na výpočty vzdáleností.

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))
Zkusit odpovědět na tuto otázku s trenérem AI

7Uveďte předpoklad podmíněné nezávislosti Naivního Bayese a vysvětlete, proč Naivní Bayes může stále dobře fungovat, i když je tento předpoklad porušen.

Předpoklad podmíněné nezávislosti Naivního Bayese uvádí, že za předpokladu daného popisku třídy Y = y jsou všechny rysy X_1, X_2, ..., X_d vzájemně nezávislé: P(X_1, ..., X_d | Y = y) = \prod_{j=1}^d P(X_j | Y = y). Pomocí Bayesova teorému je posteriorní pravděpodobnost: P(Y = y | X) \propto P(Y = y) \prod_{j=1}^d P(X_j | Y = y), kde P(Y = y) je apriorní pravděpodobnost třídy a P(X_j | Y = y) je podmíněná pravděpodobnost třídy (class-conditional likelihood) (např. Gaussovské pro spojité rysy, Multinomiální pro počty). Naivní Bayes často funguje dobře v praxi i přes porušení předpokladu nezávislosti, protože klasifikace se opírá o rozhodovací pravidlo argmax (argmax_y P(Y=y | X)) spíše než o přesnou kalibraci pravděpodobnosti. I když korelace rysů způsobí, že se předpovězené pravděpodobnosti stanou příliš sebevědomými nebo zkreslenými, správná třída si často udržuje nejvyšší relativní pořadí. Dokud korelace nepřevrátí pořadí pravděpodobností tříd, klasifikační rozhodnutí 0-1 zůstává přesné.

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]]))
Zkusit odpovědět na tuto otázku s trenérem AI

Otázky pro Middly

8Odvoďte nebo vysvětlete řešení metodou nejmenších čtverců (OLS – Ordinary Least Squares) v uzavřeném tvaru a uveďte, kdy existuje jednoznačně.

Cílová funkce metody nejmenších čtverců (OLS – Ordinary Least Squares) minimalizuje součet čtverců reziduí: $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$. Položením gradientu vzhledem k $\beta$ rovnému nule získáme: $$\nabla_\beta S(\beta) = -2 X^T y + 2 X^T X \beta = 0 \implies X^T X \beta = X^T y$$ To jsou normální rovnice. Pokud je $X^T X$ regulární (invertibilní), pak jedinečné řešení v uzavřeném tvaru je: $$\hat{\beta} = (X^T X)^{-1} X^T y$$ Geometricky, $\hat{y} = X\hat{\beta} = X(X^T X)^{-1} X^T y = H y$ představuje ortogonální projekci cílového vektoru $y$ na sloupcový prostor designové matice $X$, kde $H$ je projekční (hat) matice. Řešení existuje jednoznačně tehdy a pouze tehdy, je-li $X^T X$ invertibilní, což vyžaduje, aby designová matice $X$ o rozměrech $N \times P$ měla plnou sloupcovou hodnost ($Rank(X) = P$). To vyžaduje $N \ge P$ a žádnou přesnou multikolinearitu (žádný příznak není lineární kombinací ostatních). Pokud má $X$ nedostatečnou hodnost (rank-deficient), pak je $X^T X$ singulární, což vede k nekonečně mnoha řešením, která se často řeší pomocí regularizace nebo Moore-Penroseovy pseudoinverze $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}")
Zkusit odpovědět na tuto otázku s trenérem AI

9Co je metoda maximální věrohodnosti (MLE) a jak vede k funkci cíle křížové entropie logistické regrese?

Metoda maximální věrohodnosti (Maximum Likelihood Estimation – MLE) je metoda pro odhad parametrů modelu $\theta$ výběrem hodnot, které maximalizují věrohodnost $L(\theta) = P(\mathcal{D}|\theta)$ pozorované datové sady. V binární logistické regresi je každá nálepka (label) $y_i \in \{0, 1\}$ modelována jako nezávislá Bernoulliho náhodná proměnná podmíněná $x_i$, s pravděpodobností úspěchu $p_i = \sigma(w^T x_i + b)$. Funkce pravděpodobnostní hmotnosti pro pozorování $i$ je $P(y_i|x_i) = p_i^{y_i} (1 - p_i)^{1 - y_i}$. Za předpokladu i.i.d. (nezávislých a identicky distribuovaných) vzorků je sdružená věrohodnost: $$L(w, b) = \prod_{i=1}^N p_i^{y_i} (1 - p_i)^{1 - y_i}$$ Vezmeme-li přirozený logaritmus, produkt se převede na výpočetně zvládnutelný součet log-věrohodností: $$\ell(w, b) = \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$ Jelikož optimalizační algoritmy jsou standardně formulovány jako minimalizační problémy, negujeme log-věrohodnost a normalizujeme ji velikostí vzorku $N$, čímž získáme negativní log-věrohodnost (Negative Log-Likelihood – NLL), která je přesně funkcí cíle binární křížové entropie (Binary Cross-Entropy – log loss): $$J(w, b) = -\frac{1}{N} \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$ Tato funkce cíle je konvexní vzhledem k lineárním logitům/vahám, takže vhodné numerické řešiče optimalizují globální cíl. Přísná konvexnost a konečná unikátní MLE vyžadují další podmínky, jako je dostatečná hodnost příznaků, regularizace a absence dokonalého oddělení tříd.

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}")
Zkusit odpovědět na tuto otázku s trenérem AI

10Jak gradientní sestup optimalizuje cíl klasického strojového učení (ML) a jak rychlost učení, konvergence a konvexnost ovlivňují trénování?

Gradientní sestup minimalizuje empirickou ztrátovou funkci iterativní aktualizací parametrů modelu v opačném směru gradientu objektivní funkce vzhledem k těmto parametrům: $\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)$. Klíčové faktory ovlivňující trénování zahrnují: 1. **Rychlost učení ($\eta$):** Řídí velikost kroku. Pokud je nastavena příliš malá, konvergence je extrémně pomalá a trénování se může zastavit. Pokud je nastavena příliš velká, aktualizace přestřelí minimum, což způsobí oscilaci nebo numerickou divergenci. 2. **Konvergence:** Je určena monitorováním kritérií zastavení, jako je malá norma gradientu ($||\nabla L(\theta)|| \le \epsilon$), minimální posun parametrů nebo plató ztráty napříč po sobě jdoucími iteracemi. 3. **Konvexnost:** U konvexních cílů (např. standardní OLS (Ordinary Least Squares) lineární regrese nebo logistická regrese) je jakékoli lokální minimum zaručeno globálním minimem, což umožňuje gradientnímu sestupu spolehlivě konvergovat s vhodnými velikostmi kroku. U nekonvexních cílů (např. vícevrstvých neuronových sítí) obsahuje krajina ztrát více lokálních minim, sedlových bodů a plató, což činí konečné řešení citlivým na inicializaci. 4. **Optimalizace vs. Generalizace:** Konvergence na trénovací ztrátě odráží úspěch optimalizace, zatímco validační ztráta hodnotí generalizaci. Dosažení nízké trénovací ztráty s vysokou validační chybou naznačuje přeučení spíše než selhání optimalizace.

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
Zkusit odpovědět na tuto otázku s trenérem AI

11Porovnejte L1, L2 a ElasticNet regularizaci z hlediska řídkosti, korelovaných příznaků a praktické volby modelu.

L1 (Lasso), L2 (Ridge) a ElasticNet regularizace se liší ve formulaci penalizace, geometrii omezení, řídkosti a v zacházení s korelovanými prediktory: 1. **Řídkost a geometrie:** * L1 používá penalizaci absolutní hodnotou ($\lambda \|w\|_1$). Hranice jejího omezení je diamant/polytop s ostrými vrcholy na souřadnicových osách. Když se izolinie ztrátové funkce protnou v těchto rozích, váhy jsou hnány k přesné nule, čímž dochází k automatickému výběru příznaků. * L2 používá penalizaci čtvercovou euklidovskou normou ($\lambda \|w\|_2^2$). Hranice jejího omezení je hladká hypersféra bez rohů, smršťující váhy k nule asymptoticky, ale zřídka je nastaví na přesnou nulu. 2. **Korelované příznaky:** * Při silné kolinearitě má L1 tendenci libovolně vybrat jeden příznak ze skupiny korelovaných prediktorů a nastavit zbývající koeficienty na nulu, což vede k nestabilním odhadům napříč opakovanými vzorky. * L2 zachovává všechny korelované příznaky, rozděluje mezi ně váhy a smršťuje je dohromady. 3. **ElasticNet:** * Kombinuje obě penalizace: $\lambda_1 \|w\|_1 + \lambda_2 \|w\|_2^2$ (často parametrizováno s $\alpha$ a $l_1\_\text{ratio}$).) * Poskytuje řídkost a výběr příznaků jako Lasso a zároveň zachovává efekt seskupování (grouping effect) Ridge regrese, vybírající shluky korelovaných prediktorů dohromady. Je obzvláště užitečná, když $p > N$ nebo při závažné multikolinearitě.

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_)
Zkusit odpovědět na tuto otázku s trenérem AI

12Jaký je na vysoké úrovni rozdíl mezi Ridge regresí, regresí hlavních komponent (PCR) a parciální metodou nejmenších čtverců (PLS)?

Ridge regrese, regrese hlavních komponent (PCR) a parciální metoda nejmenších čtverců (PLS) jsou tři lineární techniky používané k řešení multikolinearity a vysoké dimenzionality, ale liší se v tom, jak redukují rozptyl a zda je redukce spojitá nebo řízená: 1. **Ridge regrese:** Zachovává všech $p$ původních příznaků a aplikuje spojité smršťování na velikosti koeficientů pomocí L2 penalizace. Nekonstruuje nízkodimenzionální latentní komponenty ani nezahazuje dimenze příznaků; spíše smršťuje rozptyl podél směrů s nízkými vlastními čísly $X^T X$. 2. **Regrese hlavních komponent (Principal Component Regression – PCR):** Dvoufázová, neřízená metoda redukce dimenzionality. Nejprve aplikuje analýzu hlavních komponent (Principal Component Analysis – PCA) striktně na matici prediktorů $X$, aby našla ortogonální směry maximálního rozptylu, ponechá prvních $k$ hlavních komponent a na těchto $k$ komponentách provede OLS (Ordinary Least Squares) regresi. Protože PCA ignoruje cílovou proměnnou $y$, PCR riskuje zahození komponent, které mají nízký rozptyl v $X$, ale vysokou prediktivní sílu pro $y$. 3. **Parciální metoda nejmenších čtverců (Partial Least Squares – PLS):** Řízená metoda redukce dimenzionality. Konstruuje $k$ ortogonálních latentních komponent nalezením lineárních kombinací $X$, které maximalizují kovarianci mezi $X$ a odezvou $y$. Explicitním začleněním informací o cíli PLS identifikuje komponenty, které vysvětlují jak rozptyl příznaků, tak variaci odezvy.

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)
Zkusit odpovědět na tuto otázku s trenérem AI

Otázky pro Seniory

13Jak moderní implementace gradientního boostingu, jako jsou XGBoost, LightGBM a CatBoost, optimalizují trénování nebo odlišně zpracovávají tabulkové rysy?

Moderní frameworky GBDT (Gradient Boosting Decision Tree) se podstatně liší svými algoritmy pro hledání rozdělení (split-finding algorithms), strategiemi růstu stromů a zpracováním tabulkových/kategorických rysů: 1. XGBoost: Tradičně spoléhá na přesné hladové (exact greedy) nebo přibližné kvantilové skicování (approximate quantile sketch) pro hledání rozdělení (a později Fast Hist), používá růst stromu po úrovních (level-wise/depth-wise) a zpracovává chybějící hodnoty učením optimálního výchozího směru větve (default branch direction) během hledání rozdělení. 2. LightGBM: Používá histogram-založené hledání rozdělení (binování spojitých rysů do diskrétních kbelíků, typicky 256), růst stromu po listech (leaf-wise/best-first) pro rychlejší snížení ztráty, Gradient-based One-Side Sampling (GOSS) pro zachování instancí s velkým gradientem při subsamplování instancí s malým gradientem a Exclusive Feature Bundling (EFB) pro sloučení vzájemně se vylučujících řídkých rysů. Pro kategorické proměnné najde optimální rozdělení seřazením histogramových košů kategorií ($O(K \log K)$). 3. CatBoost: Používá oblivious (symetrické) rozhodovací stromy, kde všechny uzly v dané hloubce sdílejí přesně stejné rozdělení, což umožňuje rychlé vektorizované skórování na CPU (Central Processing Unit)/GPU (Graphics Processing Unit). Jeho primární inovací jsou Ordered Target Statistics a ordered boosting, které počítají cílové statistiky přes náhodné permutace trénovacích dat, aby se zabránilo úniku cílových dat (target leakage) a posunu predikcí (prediction shift).

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'])
Zkusit odpovědět na tuto otázku s trenérem AI

14Jak byste se rozhodli, zda je vlastní ztrátová funkce vhodná pro gradientový boosting model za podmínek asymetrických obchodních nákladů?

Rozhodování o tom, zda implementovat vlastní ztrátovou funkci v gradientovém boostingu za asymetrických obchodních nákladů, vyžaduje posouzení, zda asymetrie může být řešena následně kalibrací pravděpodobnosti a laděním prahové hodnoty, nebo zda zásadně mění optimalizační krajinu během indukce stromu: 1. Ladění prahové hodnoty vs. vlastní ztrátová funkce: Pro klasifikační úlohy s asymetrickými náklady na chyby (např. falešné negativity stojí 10x více než falešné pozitivity) je standardní křížová entropie správná bodovací funkce, která má za cíl odhadovat aposteriorní pravděpodobnosti $P(y=1|x)$, ale kalibrace by měla být zkontrolována a v případě potřeby opravena na validačních datech. Posunutí prahové hodnoty pro rozhodování o klasifikaci na základě matice obchodních nákladů $\tau = \frac{C_{FP}}{C_{FP} + C_{FN}}$ nebo aplikace vah vzorků je často čistší a vyhýbá se vlastním derivacím. Nicméně pro asymetrickou regresi (např. asymetrická pinball ztrátová funkce pro poptávku po zásobách) nebo nelineární obchodní penalizace, kde standardní objektivní funkce nemohou vést k nalezení rozdělení, je vlastní ztrátová funkce opodstatněná. 2. Matematické požadavky pro GBDT (Gradient Boosting Decision Trees): U boosterů druhého řádu (XGBoost, LightGBM) vlastní ztrátová funkce $L(y, \hat{y})$ normálně potřebuje spočítatelné gradienty prvního řádu ($g_i = \partial L / \partial \hat{y}_i$) a platné hodnoty zakřivení/Hessianu druhého řádu ($h_i = \partial^2 L / \partial \hat{y}_i^2$) pro výpočty zisku rozdělení a vah listů ($w^* = -\sum g_i / (\sum h_i + \lambda)$). Hessiany by měly být nezáporné nebo bezpečně aproximované/ořezané pro numerickou stabilitu; některé implementace podporují objektivní funkce prvního řádu nebo aproximované, takže požadavek je závislý na frameworku. Nerozdělitelné nebo nespojité obchodní metriky by měly být nahrazeny hladkými surogátními aproximacemi (např. Huberizované nebo log-cosh varianty).

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)
Zkusit odpovědět na tuto otázku s trenérem AI

15Co je LambdaMART a jak adaptuje gradientní boosting pro cíle učení pro řazení (learning-to-rank)?

LambdaMART je algoritmus učení pro řazení (LTR - Learning-to-Rank), který kombinuje MART (Multiple Additive Regression Trees / Gradient Boosting) s frameworkem LambdaRank. Při řazení závisí cílové metriky jako NDCG (Normalizovaný diskontovaný kumulativní zisk) a MAP na diskrétním pořadí seřazení (ranky), což je činí téměř všude plochými a nediferencovatelnými vzhledem ke spojitým skóre modelu. LambdaMART to obchází konstrukcí virtuálních gradientů, nazývaných 'lambda gradienty' ($\lambda_{ij}$), pro dvojice položek $(i, j)$ v rámci stejného dotazu. Základní párový gradient pochází z logistické ztrátové funkce na rozdílech skóre ($s_i - s_j$). LambdaMART škáluje tento gradient přesnou změnou v cílové metrice řazení ($|\Delta \text{NDCG}_{ij}|$), která by nastala, kdyby byly pozice dokumentu $i$ a dokumentu $j$ prohozeny: $\lambda_{ij} = \frac{-\sigma}{1 + e^{\sigma(s_i - s_j)}} |\Delta \text{NDCG}_{ij}|$ Pro každý jednotlivý dokument $i$ je celkový gradient vypočten agregováním párových lambd napříč všemi dvojicemi zahrnujícími dokument $i$: $\lambda_i = \sum_{j: j \succ i} \lambda_{ij} - \sum_{k: i \succ k} \lambda_{ki}$. Standardní regresní stromy v boostingovém ansámblu pak přizpůsobí tyto složené lambda gradienty pro jednotlivé dokumenty v každém iteračním kroku boostingu, čímž přímo optimalizují listwise metriky řazení.

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)
Zkusit odpovědět na tuto otázku s trenérem AI