Feature Engineering w Machine Learning: Techniki, Pipelines i Pytania Rekrutacyjne 2026
Kompletny przewodnik po feature engineering w uczeniu maszynowym: kodowanie zmiennych, skalowanie, transformacje, selekcja cech i pytania rekrutacyjne na 2026 rok.

Feature engineering stanowi fundament skutecznego modelowania w uczeniu maszynowym. Surowe dane niemal nigdy nie trafiają do algorytmów w postaci gotowej do bezpośredniego wykorzystania — to właśnie transformacja danych w wartościowe cechy decyduje o przepaści między przeciętnym a wybitnym modelem predykcyjnym.
Każdy doświadczony data scientist wie, że zbiór danych pobrany z bazy produkcyjnej lub API zewnętrznego wymaga gruntownego przetworzenia. Braki danych, rozkłady skośne, zmienne kategoryczne bez naturalnego porządku, wartości odstające — wszystko to wymaga świadomych decyzji inżynierskich, zanim jakikolwiek klasyfikator lub regresor otrzyma dane wejściowe.
Badania konsekwentnie potwierdzają, że decyzje dotyczące preprocessingu i inżynierii cech mają większy wpływ na dokładność modelu niż strojenie hiperparametrów. Dobrze zaprojektowany zbiór cech potrafi sprawić, że prosta regresja logistyczna pokona źle przygotowany model gradient boosting.
Strategie kodowania zmiennych kategorycznych
Zmienne kategoryczne stanowią jedno z najczęstszych wyzwań w przygotowaniu danych. Algorytmy uczenia maszynowego operują na liczbach, więc każda wartość tekstowa musi zostać przekształcona w reprezentację numeryczną. Wybór metody kodowania zależy od natury zmiennej — czy posiada naturalny porządek (ordinalna), czy też nie (nominalna).
Label Encoding przypisuje każdej kategorii unikalny numer całkowity. Sprawdza się doskonale w przypadku zmiennych ordinalnych, takich jak rozmiar (mały, średni, duży), gdzie istnieje logiczna hierarchia. Algorytmy drzewiaste (Random Forest, XGBoost) radzą sobie z takim kodowaniem nawet dla zmiennych nominalnych, ponieważ dokonują podziału na podstawie progów.
One-Hot Encoding tworzy osobną kolumnę binarną dla każdej kategorii. Jest to metoda preferowana dla zmiennych nominalnych w modelach liniowych i sieciach neuronowych, ponieważ nie narzuca fałszywego porządku między kategoriami. Parametr drop="first" eliminuje jedną kolumnę referencyjną, co zapobiega współliniowości w modelach liniowych.
# encoding_strategies.py
import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.compose import ColumnTransformer
df = pd.DataFrame({
"size": ["small", "medium", "large", "medium", "small"],
"color": ["red", "blue", "green", "red", "blue"],
"price": [10, 25, 40, 22, 12]
})
# Label encoding for ordinal feature (size has natural order)
le = LabelEncoder()
df["size_encoded"] = le.fit_transform(df["size"]) # large=0, medium=1, small=2
# One-hot encoding for nominal feature (color has no order)
ct = ColumnTransformer(
transformers=[
("onehot", OneHotEncoder(drop="first", sparse_output=False), ["color"])
],
remainder="passthrough" # Keep other columns unchanged
)
result = ct.fit_transform(df[["color", "price"]])
# Produces: color_green, color_red columns (blue dropped as reference)W praktyce produkcyjnej warto również rozważyć Target Encoding (kodowanie średnią zmiennej docelowej) dla zmiennych o dużej liczbie kategorii. Technika ta zastępuje każdą kategorię średnią wartością zmiennej docelowej obliczoną na zbiorze treningowym, co pozwala uniknąć eksplozji wymiarowości typowej dla one-hot encoding przy setkach kategorii.
Skalowanie cech: StandardScaler, MinMaxScaler i RobustScaler
Skalowanie cech numerycznych jest niezbędne dla algorytmów wrażliwych na skalę zmiennych. Modele oparte na odległości (KNN, SVM), regresja liniowa z regularyzacją oraz sieci neuronowe wymagają, aby cechy miały porównywalne zakresy wartości. Bez skalowania cecha o zakresie 0–1000 zdominuje cechę o zakresie 0–1.
StandardScaler transformuje dane do rozkładu o średniej 0 i odchyleniu standardowym 1. Jest to domyślny wybór w większości przypadków, ale wykazuje wrażliwość na wartości odstające, które zaburzają obliczaną średnią i odchylenie.
MinMaxScaler mapuje wartości do zakresu [0, 1]. Przydatny, gdy algorytm wymaga danych w ściśle określonym przedziale (np. sieci neuronowe z funkcją aktywacji sigmoid). Jego słabością jest ekstremalna wrażliwość na outlinery — pojedyncza wartość odstająca może skompresować wszystkie pozostałe obserwacje do wąskiego pasma.
RobustScaler używa mediany i rozstępu międzykwartylowego (IQR) zamiast średniej i odchylenia standardowego. Dzięki temu wartości odstające nie zaburzają skalowania rdzenia danych, co czyni go idealnym wyborem dla zbiorów z anomaliami.
# feature_scaling.py
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
# Simulated dataset: salary with outliers
data = np.array([[35000], [42000], [55000], [67000], [450000]]) # 450k is an outlier
# StandardScaler: mean=0, std=1 (sensitive to outliers)
standard = StandardScaler().fit_transform(data)
# Result: [-0.72, -0.68, -0.60, -0.53, 2.53] — outlier distorts the scale
# MinMaxScaler: maps to [0, 1] (very sensitive to outliers)
minmax = MinMaxScaler().fit_transform(data)
# Result: [0.0, 0.017, 0.048, 0.077, 1.0] — most values crushed near zero
# RobustScaler: uses median and IQR (robust to outliers)
robust = RobustScaler().fit_transform(data)
# Result: [-0.77, -0.5, 0.0, 0.46, 15.38] — outlier isolated, core data preservedPodczas rozmowy kwalifikacyjnej warto podkreślić, że skalowanie wykonuje się po podziale na zbiór treningowy i testowy. Dopasowanie skalera na całym zbiorze danych przed podziałem prowadzi do wycieku danych (data leakage), ponieważ statystyki zbioru testowego wpływają na transformacje danych treningowych.
Transformacje matematyczne dla rozkładów skośnych
Wiele rzeczywistych zmiennych — dochody, ceny nieruchomości, liczba transakcji — wykazuje silną skośność prawostronną. Kilka procent obserwacji o ekstremalnie wysokich wartościach wydłuża prawy ogon rozkładu, co negatywnie wpływa na modele zakładające normalność rozkładu cech.
Transformacja logarytmiczna (np.log1p) to najprostsze rozwiązanie. Kompresuje duże wartości i rozciąga małe, przybliżając rozkład do normalnego. Funkcja log1p (logarytm z 1+x) bezpiecznie obsługuje wartości zerowe.
Box-Cox automatycznie dobiera optymalny parametr potęgowy lambda, który najlepiej normalizuje rozkład. Wymaga jednak ściśle dodatnich wartości — dane z zerami lub wartościami ujemnymi wymagają wstępnego przesunięcia.
Yeo-Johnson rozszerza Box-Cox o obsługę wartości zerowych i ujemnych, co czyni go bardziej uniwersalnym wyborem w praktyce.
# skew_transformations.py
import numpy as np
from sklearn.preprocessing import PowerTransformer
# Right-skewed income data (common in real datasets)
income = np.array([[25000], [32000], [41000], [55000], [72000],
[150000], [320000], [890000]])
# Log transform: simple, effective for right-skewed data
log_income = np.log1p(income) # log1p handles zero values safely
# Box-Cox: finds optimal power parameter automatically
pt = PowerTransformer(method="box-cox") # Requires strictly positive values
income_boxcox = pt.fit_transform(income)
print(f"Optimal lambda: {pt.lambdas_[0]:.3f}") # Shows learned parameter
# Yeo-Johnson: works with zero and negative values too
pt_yj = PowerTransformer(method="yeo-johnson")
income_yj = pt_yj.fit_transform(income)Warto pamiętać, że transformacje potęgowe nie zawsze są konieczne. Modele drzewiaste (Random Forest, XGBoost, LightGBM) są z natury odporne na rozkłady skośne, ponieważ dokonują podziału na podstawie progów, a nie odległości. Transformacje mają największy sens w kontekście modeli liniowych, SVM z jądrem RBF oraz sieci neuronowych.
Selekcja cech: eliminacja szumu przed trenowaniem
Nie każda dostępna cecha przyczynia się do lepszej predykcji. Cechy irrelewantne lub redundantne zwiększają złożoność modelu, wydłużają czas trenowania i mogą prowadzić do overfittingu. Selekcja cech pozwala zidentyfikować podzbiór zmiennych, który maksymalizuje moc predykcyjną przy minimalnej złożoności.
Istnieją trzy główne podejścia do selekcji cech:
Metody filtrujące oceniają każdą cechę niezależnie od modelu, korzystając z testów statystycznych (ANOVA, chi-kwadrat, korelacja). Są szybkie obliczeniowo, ale nie uwzględniają interakcji między cechami.
Metody wrappingowe iteracyjnie dobierają podzbiory cech, trenując model na każdym z nich i oceniając wynik. Sequential Feature Selection (SFS) dodaje lub usuwa cechy po jednej, optymalizując zadaną metrykę. Są dokładne, ale kosztowne obliczeniowo.
Metody osadzone (embedded) realizują selekcję cech jako integralną część procesu trenowania. Regularyzacja L1 (Lasso) zeruje wagi nieistotnych cech, a modele drzewiaste obliczają ważność cech na podstawie redukcji nieczystości.
# feature_selection.py
from sklearn.datasets import make_classification
from sklearn.feature_selection import (
SelectKBest, f_classif, # Filter method
SequentialFeatureSelector, # Wrapper method
SelectFromModel # Embedded method
)
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LassoCV
# Dataset: 20 features, only 5 are informative
X, y = make_classification(
n_samples=1000, n_features=20,
n_informative=5, n_redundant=3, random_state=42
)
# Filter: ANOVA F-test selects top k features by statistical significance
selector_filter = SelectKBest(f_classif, k=8)
X_filtered = selector_filter.fit_transform(X, y)
print(f"Selected features: {selector_filter.get_support(indices=True)}")
# Embedded: L1 regularization (Lasso) zeros out irrelevant feature weights
lasso = LassoCV(cv=5, random_state=42).fit(X, y)
selector_embedded = SelectFromModel(lasso, prefit=True)
X_lasso = selector_embedded.transform(X)
print(f"Lasso kept {X_lasso.shape[1]} features out of {X.shape[1]}")Podczas rozmowy rekrutacyjnej często pojawia się pytanie o różnicę między selekcją cech a redukcją wymiarowości (PCA). Kluczowa odpowiedź: selekcja cech zachowuje oryginalne zmienne (interpretowalność), podczas gdy PCA tworzy nowe, syntetyczne komponenty będące kombinacjami liniowymi oryginalnych cech.
Gotowy na rozmowy o Data Science & ML?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Budowanie produkcyjnych pipeline'ów z ColumnTransformer
W środowisku produkcyjnym poszczególne kroki preprocessingu nie mogą istnieć jako oddzielne skrypty. Pipeline z scikit-learn łączy transformacje i model w jeden obiekt, który gwarantuje spójność między trenowaniem a inferencją. ColumnTransformer umożliwia zastosowanie różnych transformacji do różnych grup kolumn.
Taki pipeline eliminuje trzy krytyczne problemy:
- Wyciek danych — transformacje są dopasowywane wyłącznie na foldach treningowych podczas walidacji krzyżowej
- Niespójność — ten sam obiekt pipeline obsługuje dane treningowe, walidacyjne i produkcyjne
- Brak powtarzalności — pipeline można serializować (
joblib.dump) i wdrożyć jako artefakt modelu
# production_pipeline.py
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import cross_val_score
# Define column groups by type
numeric_features = ["age", "income", "credit_score"]
categorical_features = ["education", "employment_type", "region"]
# Numeric pipeline: impute missing values, then scale
numeric_pipeline = Pipeline([
("imputer", SimpleImputer(strategy="median")), # Median resists outliers
("scaler", StandardScaler())
])
# Categorical pipeline: impute missing, then one-hot encode
categorical_pipeline = Pipeline([
("imputer", SimpleImputer(strategy="most_frequent")),
("encoder", OneHotEncoder(handle_unknown="ignore", sparse_output=False))
])
# Combine into a single preprocessor
preprocessor = ColumnTransformer([
("num", numeric_pipeline, numeric_features),
("cat", categorical_pipeline, categorical_features)
])
# Full pipeline: preprocessing + model in one object
full_pipeline = Pipeline([
("preprocessor", preprocessor),
("classifier", GradientBoostingClassifier(n_estimators=200, random_state=42))
])
# Cross-validation applies preprocessing correctly within each fold
scores = cross_val_score(full_pipeline, X, y, cv=5, scoring="roc_auc")
print(f"AUC: {scores.mean():.3f} +/- {scores.std():.3f}")Parametr handle_unknown="ignore" w OneHotEncoder jest kluczowy w produkcji — jeśli pojawi się kategoria nieobecna w danych treningowych, encoder zwróci wektor zerowy zamiast rzucić wyjątek.
Automatyczna inżynieria cech z Featuretools
Ręczne tworzenie cech wymaga głębokiej znajomości domeny i jest czasochłonne. Biblioteka Featuretools automatyzuje ten proces za pomocą techniki Deep Feature Synthesis (DFS), która generuje cechy na podstawie relacji między tabelami.
DFS operuje na dwóch typach prymitywów:
- Agregacyjne (count, mean, max, std) — podsumowują dane z tabel podrzędnych na poziomie tabeli nadrzędnej
- Transformacyjne (month, weekday, hour) — tworzą nowe cechy z pojedynczych kolumn
Parametr max_depth kontroluje złożoność generowanych cech. Głębokość 1 tworzy proste agregacje (np. średnia kwota transakcji per klient), natomiast głębokość 2 generuje cechy zagnieżdżone (np. odchylenie standardowe miesięcznych średnich kwot transakcji per klient).
# automated_feature_engineering.py
import featuretools as ft
import pandas as pd
# Define entities from relational tables
customers = pd.DataFrame({
"customer_id": [1, 2, 3],
"signup_date": pd.to_datetime(["2024-01-15", "2024-03-22", "2024-06-01"]),
"region": ["US", "EU", "APAC"]
})
transactions = pd.DataFrame({
"txn_id": range(1, 8),
"customer_id": [1, 1, 1, 2, 2, 3, 3],
"amount": [50, 120, 30, 200, 85, 340, 15],
"category": ["food", "tech", "food", "tech", "travel", "food", "tech"]
})
# Create an EntitySet with relationships
es = ft.EntitySet(id="retail")
es = es.add_dataframe(dataframe=customers, dataframe_name="customers",
index="customer_id", time_index="signup_date")
es = es.add_dataframe(dataframe=transactions, dataframe_name="transactions",
index="txn_id")
es = es.add_relationship("customers", "customer_id",
"transactions", "customer_id")
# DFS generates features: COUNT, MEAN, MAX, STD of transactions per customer
feature_matrix, feature_defs = ft.dfs(
entityset=es, target_dataframe_name="customers",
max_depth=2, # Controls complexity of generated features
trans_primitives=["month", "weekday"], # Transformation primitives
agg_primitives=["count", "mean", "std", "max"] # Aggregation primitives
)
print(f"Generated {len(feature_defs)} features from 2 tables")Featuretools sprawdza się szczególnie w projektach z danymi relacyjnymi (e-commerce, bankowość, telekomunikacja), gdzie ręczne tworzenie agregacji z wielu tabel zajmuje tygodnie. Warto jednak pamiętać, że automatycznie wygenerowane cechy wymagają walidacji domenowej — nie każda statystycznie możliwa kombinacja ma sens biznesowy.
Najczęściej zadawane pytania rekrutacyjne o Feature Engineering
Poniżej znajdują się pytania, które regularnie pojawiają się na rozmowach kwalifikacyjnych na stanowiska data scientist i ML engineer w 2026 roku.
P: Czym różni się Label Encoding od One-Hot Encoding i kiedy stosować każde z nich?
Label Encoding przypisuje kolejne liczby całkowite kategoriom. Nadaje się do zmiennych ordinalnych (rozmiar, wykształcenie) oraz modeli drzewiastych. One-Hot Encoding tworzy kolumny binarne — jest konieczny dla zmiennych nominalnych w modelach liniowych, KNN i sieciach neuronowych, aby uniknąć narzucenia fałszywego porządku.
P: Dlaczego skalowanie cech jest ważne i które algorytmy tego wymagają?
Algorytmy oparte na odległości (KNN, SVM), regresja z regularyzacją (Ridge, Lasso) i sieci neuronowe wymagają skalowania, ponieważ cechy o większych zakresach dominują w obliczeniach. Modele drzewiaste nie wymagają skalowania, gdyż dokonują podziału na podstawie progów.
P: Jak radzić sobie z wartościami odstającymi podczas feature engineering?
Kilka podejść: użycie RobustScaler zamiast StandardScaler, transformacje logarytmiczne kompresujące ogony rozkładu, winsoryzacja (przycinanie do percentyli np. 1. i 99.), lub usuwanie obserwacji po analizie domenowej potwierdzającej, że są błędem pomiarowym.
P: Czym jest data leakage w kontekście feature engineering i jak mu zapobiegać?
Data leakage występuje, gdy informacja ze zbioru testowego przenika do procesu trenowania. Typowy przykład: dopasowanie skalera na całym zbiorze przed podziałem train/test. Zapobiega mu stosowanie pipeline'ów scikit-learn, które wykonują fit wyłącznie na danych treningowych w każdym foldzie walidacji krzyżowej.
P: Kiedy stosować PCA zamiast selekcji cech?
PCA redukuje wymiarowość tworząc nowe, ortogonalne komponenty — przydatne gdy cechy są silnie skorelowane lub gdy interpretowalność nie jest priorytetem (np. przetwarzanie obrazów). Selekcja cech zachowuje oryginalne zmienne, co jest kluczowe w domenach wymagających wyjaśnienia decyzji modelu (finanse, medycyna).
P: Jak obsłużyć zmienne kategoryczne o bardzo dużej liczbie kategorii (high cardinality)?
One-hot encoding staje się niepraktyczny przy setkach kategorii. Alternatywy to: target encoding (średnia zmiennej docelowej per kategoria z regularyzacją), frequency encoding (częstotliwość występowania kategorii), hash encoding (zmniejsza wymiarowość kosztem kolizji) lub embeddingi uczone w sieciach neuronowych.
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Podsumowanie
Feature engineering pozostaje jedną z najważniejszych kompetencji data scientista i ML engineera. Kluczowe wnioski z tego przewodnika:
- Kodowanie kategoryczne: Label Encoding dla zmiennych ordinalnych, One-Hot Encoding dla nominalnych, Target Encoding dla wysokiej kardynalności
- Skalowanie: StandardScaler jako domyślny wybór, RobustScaler w obecności outlierów, MinMaxScaler dla ściśle określonych przedziałów
- Transformacje: logarytmiczna, Box-Cox i Yeo-Johnson normalizują rozkłady skośne — kluczowe dla modeli liniowych, zbędne dla modeli drzewiastych
- Selekcja cech: metody filtrujące (szybkie, niezależne od modelu), wrappingowe (dokładne, kosztowne) i osadzone (L1, ważność cech w drzewach)
- Pipeline'y:
ColumnTransformer+Pipelinegwarantują spójność, eliminują data leakage i umożliwiają serializację - Automatyzacja: Featuretools i Deep Feature Synthesis przyspieszają generowanie cech z danych relacyjnych
- Rozmowy kwalifikacyjne: nacisk na zrozumienie trade-offów między metodami, data leakage i praktyczne zastosowanie pipeline'ów
Opanowanie tych technik nie tylko poprawia wyniki modeli, ale stanowi też silny sygnał kompetencji podczas procesów rekrutacyjnych w branży data science.
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Tagi
Udostępnij
Powiązane artykuły

Python w Data Science: NumPy, Pandas i Scikit-Learn w 2026
Praktyczny przewodnik po NumPy 2.1, Pandas 2.2 i Scikit-Learn 1.6 w Pythonie 3.12. Od czyszczenia danych przez inżynierię cech po kompletny pipeline ML — z pełnymi przykładami kodu.

PyTorch vs TensorFlow w 2026: Ktory framework deep learningu wybrac?
Porownanie PyTorch i TensorFlow w 2026 roku: torch.compile vs XLA, debugowanie, ekosystem, wdrazanie modeli produkcyjnych i pytania rekrutacyjne. Kompleksowy przewodnik dla inzynierow ML.

Algorytmy uczenia maszynowego: kompletny przewodnik po rozmowach technicznych
Opanowanie kluczowych algorytmów uczenia maszynowego wymaganych na rozmowach technicznych w 2026 roku. Uczenie nadzorowane i nienadzorowane, metody zespolowe, metryki ewaluacji i regularyzacja z implementacjami w Pythonie.