4.3 Optimizarea hiperparametrilor
Hiperparametrii (k, max_depth, C, learning_rate…) nu se învață din date — îi alegi tu. Căutarea lor sistematică aduce de regulă ultimele puncte care fac diferența în clasament.
Teorie
Cross-validation — fundația evaluării corecte
Un singur split train/validare poate fi norocos sau ghinionist. K-fold cross-validation împarte train-ul în k felii (de regulă 5): antrenează de k ori, de fiecare dată validând pe altă felie, și raportează media. Mai stabil, folosește toate datele.
from sklearn.model_selection import cross_val_score, StratifiedKFold
scoruri = cross_val_score(model, X, y, cv=5, scoring="f1_macro")
print(scoruri.mean().round(3), "±", scoruri.std().round(3))
# la clasificare, felii stratificate (proporția claselor păstrată):
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
Grid Search — căutare exhaustivă
Definești o grilă de valori; se încearcă toate combinațiile, fiecare evaluată prin cross-validation.
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
grila = {
"n_estimators": [100, 300],
"max_depth": [None, 5, 10, 20],
"min_samples_leaf": [1, 3, 5],
}
gs = GridSearchCV(RandomForestClassifier(random_state=42),
grila, cv=5, scoring="f1_macro", n_jobs=-1)
gs.fit(X_train, y_train)
print(gs.best_params_, gs.best_score_)
model_final = gs.best_estimator_ # gata antrenat pe tot train-ul
Random Search — căutare aleatoare
Când grila e prea mare, RandomizedSearchCV încearcă un număr fix de combinații
aleatoare. Surprinzător de eficient: de obicei doar 1–2 hiperparametri contează cu adevărat, iar
căutarea aleatoare acoperă mai multe valori distincte ale fiecăruia decât o grilă rigidă.
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
distributii = {
"n_estimators": randint(100, 1000),
"max_depth": randint(3, 30),
"learning_rate": uniform(0.01, 0.3),
}
rs = RandomizedSearchCV(model, distributii, n_iter=40, cv=5,
scoring="f1_macro", n_jobs=-1, random_state=42)
rs.fit(X_train, y_train)
| Grid Search | Random Search | |
|---|---|---|
| Combinații încercate | toate | n_iter alese aleator |
| Potrivit când | 2–3 hiperparametri, valori puține | mulți hiperparametri / intervale continue |
| Cost | explodează exponențial | controlat de tine |
Pipeline înainte
de GridSearchCV — altfel scalerul „vede" feliile de validare și scorurile ies umflate.Problemă rezolvată: tuning complet cu Pipeline
Rețeta corectă și completă: preprocesare în pipeline, grilă peste model, evaluare cinstită — șablonul pe care îl poți refolosi la orice problemă tabelară de pe platformă.
Șablonul complet
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import classification_report
train = pd.read_csv("train.csv")
feats = [c for c in train.columns if c not in ("SampleID", "target")]
X_tr, X_va, y_tr, y_va = train_test_split(train[feats], train["target"],
test_size=0.2, random_state=42,
stratify=train["target"])
pipe = Pipeline([
("scaler", StandardScaler()),
("model", SVC()),
])
grila = {
"model__C": [0.1, 1, 10, 100],
"model__gamma": ["scale", 0.01, 0.1, 1],
}
gs = GridSearchCV(pipe, grila, cv=5, scoring="f1_macro", n_jobs=-1)
gs.fit(X_tr, y_tr)
print("Cei mai buni parametri:", gs.best_params_)
print("Scor CV:", round(gs.best_score_, 3))
print(classification_report(y_va, gs.predict(X_va))) # verificare finală
Observă sintaxa model__C: numele pasului din pipeline + __ +
numele hiperparametrului.
Probleme propuse
O grilă are 4×5×3 combinații cu cv=5. Câte antrenări rulează GridSearchCV? Dar RandomizedSearchCV cu n_iter=30? Ce alegi dacă o antrenare durează 30 de secunde?
Rulează de 10 ori un train_test_split diferit și măsoară scorul; apoi rulează o singură dată cross_val_score cu cv=10. Compară împrăștierea rezultatelor.
Pe aceeași problemă și același buget (40 de antrenări), compară scorul final GridSearchCV vs RandomizedSearchCV pentru un HistGradientBoosting. Care câștigă?
Ia soluția ta cea mai bună de la orice problemă tabelară și adaugă-i tuning cu RandomizedSearchCV. Notează scorul înainte și după.