Feature Engineering cho Machine Learning: Kỹ thuật và Câu hỏi Phỏng vấn 2026

Nắm vững các kỹ thuật feature engineering cho machine learning với các ví dụ Python thực tế. Bao gồm encoding, scaling, chọn lọc đặc trưng, pipeline scikit-learn và các câu hỏi phỏng vấn data science.

Feature engineering cho machine learning: minh họa pipeline chuyển đổi dữ liệu

Feature engineering quyết định mức độ hiệu quả của một mô hình machine learning. Dữ liệu thô hiếm khi ở dạng mà các thuật toán có thể khai thác trực tiếp — việc chuyển đổi dữ liệu thành các đặc trưng có ý nghĩa là cầu nối giữa thu thập dữ liệu và độ chính xác của mô hình.

Tại sao Feature Engineering quan trọng

Các nghiên cứu liên tục cho thấy rằng các lựa chọn preprocessing và feature engineering có tác động lớn hơn đến độ chính xác của mô hình so với việc tinh chỉnh hyperparameter. Một tập hợp đặc trưng được thiết kế tốt có thể giúp một mô hình hồi quy logistic đơn giản vượt trội hơn một mô hình gradient boosting với các đặc trưng kém.

Chiến lược Encoding Phân loại cho các Mô hình ML

Hầu hết các thuật toán machine learning yêu cầu đầu vào là số. Các biến phân loại — nhãn văn bản như "cao", "trung bình", "thấp" hoặc tên quốc gia — cần được chuyển đổi thành số mà mô hình có thể xử lý. Chiến lược encoding ảnh hưởng trực tiếp đến hiệu suất và khả năng diễn giải của mô hình.

Ba kỹ thuật encoding bao phủ phần lớn các tình huống thực tế: label encoding cho dữ liệu thứ tự, one-hot encoding cho các danh mục danh định, và target encoding cho các đặc trưng có số lượng giá trị duy nhất cao.

python
# 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)

Label encoding phù hợp với các đặc trưng thứ tự, nơi thứ tự số tương ứng với thứ tự danh mục. One-hot encoding ngăn mô hình suy ra các mối quan hệ thứ tự sai giữa các danh mục danh định. Tham số drop="first" tránh bẫy biến giả bằng cách loại bỏ một cột dư thừa.

Target Encoding và Rò rỉ Dữ liệu

Target encoding thay thế mỗi danh mục bằng giá trị trung bình của mục tiêu cho nhóm đó. Mặc dù rất hiệu quả cho các đặc trưng có số lượng giá trị duy nhất cao (mã bưu chính, ID sản phẩm), kỹ thuật này làm rò rỉ thông tin mục tiêu vào các đặc trưng. Luôn áp dụng target encoding bên trong các fold cross-validation bằng lớp TargetEncoder của scikit-learn để tránh các chỉ số đánh giá quá lạc quan.

Feature Scaling: StandardScaler vs MinMaxScaler vs RobustScaler

Các thuật toán dựa trên khoảng cách (KNN, SVM, K-Means) và các bộ tối ưu gradient descent mặc định xử lý tất cả các đặc trưng như nhau. Một cột lương với phạm vi từ 30.000 đến 200.000 sẽ áp đảo một cột kinh nghiệm làm việc với phạm vi từ 0 đến 40 nếu không có scaling.

Việc lựa chọn scaler phụ thuộc vào phân phối dữ liệu và độ nhạy với outlier.

python
# 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 preserved

StandardScaler phù hợp với hầu hết các trường hợp sử dụng — mô hình tuyến tính, mạng nơ-ron và PCA đều mong đợi các đặc trưng đã được chuẩn hóa. MinMaxScaler thích hợp với các hàm kích hoạt có giới hạn (sigmoid, tanh) và chuẩn hóa pixel hình ảnh. RobustScaler nên là lựa chọn mặc định khi có outlier trong tập dữ liệu, như đã được ghi nhận trong hướng dẫn preprocessing của scikit-learn.

Biến đổi Toán học cho các Phân phối Lệch

Các đặc trưng bị lệch vi phạm giả định phân phối chuẩn của các mô hình tuyến tính và làm tăng ảnh hưởng của các giá trị cực đoan. Các phép biến đổi log, căn bậc hai và Box-Cox nén phần đuôi của các phân phối lệch, đưa chúng gần hơn với phân phối chuẩn.

python
# 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)

PowerTransformer với Box-Cox hoặc Yeo-Johnson tự động học tham số biến đổi tối ưu. Yeo-Johnson xử lý được các giá trị bằng không và âm, khiến nó trở thành lựa chọn mặc định an toàn hơn. Luôn kiểm tra phân phối kết quả bằng biểu đồ Q-Q hoặc kiểm định Shapiro-Wilk để xác nhận phép biến đổi đã cải thiện tính chuẩn.

Chọn lọc Đặc trưng: Loại bỏ Nhiễu trước khi Huấn luyện

Nhiều đặc trưng hơn không phải lúc nào cũng đồng nghĩa với dự đoán tốt hơn. Các đặc trưng không liên quan hoặc dư thừa tạo ra nhiễu, tăng thời gian huấn luyện và gây overfitting — đặc biệt trong các tập dữ liệu nhiều chiều, nơi số lượng đặc trưng gần bằng hoặc vượt quá số lượng mẫu.

Ba phương pháp chọn lọc đặc trưng: phương pháp filter (kiểm định thống kê), phương pháp wrapper (đánh giá dựa trên mô hình), và phương pháp embedded (tích hợp trong quá trình huấn luyện).

python
# 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]}")

Phương pháp filter (ANOVA, chi-squared, mutual information) chạy nhanh nhưng đánh giá các đặc trưng một cách độc lập — chúng bỏ sót các tương tác giữa các đặc trưng. Phương pháp embedded như chính quy hóa Lasso thực hiện chọn lọc trong quá trình huấn luyện, tạo ra các mô hình thưa có khả năng tổng quát hóa tốt hơn. Để hiểu sâu hơn về các thuật toán đằng sau các mô hình này, hướng dẫn thuật toán machine learning trình bày các nền tảng toán học.

Sẵn sàng chinh phục phỏng vấn Data Science & ML?

Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.

Xây dựng Pipeline Sẵn sàng cho Sản xuất với ColumnTransformer

Việc phân tán các bước preprocessing trên các ô notebook tạo ra các quy trình làm việc dễ vỡ và không thể tái tạo. PipelineColumnTransformer của scikit-learn đóng gói toàn bộ quy trình feature engineering thành một đối tượng duy nhất, có thể serialize và ngăn chặn rò rỉ dữ liệu trong cross-validation.

python
# 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}")

Pipeline đảm bảo rằng các thống kê imputation, tham số scaling và ánh xạ encoding chỉ được tính toán từ dữ liệu huấn luyện trong mỗi fold cross-validation. Gọi full_pipeline.fit(X_train, y_train) sau đó full_pipeline.predict(X_test) áp dụng các phép biến đổi giống hệt nhau mà không bị rò rỉ thông tin. Toàn bộ pipeline có thể được serialize bằng joblib.dump() để triển khai.

Feature Engineering Tự động với Featuretools

Feature engineering thủ công hoạt động tốt cho các tập dữ liệu có cấu trúc với vài chục cột. Các tập dữ liệu quan hệ trải dài trên nhiều bảng — giao dịch liên kết với khách hàng liên kết với thương nhân — cần các phương pháp tự động để khám phá các tổ hợp đặc trưng một cách hệ thống.

Featuretools triển khai Deep Feature Synthesis (DFS), duyệt qua các mối quan hệ thực thể và áp dụng các primitive biến đổi và tổng hợp để tạo ra hàng trăm đặc trưng ứng viên một cách tự động.

python
# 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")

DFS tạo ra các đặc trưng như MEAN(transactions.amount), STD(transactions.amount)COUNT(transactions) — các phép tổng hợp mà một nhà khoa học dữ liệu thường tạo thủ công nhưng trong thời gian ngắn hơn nhiều. Tham số max_depth kiểm soát độ phức tạp của đặc trưng: độ sâu 2 tạo ra các phép tổng hợp lồng nhau như STD(transactions.MONTH(signup_date)).

Mẹo Phỏng vấn Feature Engineering

Người phỏng vấn thường yêu cầu ứng viên thiết kế các đặc trưng cho một bài toán kinh doanh cụ thể (dự đoán rời bỏ, phát hiện gian lận, hệ thống gợi ý). Hãy luyện tập xây dựng các đặc trưng theo khung recency, frequency và monetary value (phân tích RFM) — ba chiều này áp dụng cho hầu hết mọi bài toán ML liên quan đến khách hàng. Xem lại các câu hỏi phỏng vấn feature engineering phổ biến để chuẩn bị.

Các Câu hỏi Phỏng vấn Feature Engineering Thường gặp

Các buổi phỏng vấn data science năm 2026 kiểm tra cả hiểu biết lý thuyết lẫn khả năng triển khai thực tế của feature engineering. Các câu hỏi sau đây xuất hiện thường xuyên trong các buổi phỏng vấn tại các công ty công nghệ lớn và startup.

H: Làm thế nào để xử lý đặc trưng phân loại có hơn 10.000 giá trị duy nhất?

Các biến phân loại có số lượng giá trị duy nhất cao không thể sử dụng one-hot encoding — vì sẽ tạo ra 10.000 cột thưa. Các chiến lược hiệu quả bao gồm: target encoding (với cross-validation đúng cách để tránh rò rỉ), frequency encoding (thay thế danh mục bằng số lần xuất hiện), hashing (sử dụng HashingVectorizer để ánh xạ danh mục vào không gian có kích thước cố định), và các lớp embedding trong mạng nơ-ron.

H: Khi nào KHÔNG nên scaling các đặc trưng?

Các mô hình dựa trên cây quyết định (Random Forest, XGBoost, LightGBM) không bị ảnh hưởng bởi các phép biến đổi đơn điệu trên đặc trưng. Scaling chỉ thêm tính toán không cần thiết mà không ảnh hưởng đến các điểm chia. Các mô hình dựa trên khoảng cách và mạng nơ-ron luôn cần scaling.

H: Giải thích sự khác biệt giữa feature selection và dimensionality reduction.

Feature selection giữ lại một tập con các đặc trưng gốc — các đặc trưng được chọn vẫn có thể diễn giải được. Dimensionality reduction (PCA, t-SNE, UMAP) tạo ra các đặc trưng tổng hợp mới như là các tổ hợp tuyến tính hoặc phi tuyến của các đặc trưng gốc. Các thành phần PCA tối đa hóa explained variance nhưng mất khả năng diễn giải trực tiếp. Sự lựa chọn phụ thuộc vào việc khả năng giải thích của mô hình có phải là yêu cầu của dự án hay không.

H: Làm thế nào để phát hiện và xử lý đa cộng tuyến?

Variance Inflation Factor (VIF) trên 5-10 cho thấy đa cộng tuyến có vấn đề. Ma trận tương quan bắt được các mối quan hệ cặp đôi nhưng bỏ sót các phụ thuộc đa biến. Các giải pháp bao gồm loại bỏ một trong các đặc trưng tương quan, kết hợp chúng (PCA trên tập con tương quan), hoặc sử dụng chính quy hóa (Ridge/Lasso) xử lý cộng tuyến một cách nội tại.

Để thực hành trực tiếp với các thư viện thao tác dữ liệu Python cần thiết cho feature engineering, hướng dẫn Python cho Data Science trình bày chi tiết các quy trình làm việc với NumPy, Pandas và scikit-learn.

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Kết luận

  • Thực hiện encoding phân loại một cách có chủ đích: label encoding cho dữ liệu thứ tự, one-hot cho danh định, target encoding (bên trong các fold CV) cho đặc trưng có số lượng giá trị duy nhất cao
  • Scaling đặc trưng dựa trên yêu cầu của mô hình: StandardScaler cho mô hình tuyến tính và mạng nơ-ron, bỏ qua scaling cho mô hình dựa trên cây
  • Áp dụng các phép biến đổi lũy thừa (PowerTransformer) để giảm độ lệch trước khi đưa dữ liệu vào các thuật toán giả định phân phối chuẩn
  • Chọn lọc đặc trưng một cách hệ thống bằng phương pháp filter cho tốc độ, phương pháp embedded (Lasso) cho độ chính xác, và luôn xác nhận bằng cross-validation
  • Đóng gói tất cả preprocessing vào Pipeline + ColumnTransformer của scikit-learn để ngăn chặn rò rỉ dữ liệu và đảm bảo khả năng tái tạo
  • Tự động hóa việc tạo đặc trưng với Featuretools DFS cho các tập dữ liệu quan hệ trải dài trên nhiều bảng
  • Luyện tập giải thích các quyết định feature engineering bằng ngôn ngữ kinh doanh — người phỏng vấn đánh giá cả kỹ năng kỹ thuật lẫn sự rõ ràng trong giao tiếp

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Thẻ

#feature engineering
#machine learning
#scikit-learn
#data science
#phỏng vấn
#python

Chia sẻ

Bài viết liên quan