Mục lục
- Mục tiêu bài học
- Scikit-Learn là gì
- Cài đặt và import
- Triết lý sklearn — API thống nhất
- Cấu trúc thư viện — các submodule chính
- Quy ước input X và y
- Workflow chuẩn — 5 dòng code
- random_state và reproducibility
- Hyperparameter vs Parameter
- Estimator clone
- Những gì sklearn KHÔNG làm
- Tài nguyên học tập
- Bài tập thực hành
- Bài tiếp theo
Mục tiêu bài học
Sau khi đọc bài này, bạn sẽ:
- Biết sklearn là gì, ai phát triển và vị trí trong ecosystem ML Python.
- Hiểu triết lý API thống nhất:
fit/predict/transformdùng cho mọi model. - Nhớ được các submodule chính và biết tra cứu thuộc nhóm nào.
- Viết được workflow 5 dòng: load data → split → fit → score.
- Phân biệt được hyperparameter và parameter, hiểu vai trò
random_state. - Biết giới hạn của sklearn để chọn công cụ phù hợp khi gặp deep learning hoặc dữ liệu lớn.
Scikit-Learn là gì
Scikit-Learn (gọi tắt là sklearn) là thư viện Machine Learning cổ điển open-source viết bằng Python, build trên nền NumPy, SciPy và một phần Cython để tăng tốc.
Lịch sử ngắn:
- 2007: David Cournapeau khởi tạo dự án trong khuôn khổ Google Summer of Code, ban đầu tên scikits.learn (một SciKit của SciPy).
- 2010: nhóm tại INRIA (Pháp) — đặc biệt Fabian Pedregosa, Gaël Varoquaux, Alexandre Gramfort — phát hành public version đầu tiên.
- Từ đó tới nay duy trì bởi INRIA + cộng đồng, được Google, Microsoft, Quansight, Nvidia... tài trợ qua các grant.
- Paper gốc thường được trích dẫn: Pedregosa et al. (2011) — "Scikit-learn: Machine Learning in Python" trên JMLR.
Vị trí trong ecosystem:
- Sklearn lo phần ML cổ điển: linear/logistic regression, tree, ensemble, SVM, KNN, clustering, PCA, preprocessing, pipeline, model selection.
- Deep Learning (mạng nhiều tầng, GPU) thuộc về PyTorch / TensorFlow — sẽ học ở Series 3.
- LLM / Generative AI là một hướng khác hoàn toàn — Series 4.
Bài này dùng sklearn 1.5+ (bản phát hành 2024-2025). Một số API cũ (như load_boston) đã bị remove vì lý do đạo đức dữ liệu; sách / blog cũ trước 2022 cần đọc kèm changelog.
Cài đặt và import
Cài đặt:
pip install scikit-learn
# Hoặc dùng conda
conda install -c conda-forge scikit-learn
Google Colab, Kaggle Notebook, Jupyter image của jupyter/scipy-notebook đều có sẵn sklearn — không cần cài lại.
Kiểm tra version:
import sklearn
print(sklearn.__version__)
# Ví dụ output: 1.5.2
Convention import: sklearn không có alias chuẩn như np hay pd. Mọi thứ import theo dạng from sklearn.<submodule> import <Class>:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
Tránh viết import sklearn rồi gọi sklearn.linear_model.LogisticRegression(...) — dài và không phổ biến trong code thực tế.
Triết lý sklearn — API thống nhất
Điểm mạnh lớn nhất của sklearn không nằm ở số lượng thuật toán, mà ở consistent API: mọi object đều tuân theo cùng một bộ method. Nắm 3 interface dưới đây là dùng được hầu hết thư viện.
1. Estimator interface (model)
Mọi model dự đoán đều có:
.fit(X, y)— train model trên dữ liệu..predict(X)— sinh dự đoán cho dữ liệu mới..score(X, y)— đánh giá nhanh trên test set (accuracy cho classifier, R² cho regressor).
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train) # train
y_pred = model.predict(X_test) # predict
acc = model.score(X_test, y_test) # đánh giá
2. Transformer interface (preprocessor)
Các đối tượng biến đổi dữ liệu (scaler, encoder, PCA...) có:
.fit(X)— học thông số từ data (vd: mean, std)..transform(X)— áp dụng biến đổi..fit_transform(X)— shortcut: fit rồi transform luôn trên cùng tập.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train) # học mean/std trên train
X_test_scaled = scaler.transform(X_test) # chỉ transform, KHÔNG fit lại
Quy tắc vàng: fit trên train, transform trên cả train và test. Fit lại trên test sẽ leak thông tin và làm metric không trung thực.
3. Predictor cho unsupervised
Một số model unsupervised (vd KMeans) vừa là estimator vừa là transformer:
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=42)
km.fit(X)
labels = km.predict(X) # gán cluster
distances = km.transform(X) # khoảng cách tới mỗi centroid
Vì cùng một bộ method, việc swap model chỉ là đổi tên class — không cần viết lại pipeline. Đây là lý do sklearn dễ học và dễ thử nghiệm.
Cấu trúc thư viện — các submodule chính
Sklearn tổ chức theo submodule — biết tên submodule là biết tra ở đâu:
| Submodule | Mục đích | Ví dụ object |
|---|---|---|
sklearn.datasets |
Load dataset built-in / fetch dataset chuẩn | load_iris, load_digits, fetch_california_housing |
sklearn.model_selection |
Chia train/test, cross-validation, tìm hyperparameter | train_test_split, KFold, GridSearchCV |
sklearn.preprocessing |
Scaling, encoding, biến đổi feature | StandardScaler, MinMaxScaler, OneHotEncoder |
sklearn.linear_model |
Linear/logistic regression và biến thể regularized | LinearRegression, LogisticRegression, Ridge, Lasso |
sklearn.tree |
Decision tree | DecisionTreeClassifier, DecisionTreeRegressor |
sklearn.ensemble |
Bagging, boosting, voting | RandomForestClassifier, GradientBoostingRegressor |
sklearn.cluster |
Clustering unsupervised | KMeans, DBSCAN, AgglomerativeClustering |
sklearn.decomposition |
Giảm chiều | PCA, TruncatedSVD, NMF |
sklearn.metrics |
Hàm đo accuracy, MSE, F1, ROC... | accuracy_score, mean_squared_error, classification_report |
sklearn.pipeline |
Ghép preprocessor + model thành một estimator duy nhất | Pipeline, make_pipeline |
Còn nhiều submodule khác (neighbors, svm, naive_bayes, feature_selection, impute...). Khi cần một thuật toán, hỏi: "thuật toán này thuộc nhóm gì?" rồi vào submodule tương ứng tra cứu.
Lưu ý: load_boston đã bị remove từ sklearn 1.2 vì vấn đề đạo đức dữ liệu (biến chủng tộc trong feature). Dùng fetch_california_housing hoặc fetch_openml('ames_housing') thay thế cho bài tập regression giá nhà.
Quy ước input X và y
Mọi API sklearn đều giả định input có dạng cố định:
X: ma trận feature, shape(n_samples, n_features)— luôn 2 chiều, kể cả khi chỉ có 1 feature.y: vector label / target, shape(n_samples,)— 1 chiều cho single-output;(n_samples, n_outputs)cho multi-output.
Hỗ trợ cả NumPy array và Pandas DataFrame. Sklearn nội bộ sẽ chuyển DataFrame sang NumPy khi cần, nhưng giữ thông tin tên cột để báo lỗi rõ ràng hơn.
import numpy as np
import pandas as pd
# Cách 1: NumPy
X = np.array([[5.1, 3.5], [4.9, 3.0], [6.2, 3.4]])
y = np.array([0, 0, 1])
print(X.shape) # (3, 2)
print(y.shape) # (3,)
# Cách 2: Pandas DataFrame / Series
df = pd.DataFrame(X, columns=['sepal_length', 'sepal_width'])
target = pd.Series(y, name='species')
# model.fit(df, target) hoạt động bình thường
Lỗi thường gặp: đưa vào X 1 chiều khi chỉ có 1 feature.
X_wrong = np.array([1, 2, 3, 4]) # shape (4,) — SAI
X_right = np.array([[1], [2], [3], [4]]) # shape (4, 1) — ĐÚNG
# hoặc dùng reshape
X_right = np.array([1, 2, 3, 4]).reshape(-1, 1)
Workflow chuẩn — 5 dòng code
Để cảm nhận sự gọn gàng của sklearn, đây là một classification workflow hoàn chỉnh trên dataset Iris:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 1. Load data
X, y = load_iris(return_X_y=True)
# 2. Chia train / test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. Khởi tạo + train + đánh giá
model = LogisticRegression(max_iter=1000).fit(X_train, y_train)
print(f"Test accuracy: {model.score(X_test, y_test):.4f}")
# Output ví dụ: Test accuracy: 1.0000
Phân tích nhanh:
return_X_y=Truetrả về thẳng tuple (X, y) thay vì objectBunch— tiện cho code ngắn.test_size=0.2giữ 20% cho test (32 mẫu trên 150).max_iter=1000tăng số iteration solver vì mặc định 100 đôi khi không đủ converge — sklearn sẽ warning nếu thiếu..fit().score()chain được vì.fit()trả vềselftheo convention.
In thêm tên feature và label để hiểu data:
data = load_iris()
print("Feature names:", data.feature_names)
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print("Target names:", data.target_names)
# ['setosa' 'versicolor' 'virginica']
print("X shape:", data.data.shape, "y shape:", data.target.shape)
# X shape: (150, 4) y shape: (150,)
random_state và reproducibility
Rất nhiều function / class trong sklearn dùng số ngẫu nhiên: train_test_split trộn dữ liệu, RandomForest chọn feature ngẫu nhiên, KMeans khởi tạo centroid ngẫu nhiên...
Tham số random_state điều khiển bộ sinh số ngẫu nhiên. Cùng random_state → cùng kết quả khi chạy lại.
from sklearn.model_selection import train_test_split
# random_state = None (mặc định): mỗi lần chạy ra split khác nhau
X1, X2, y1, y2 = train_test_split(X, y, test_size=0.2)
# random_state = 42: chạy 100 lần vẫn ra cùng kết quả
X1, X2, y1, y2 = train_test_split(X, y, test_size=0.2, random_state=42)
Vì sao 42? Quy ước cộng đồng (joke từ Hitchhiker's Guide to the Galaxy). Số nào cũng được — quan trọng là phải cố định trong report và bài tập để người khác reproduce được kết quả.
Lưu ý: reproducibility tuyệt đối còn phụ thuộc version sklearn, NumPy, BLAS backend, OS. Cùng random_state trên 2 máy đôi khi vẫn lệch ở chữ số thập phân thứ 6-7 — chấp nhận được cho lab; cần lock chặt cho production.
Hyperparameter vs Parameter
Hai khái niệm dễ nhầm:
- Hyperparameter: tham số do người dùng set khi tạo estimator. Vd:
Ccủa Logistic Regression,n_estimatorscủa Random Forest,n_clusterscủa KMeans. - Parameter (weight, coefficient): giá trị model học từ data trong
.fit(). Vd:coef_vàintercept_của Linear Regression.
from sklearn.linear_model import LogisticRegression
# C, max_iter, solver — hyperparameter (đặt trước khi fit)
model = LogisticRegression(C=1.0, max_iter=1000, solver='lbfgs')
model.fit(X_train, y_train)
# coef_, intercept_ — parameter (học từ data, kết thúc bằng _)
print("coef_ shape:", model.coef_.shape)
print("intercept_:", model.intercept_)
Quy ước đặt tên: mọi thuộc tính kết thúc bằng dấu gạch dưới (coef_, feature_importances_, classes_) là parameter học được sau khi fit — truy cập trước khi fit sẽ raise NotFittedError.
Hyperparameter tuning (Grid Search, Random Search) là chủ đề riêng — sẽ học ở Module 6 cuối series.
Estimator clone
Khi cần một estimator cùng cấu hình nhưng chưa fit (vd để train trên fold khác trong cross-validation, hoặc thử cấu hình giống hệt trên dataset khác), dùng clone:
from sklearn.base import clone
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
# clone tạo bản copy: cùng hyperparameter, KHÔNG copy weight đã fit
rf_fresh = clone(rf)
print(hasattr(rf, 'classes_')) # True — đã fit
print(hasattr(rf_fresh, 'classes_')) # False — chưa fit
Phân biệt với copy.deepcopy: deepcopy sao chép cả trạng thái đã train (weight, classes_); clone chỉ giữ cấu hình. Cross-validation nội bộ của sklearn dùng clone.
Những gì sklearn KHÔNG làm
Biết giới hạn quan trọng không kém biết tính năng:
- Không có deep learning. Sklearn có
MLPClassifierđơn giản nhưng không phải framework DL. Mạng CNN, RNN, Transformer phải dùng PyTorch hoặc TensorFlow (Series 3). - Không có GPU support trực tiếp. Toàn bộ sklearn chạy trên CPU (single-host, multi-core qua
n_jobs). Nếu cần GPU cho thuật toán cổ điển, có cuML của Nvidia RAPIDS — API gần giống sklearn nhưng chạy GPU. - Không cho dataset out-of-memory. Sklearn giả định dữ liệu fit hết vào RAM. Khi dataset hàng chục GB, dùng Dask-ML, Vaex, hoặc partial_fit của một số estimator (
SGDClassifier,MiniBatchKMeans). - Không phải reinforcement learning library. RL có ecosystem riêng: Stable-Baselines3, RLlib, CleanRL.
- Không tự làm feature engineering domain-specific (text, ảnh, time-series phức tạp). Có module hỗ trợ cơ bản nhưng cần thư viện chuyên:
nltk/spacycho text,opencv/PILcho ảnh,statsmodels/prophetcho time-series.
Khi gặp bài toán vượt giới hạn này, chuyển công cụ chứ không cố ép sklearn.
Tài nguyên học tập
- User Guide tại
scikit-learn.org/stable/user_guide.html— viết kỹ, có lý thuyết kèm code; nên đọc mỗi khi gặp model mới. - API Reference tại
scikit-learn.org/stable/api/— tra cứu signature và parameter từng class. - Examples gallery tại
scikit-learn.org/stable/auto_examples/— code mẫu kèm hình vẽ, copy chạy được. - Sách: "Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow" — Aurélien Géron (O'Reilly, 3rd ed. 2022).
- Khóa MOOC chính chủ: "scikit-learn MOOC" của INRIA, miễn phí, có exercise.
Khi tra Stack Overflow / blog, lưu ý version. Code từ 2018-2020 có thể dùng API đã thay đổi (vd sklearn.cross_validation đã đổi thành sklearn.model_selection; load_boston đã remove).
Bài tập thực hành
Bài 1: Load dataset digits từ sklearn.datasets. In shape của X và y, số class, và 1-2 dòng đầu của X.
# Gợi ý
from sklearn.datasets import load_digits
data = load_digits()
# Hoàn thiện in shape, target_names, ...
Bài 2: Train LogisticRegression trên iris với random_state=0 và random_state=42. So sánh test accuracy giữa hai lần split. Giải thích vì sao có thể khác nhau dù cùng model.
Bài 3: Mở scikit-learn.org/stable/api/sklearn.linear_model.html (hoặc dùng dir(sklearn.linear_model)) và liệt kê 3 estimator khác ngoài LinearRegression / LogisticRegression. Ghi 1 câu giải thích từng cái (vd Ridge = linear regression có L2 regularization).
Bài 4 (nâng cao): Thay LogisticRegression trong workflow ở mục 7 bằng RandomForestClassifier(n_estimators=100, random_state=42). Quan sát: code phía ngoài có cần đổi gì không? (Trả lời ngắn: gần như không — đây chính là điểm mạnh của consistent API).
Gợi ý đáp án bài 2: hai random_state khác → train_test_split trả về hai cách chia khác → tập train / test có sample khác nhau → model học khác → score khác. Đây là lý do production đánh giá bằng cross-validation chứ không chỉ một split duy nhất.
Bài tiếp theo
Bài 5: Dataset đầu tiên — load_iris và làm quen với feature / label — mổ xẻ chi tiết dataset Iris (150 hoa, 4 feature, 3 loài), xem từng cột nghĩa là gì và thực hành visualize trước khi train.
Tài liệu tham khảo
- Scikit-Learn — Official documentation
- Scikit-Learn — User Guide
- Scikit-Learn — Developer guide: API conventions (fit/transform/predict)
- Pedregosa et al. — Scikit-learn: Machine Learning in Python, JMLR 2011
- Buitinck et al. — API design for machine learning software: experiences from the scikit-learn project, arXiv:1309.0238 (2013)
- Scikit-Learn — Release notes (changelog các version)
- INRIA — scikit-learn MOOC (free course)
- RAPIDS cuML — sklearn-compatible API trên GPU
