Fundamente de Data Science

4.5 Feature Engineering

Datele brute rareori conțin răspunsul în forma potrivită. Feature engineering înseamnă a construi coloane noi, informative — de multe ori diferența dintre 70p și 100p la o problemă ONIA.

Teorie

De la date brute la caracteristici informative

Modelele văd doar numerele pe care li le dai. O dată calendaristică e aproape inutilă ca text, dar devine valoroasă ca luna, zi_din_saptamana, este_weekend. Principiu: încorporează în coloane cunoștințele tale despre problemă.

# exemple de feature-uri derivate
df["pret_pe_mp"] = df["pret"] / df["suprafata"]
df["varsta_cladirii"] = 2026 - df["an_constructie"]
df["raport_datorie_venit"] = df["datorii"] / (df["venit"] + 1)
df["luna"] = pd.to_datetime(df["data"]).dt.month

Ferestre glisante (sliding windows)

Pentru serii de timp: rezumatul ultimelor n valori devine feature pentru momentul curent.

df["media_7_zile"] = df["vanzari"].rolling(window=7).mean()
df["max_7_zile"] = df["vanzari"].rolling(window=7).max()
df["ieri"] = df["vanzari"].shift(1)        # lag features
df["acum_o_saptamana"] = df["vanzari"].shift(7)

Pooling

Comprimarea unei secvențe/regiuni la o singură valoare: max pooling (cea mai mare), average pooling (media). Pe imagini, un bloc 2×2 → un pixel; pe serii, o fereastră → un rezumat. Reduce dimensiunea păstrând semnalul dominant.

# average pooling 2x2 pe o imagine în tonuri de gri (H, W)
H, W = img.shape
pooled = img[:H//2*2, :W//2*2].reshape(H//2, 2, W//2, 2).mean(axis=(1, 3))

One-hot encoding și codificare ordinală

# nominal (fără ordine): one-hot
df = pd.get_dummies(df, columns=["oras"])

# ordinal (cu ordine naturală): mapare la numere
ordine = {"Fair": 0, "Good": 1, "Very Good": 2, "Premium": 3, "Ideal": 4}
df["cut"] = df["cut"].map(ordine)

Momente statistice

Când o observație are mai multe valori (un senzor cu 100 de măsurători, un text cu n cuvinte), le rezumi prin momente: media, deviația standard, minim, maxim, mediană, asimetrie (skewness), kurtosis.

agg = df.groupby("SampleID")["semnal"].agg(
    ["mean", "std", "min", "max", "median", "skew"])

PCA ca feature engineering

Componentele principale (lecția 3.2) pot deveni coloane noi: comprimă zeci de coloane corelate în câteva „rezumate" — utile mai ales pentru modelele liniare și K-NN.

Problemă rezolvată: Magazinul regal al diamantelor

Magazinul regal al diamantelor Mediu Rezolvată — 100p

Predicția prețului diamantelor. Cheia problemei nu e modelul, ci codificarea: cut, color și clarity au ordine naturală — one-hot pierde această informație, codificarea ordinală o păstrează. Exact trucul care duce la 100p.

Soluția pas cu pas
import pandas as pd
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.model_selection import cross_val_score

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

# codificare ORDINALĂ — ordinea contează!
cut_map = {"Fair": 0, "Good": 1, "Very Good": 2, "Premium": 3, "Ideal": 4}
color_map = {c: i for i, c in enumerate("JIHGFED")}     # J slab ... D top
clarity_map = {c: i for i, c in enumerate(
    ["I3", "I2", "I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF", "FL"])}

for df in (train, test):
    df["cut"] = df["cut"].map(cut_map)
    df["color"] = df["color"].map(color_map)
    df["clarity"] = df["clarity"].map(clarity_map)
    df["volum"] = df["x"] * df["y"] * df["z"]     # feature nou geometric

feats = ["carat", "cut", "color", "clarity", "depth", "table", "volum"]
model = HistGradientBoostingRegressor(random_state=42)
print(cross_val_score(model, train[feats], train["price"], cv=5,
                      scoring="neg_mean_absolute_error").mean())

model.fit(train[feats], train["price"])
pd.DataFrame({
    "SampleID": test["SampleID"],
    "price": model.predict(test[feats]).round(2)
}).to_csv("submission.csv", index=False)

De reținut: aceeași problemă cu one-hot în loc de ordinal pierde puncte — modelul nu mai știe că Ideal > Premium > Very Good.

Probleme propuse

1. Nominal sau ordinal? Exercițiu

Clasifică și codifică potrivit: culoarea mașinii, mărimea tricoului (S/M/L/XL), județul, nivelul de studii, luna anului. Justifică fiecare alegere (luna e capcană — e ciclică!).

2. Ferestre pe vreme Exercițiu

Pe un CSV cu temperaturi zilnice, construiește media/min/max pe ferestre de 3 și 7 zile plus lag-uri de 1 și 7 zile, apoi compară o regresie cu și fără aceste feature-uri.

3. Momente pe semnale Exercițiu

Fiecare exemplu e o serie de 100 de măsurători ale unui senzor. Construiește feature-urile mean/std/min/max/median/skew și antrenează un clasificator doar pe ele.

4. Predicția performanței școlare Platformă

Problemă în care feature-urile derivate fac diferența.