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
| Úloha | Doporučení |
|---|---|
| Tabular klasifikace | XGBoost nebo LightGBM |
| Tabular regrese | XGBoost nebo LightGBM |
| Hodně kategorických featur | CatBoost (žádný get_dummies) |
| Rychlý baseline | Random Forest |
| Obrázky | PyTorch 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.05nebo0.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_depthpř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
5nebo10
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"])
| Model | Kdy |
|---|---|
MultinomialNB | Nejrychlejší 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_transformna test datech – na testu jentransform! 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.