Hoppa till innehållet
AI-grafen
D· AI-utvecklaredatahantering· ca 45 min· grundläggande — ändras sällan· verifierad 2026-09-20

Feature engineering

Kunna skapa, koda och skala features, inklusive one-hot och normalisering.

Förkunskaper

Intuition

En modell ser bara tal. Feature engineering är att omvandla verkligheten till tal på ett sätt som gör mönstren synliga.

Kategoriska variabler:

MetodHurPassar
One-hoten 0/1-kolumn per värdefå kategorier, linjära modeller
Ordinal0, 1, 2 …när ordningen är verklig (låg/medel/hög)
Target encodingersätt med målets medelvärde i kategorinmånga kategorier — men läcker lätt
Embeddinginlärd vektormycket många kategorier, neurala nät

Fällan med ordinal kodning: koda «Malmö = 1, Lund = 2, Umeå = 3» så påstår du att Lund ligger mellan Malmö och Umeå och att Umeå är tre gånger Malmö. Det är nonsens, och en linjär modell kommer att tro på det.

Numeriska variabler skalas för att inte en variabel ska dominera bara för att den mäts i en större enhet:

MetodFormelResultat
Standardisering(x−μ)/σ(x - \mu)/\sigmamedel 0, std 1
Min–max(x−min⁡)/(max⁡−min⁡)(x - \min)/(\max - \min)intervallet [0, 1]
Robust(x−median)/IQR(x - \text{median})/\text{IQR}tål avvikare
Loglog⁡(1+x)\log(1 + x)drar ihop en högersvans

Formellt

Läckage är det stora felet i förbehandling, och det finns i tre former:

  1. Statistik från testdata. Beräkna μ\mu och σ\sigma över hela datasetet → testmängdens fördelning har påverkat träningen. Rätt: fit på träning, transform på båda.
  2. Target encoding utan korsvalidering. Ersätter du en kategori med målets medelvärde använder du målet som feature. Utan out-of-fold-beräkning memorerar modellen sina egna etiketter.
  3. Features från framtiden. «Antal köp senaste månaden» beräknat över hela perioden innehåller information som inte fanns vid beslutstillfället. Det här är det svåraste att upptäcka och det vanligaste i tidsserieproblem.

Symtomet på läckage är alltid detsamma: misstänkt bra valideringsresultat som inte håller i produktion. En modell som plötsligt får 0,99 AUC har oftast inte blivit bra — den har fått se facit.

Pipeline löser problem 1 strukturellt genom att göra hela förbehandlingen till en del av modellen. Det är inte bara snyggare kod — det är den enda formen som överlever korsvalidering korrekt, eftersom fit då körs om inom varje veck.

Vilka modeller behöver skalning?

BehöverBehöver inte
kNN, SVM, k-means (avståndsbaserade)beslutsträd
linjär/logistisk regression med regulariseringrandom forest
neurala nätgradient boosting

Träd delar på tröskelvärden och bryr sig inte om skalan. Allt som mäter avstånd eller straffar koefficienternas storlek gör det.

Domänkunskap slår automatik. De features som brukar göra störst skillnad är de någon som kan området föreslår: förhållanden (pris per kvadratmeter), tidsskillnader (dagar sedan senaste besök), och cykliska omkodningar (veckodag som sin/cos, så att söndag ligger nära måndag).

Kod

import numpy as np, pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

num = ["alder", "timmar"]
kat = ["stad", "program"]

forbehandling = ColumnTransformer([
    ("num", Pipeline([("fyll", SimpleImputer(strategy="median")),
                      ("skala", StandardScaler())]), num),
    ("kat", Pipeline([("fyll", SimpleImputer(strategy="most_frequent")),
                      ("onehot", OneHotEncoder(handle_unknown="ignore"))]), kat),
])

modell = Pipeline([("forbehandling", forbehandling),
                   ("klassificerare", LogisticRegression(max_iter=1000))])

# Korsvalideringen kör om HELA förbehandlingen inom varje veck → inget läckage
print(cross_val_score(modell, X, y, cv=5, scoring="roc_auc").mean())

# handle_unknown="ignore" behövs: produktionsdata innehåller kategorier
# som inte fanns i träningen, och utan detta kraschar transform.

# Domänkunskap: cykliska variabler
df = pd.DataFrame({"veckodag": [0, 1, 5, 6]})       # 0 = måndag, 6 = söndag
df["dag_sin"] = np.sin(2 * np.pi * df.veckodag / 7)
df["dag_cos"] = np.cos(2 * np.pi * df.veckodag / 7)
# Avståndet mellan söndag (6) och måndag (0) blir nu litet, som det ska vara:
for a, b in [(6, 0), (0, 3)]:
    va = np.array([np.sin(2*np.pi*a/7), np.cos(2*np.pi*a/7)])
    vb = np.array([np.sin(2*np.pi*b/7), np.cos(2*np.pi*b/7)])
    print(f"dag {a} → {b}: avstånd {np.linalg.norm(va - vb):.3f}")
# dag 6 → 0: avstånd 0.868
# dag 0 → 3: avstånd 1.950     ← söndag ligger nära måndag, som i verkligheten

Den cykliska kodningen är ett bra exempel på att en enkel idé ur domänkunskap ofta ger mer än en större modell.

Behärskning innebär

  • Kodar kategoriska variabler
  • Skalar numeriska variabler korrekt
  • Undviker läckage i förbehandlingen

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser