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
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
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ă!).
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.
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.
Problemă în care feature-urile derivate fac diferența.