Klasické ML

🌲 Sklearn & Boosting

Hotové modely pro tabulární data. Klikni na model pro info a příklad kódu.

Modely

Referenční poznámky

Sklearn + Boosting modely

Hotové modely – nemusíš psát nic od nuly. Fit, predict, hotovo.

Základní kostra (funguje pro všechny)

import pandas as pd
from sklearn.model_selection import train_test_split

train = pd.read_csv("train.csv")
test  = pd.read_csv("test.csv")

X = train.drop(columns=["target"])
y = train["target"]

X_tr, X_val, y_tr, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

model.fit(X_tr, y_tr)
print(model.score(X_val, y_val))  # accuracy pro classifier, R² pro regressor

preds = model.predict(test)

Který model na co

ÚlohaDoporučení
Tabular klasifikaceXGBoost nebo LightGBM
Tabular regreseXGBoost nebo LightGBM
Hodně kategorických featurCatBoost (žádný get_dummies)
Rychlý baselineRandom Forest
ObrázkyPyTorch CNN
Text (rychlý baseline)sklearn: TF-IDF + Naive Bayes / LogisticRegression
Text (max výkon)PyTorch + embeddingy / transformery
Malý dataset (<1000 vzorků)Random Forest, SVM

Hyperparametry – co dělají a jak nastavit

n_estimators (RF, XGB, LGB) / iterations (CatBoost)

Počet stromů. Víc = lepší výkon, pomalejší trénink.

  • Start: 300
  • Dobré: 500–1000
  • Víc než 1000 málokdy pomůže

learning_rate (XGB, LGB, CatBoost)

Jak velký krok každý strom udělá. Menší = pomalejší ale přesnější.

  • Start: 0.1 (rychlý trénink)
  • Lepší výkon: 0.05 nebo 0.01 (potřebuješ víc stromů)
  • Pravidlo: menší lr → větší n_estimators

max_depth (XGB, CatBoost) / depth (CatBoost)

Hloubka každého stromu. Hlubší = model se naučí složitější vzory ale přefituje.

  • Start: 6
  • Malý dataset: 3–4
  • Velký dataset: 6–8
  • Nikdy nedávej víc než 10

num_leaves (LightGBM)

LightGBM roste do šířky místo hloubky. Ekvivalent max_depth.

  • num_leaves = 2^max_depth přibližně
  • Start: 31
  • Víc featur → víc listů

subsample (XGB, LGB)

% trénovacích dat použitých na každý strom. Náhodnost zabraňuje overfitu.

  • Rozsah: 0.5–1.0
  • Start: 0.8

colsample_bytree (XGB) / feature_fraction (LGB)

% featur použitých na každý strom. Stejný princip jako subsample.

  • Start: 0.8

min_samples_leaf (RF)

Min. počet vzorků v listu stromu. Vyšší = jednodušší strom = méně overfitu.

  • Start: 1 (default)
  • Pokud overfit: zkus 5 nebo 10

reg_alpha, reg_lambda (XGB, LGB)

L1 a L2 regularizace. Penalizuje komplexní modely.

  • Default: 0 (žádná regularizace)
  • Pokud overfit: zkus reg_lambda=1

Random Forest

from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor

model = RandomForestClassifier(
    n_estimators=500,
    max_depth=None,       # None = roste dokud může (pozor na overfit na malých datech)
    min_samples_leaf=2,
    n_jobs=-1,
    random_state=42
)

Vhodný pro: rychlý baseline, malé datasety, robustní vůči outlieram.
Strop: ~0.80 na většině Kaggle úloh. Pak přejdi na XGBoost.


XGBoost

from xgboost import XGBClassifier, XGBRegressor

model = XGBClassifier(
    n_estimators=500,
    learning_rate=0.05,
    max_depth=6,
    subsample=0.8,
    colsample_bytree=0.8,
    n_jobs=-1,
    random_state=42,
    eval_metric="logloss"  # pro klasifikaci, "rmse" pro regresi
)

Vhodný pro: skoro všechno tabulární. Standard na Kaggle.


LightGBM

from lightgbm import LGBMClassifier, LGBMRegressor

model = LGBMClassifier(
    n_estimators=500,
    learning_rate=0.05,
    num_leaves=31,
    subsample=0.8,
    colsample_bytree=0.8,
    n_jobs=-1,
    random_state=42,
    verbose=-1   # vypne spam v terminálu
)

Vhodný pro: velká data (>100k řádků), rychlejší než XGBoost, podobný výsledek.


CatBoost

from catboost import CatBoostClassifier, CatBoostRegressor

model = CatBoostClassifier(
    iterations=500,
    learning_rate=0.05,
    depth=6,
    cat_features=["Cabin_deck", "Cabin_side"],  # seznam kategorických sloupců, žádný get_dummies!
    verbose=100,
    random_state=42
)

Vhodný pro: datasety s hodně kategorickými featury. Zpracuje je sám.


Feature importance – co modelu záleží nejvíc

feat_imp = pd.Series(model.feature_importances_, index=X.columns)
print(feat_imp.sort_values(ascending=False).head(10))

Ukazuje které featury nejvíc přispívají. Featury s importance ~0 můžeš vyhodit.


GridSearch – automatické ladění hyperparametrů

from sklearn.model_selection import GridSearchCV

params = {
    "n_estimators": [300, 500],
    "max_depth": [4, 6, 8],
    "learning_rate": [0.05, 0.1],
}
gs = GridSearchCV(XGBClassifier(), params, cv=5, scoring="accuracy", n_jobs=-1)
gs.fit(X_tr, y_tr)
print(gs.best_params_)
model = gs.best_estimator_

Zkouší všechny kombinace, cv=5 = 5-fold cross validation. Pomalé na velkých gridech.


Feature engineering – jak vylepšit dataset

Největší skok ve score pochází odsud, ne z modelu.

Rozdělení sloupců

# Cabin "B/0/P" → 3 featury
df[["Cabin_deck", "Cabin_num", "Cabin_side"]] = df["Cabin"].str.split("/", expand=True)

# ID "0001_01" → group číslo
df["Group"] = df["PassengerId"].str.split("_").str[0].astype(int)

Agregace

# Součet více sloupců
spend_cols = ["RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
df["TotalSpend"] = df[spend_cols].sum(axis=1)

# Průměr skupiny (group-level feature)
df["GroupMeanAge"] = df.groupby("Group")["Age"].transform("mean")

Binning – číselné hodnoty → kategorie

# Věk do skupin
df["AgeGroup"] = pd.cut(df["Age"], bins=[0, 12, 18, 35, 60, 100],
                         labels=["child", "teen", "adult", "middle", "senior"])

Logaritmická transformace – pro zešikmená data (útrata, cena)

import numpy as np
df["LogSpend"] = np.log1p(df["TotalSpend"])  # log1p = log(x+1), zvládne nuly

Fillna – strategie

# Číselné: medián (robustnější než průměr na outliery)
df[num_cols] = df[num_cols].fillna(df[num_cols].median())

# Kategorické: "None" nebo nejčastější hodnota
df[cat_cols] = df[cat_cols].fillna("None")
df["HomePlanet"] = df["HomePlanet"].fillna(df["HomePlanet"].mode()[0])

StandardScaler – normalizace pro neuronové sítě

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train[num_cols] = scaler.fit_transform(X_train[num_cols])
X_test[num_cols]  = scaler.transform(X_test[num_cols])  # pozor: jen transform, ne fit!

Pro stromy (RF, XGB, CatBoost) scaler nepomůže – stromy jsou invariantní vůči škálování.

SMOTE – vyvažování nevyvážených tříd

# pip install imbalanced-learn --break-system-packages
from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X_train, y_train)

Použij když jedna třída má výrazně méně vzorků (např. fraud detection: 1% podvodů).


Predikce textu se sklearn

Sklearn neumí text přímo – model potřebuje čísla. Trik je převést text na čísla (vektorizace) a pak na to pustit normální klasifikátor. Pro AI olympiádu je to nejrychlejší cesta k dobrému výsledku na textu, bez neuronek.

Krok 1 – text na čísla (vektorizace)

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer

texts = ["mám rád tenhle film", "naprostá nuda", "skvělé, doporučuju"]

# CountVectorizer = bag-of-words: počítá kolikrát se slovo vyskytlo
cv = CountVectorizer()
X = cv.fit_transform(texts)        # řídká matice [n_textů x n_slov]

# TfidfVectorizer = počet vážený důležitostí slova (lepší než pouhý počet)
tfidf = TfidfVectorizer(
    ngram_range=(1, 2),   # bere slova i dvojice slov ("mám rád")
    min_df=2,             # ignoruj slova co jsou v <2 dokumentech
    max_features=20000,   # nech jen 20k nejčastějších (drží paměť)
    stop_words=None       # pro češtinu vlastní seznam, "english" pro angličtinu
)
X = tfidf.fit_transform(texts)

Pravidlo: skoro vždy začni TfidfVectorizer – bije CountVectorizer skoro pokaždé.

Krok 2 – klasifikace textu (predikce labelu)

Nejčastější úloha: text → kategorie (spam/ham, sentiment, téma...). Celé se to vejde do jednoho Pipeline, takže vektorizace + model jdou společně.

from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC

# Naive Bayes – nejrychlejší baseline na text, extrémně rychlý
model = Pipeline([
    ("tfidf", TfidfVectorizer(ngram_range=(1, 2), min_df=2)),
    ("clf", MultinomialNB()),
])

model.fit(X_train_texts, y_train)        # X je seznam stringů!
print(model.score(X_val_texts, y_val))
preds = model.predict(["tohle je nový text"])
ModelKdy
MultinomialNBNejrychlejší baseline, super na bag-of-words. Začni tady.
LogisticRegression(max_iter=1000)Většinou nejlepší poměr výkon/jednoduchost na TF-IDF.
LinearSVC()Často vyhraje na delších textech. Nemá predict_proba.

Stačí v Pipeline vyměnit ("clf", ...) – zbytek je stejný.

Krok 3 – co model rozhodlo (interpretace)

import numpy as np

clf = model.named_steps["clf"]
vocab = np.array(model.named_steps["tfidf"].get_feature_names_out())

# Slova nejvíc tlačící k třídě 1 (u LogisticRegression / LinearSVC)
top = np.argsort(clf.coef_[0])[-15:]
print(vocab[top])

Predikce dalšího slova (jednoduchý generátor)

„Predikce textu" může znamenat i hádání dalšího slova. Jde to i ve sklearn: z každého textu uděláš dvojice (předchozí slova → další slovo) a natrénuješ klasifikátor, kde label je to další slovo.

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression

corpus = "kočka sedí na stromě a kočka spí na zemi".split()

# Trénovací dvojice: dvě slova → třetí slovo (kontextové okno = 2)
ctx, nxt = [], []
for i in range(len(corpus) - 2):
    ctx.append(" ".join(corpus[i:i+2]))
    nxt.append(corpus[i+2])

vec = CountVectorizer()
X = vec.fit_transform(ctx)
clf = LogisticRegression(max_iter=1000).fit(X, nxt)

# Predikce dalšího slova po "na stromě"
print(clf.predict(vec.transform(["na stromě"])))

# Generování: opakovaně přidávej predikované slovo
seed = "kočka sedí"
for _ in range(5):
    nw = clf.predict(vec.transform([" ".join(seed.split()[-2:])]))[0]
    seed += " " + nw
print(seed)

Je to naivní (žádný kontext za 2 slova, neumí nová slova), ale na ukázku principu n-gram modelu to stačí. Na vážnou generaci textu → PyTorch / transformery.

Časté chyby

  • fit_transform na test datech – na testu jen transform! Jinak leakuješ slovník.
  • Posílání matice featur místo stringů do Pipeline – Pipeline si vektorizaci dělá sám, krm ho seznamem textů.
  • Zapomenutý min_df → slovník naroste do desítek tisíc slov a model přefituje na překlepy.

Pro obrazkové úlohy (CV)

Sklearn na obrázky nestačí – použij PyTorch.

import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])  # ImageNet stats
])

Transfer learning – nejrychlejší cesta k dobrému CV výsledku

import torchvision.models as models

# Předtrénovaný ResNet, změní jen poslední vrstvu
model = models.resnet18(pretrained=True)
model.fc = nn.Linear(model.fc.in_features, NUM_CLASSES)  # tvůj počet tříd

Místo trénovat CNN od nuly – vezmeš model naučený na ImageNetu (1M obrázků) a doučíš ho na svých datech. Rychlejší, lepší výsledky na malých datasetech.