Fundamente de programare

1.4 Introducere în scikit-learn

scikit-learn este biblioteca standard de machine learning la ONIA. Toate modelele din capitolele 2 și 3 urmează același ritual: fitpredictscore.

Teorie

Structura bibliotecii

Orice model (numit estimator) are aceeași interfață, indiferent că e regresie liniară sau random forest:

model = Estimator(hiperparametri)   # 1. construiești modelul
model.fit(X_train, y_train)         # 2. înveți din date
y_pred = model.predict(X_test)      # 3. faci predicții
model.score(X_test, y_test)         # 4. evaluezi

Convenții: X este tabelul de caracteristici (2D), y este ținta (1D). Modulele importante: sklearn.linear_model, sklearn.tree, sklearn.ensemble, sklearn.cluster, sklearn.preprocessing, sklearn.model_selection, sklearn.metrics.

Împărțirea în antrenare și testare

Modelul nu se evaluează niciodată pe datele pe care a învățat — ar fi ca și cum ai da examenul cu subiectele deja văzute.

from sklearn.model_selection import train_test_split

X_train, X_val, y_train, y_val = train_test_split(
    X, y,
    test_size=0.2,      # 20% pentru validare
    random_state=42,    # reproductibilitate
    stratify=y          # la clasificare: păstrează proporția claselor
)

Normalizarea datelor

Modelele bazate pe distanțe (K-NN, SVM, K-Means) au nevoie ca toate coloanele să fie pe scări comparabile.

from sklearn.preprocessing import StandardScaler, MinMaxScaler

scaler = StandardScaler()           # medie 0, deviație 1
X_train_s = scaler.fit_transform(X_train)   # fit DOAR pe train
X_val_s = scaler.transform(X_val)            # pe val doar transform
fit_transform pe train, transform pe validare/test. Dacă faci fit și pe test, „scurgi" informație din test în model (data leakage).

Codificarea variabilelor categorice

from sklearn.preprocessing import OneHotEncoder, LabelEncoder
import pandas as pd

# One-hot: o coloană binară pentru fiecare categorie
X = pd.get_dummies(df, columns=["oras"])

# LabelEncoder: pentru ținta y la clasificare
le = LabelEncoder()
y = le.fit_transform(df["specie"])   # setosa→0, versicolor→1, ...
# înapoi la etichete: le.inverse_transform(y_pred)

Pentru categorii ordonate (Fair < Good < Premium), folosește codificare ordinală cu map — vezi problema diamantelor din lecția 4.5.

Antrenarea și evaluarea — exemplu complet

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

X, y = load_iris(return_X_y=True)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2,
                                                  random_state=42, stratify=y)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.transform(X_val)

model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
print("Acuratețe:", accuracy_score(y_val, model.predict(X_val)))

Problemă rezolvată: clasificarea florilor Iris

Clasificarea speciilor de flori Iris Ușor Rezolvată — 94p

Pe baza a patru măsurători (lungimea/lățimea sepalelor și petalelor), prezicem specia florii. Este „Hello World"-ul învățării automate și prima problemă completă cu scikit-learn.

Soluția pas cu pas

1. Citim train/test cu Pandas. 2. Separăm X și y. 3. Validăm local cu train_test_split. 4. Antrenăm pe tot train-ul și scriem submisia.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

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

feats = ["sepal_length", "sepal_width", "petal_length", "petal_width"]
X, y = train[feats], train["species"]

# validare locală
X_tr, X_va, y_tr, y_va = train_test_split(X, y, test_size=0.2,
                                          random_state=42, stratify=y)
sc = StandardScaler()
model = LogisticRegression(max_iter=1000)
model.fit(sc.fit_transform(X_tr), y_tr)
print("Val:", accuracy_score(y_va, model.predict(sc.transform(X_va))))

# model final pe toate datele + submisie
sc = StandardScaler()
model.fit(sc.fit_transform(X), y)
pred = model.predict(sc.transform(test[feats]))

pd.DataFrame({"SampleID": test["SampleID"], "species": pred}) \
  .to_csv("submission.csv", index=False)

Probleme propuse

1. Ritualul sklearn din memorie Exercițiu

Scrie din memorie cei 4 pași (construire, fit, predict, evaluare) pentru un DecisionTreeClassifier pe Iris. Verifică apoi cu documentația.

2. Efectul scalării Exercițiu

Antrenează un KNeighborsClassifier pe date cu și fără StandardScaler, pe un dataset în care o coloană are valori de mii de ori mai mari decât alta. Compară acuratețea și explică diferența.

3. Clasificarea tipului de vin Platformă

Aplică exact rețeta de la Iris pe problema vinului: citire, scalare, regresie logistică, submisie.