Python trong Khoa học dữ liệu: Machine Learning cơ bản

Machine Learning (ML) là trái tim của Khoa học dữ liệu hiện đại. Thay vì lập trình từng quy tắc thủ công, bạn để máy tính học patterns từ dữ liệu và đưa ra dự đoán. Python — với hệ sinh thái thư viện phong phú — là ngôn ngữ số một cho ML, và scikit-learn là thư viện lý tưởng để bắt đầu.
Bài viết này hướng dẫn toàn diện: khái niệm ML, kiến thức nền, workflow chuẩn, tutorial scikit-learn với code đầy đủ, bảng thuật toán, metrics đánh giá, cách tránh overfitting, 5 dự án thực hành, và FAQ.
1. Giới thiệu Machine Learning
ML là gì?
Machine Learning là nhánh của Trí tuệ nhân tạo (AI) tập trung vào việc xây dựng hệ thống tự học từ dữ liệu. Thay vì viết if area > 100 then price = X, bạn cung cấp hàng nghìn mẫu (diện tích, số phòng, giá) và để thuật toán tìm mối quan hệ.
Ba loại Machine Learning chính
| Loại | Dữ liệu | Mục tiêu | Ví dụ |
|---|---|---|---|
| Supervised Learning | Có nhãn (label) | Dự đoán hoặc phân loại | Dự đoán giá nhà, phân loại spam |
| Unsupervised Learning | Không nhãn | Tìm cấu trúc ẩn | Phân nhóm khách hàng, giảm chiều |
| Reinforcement Learning | Phần thưởng/phạt | Học chính sách tối ưu | Game AI, robot, ChatGPT fine-tuning |
Bài viết này tập trung vào Supervised Learning và Unsupervised Learning cơ bản với scikit-learn.
ML khác gì lập trình truyền thống?
Lập trình truyền thống: Dữ liệu + Quy tắc (do người viết) → Kết quả
Machine Learning: Dữ liệu + Kết quả mong muốn → Quy tắc (do máy học)
Ứng dụng ML trong thực tế
- E-commerce: Gợi ý sản phẩm, dự đoán hàng tồn kho.
- Tài chính: Phát hiện gian lận, scoring tín dụng.
- Y tế: Chẩn đoán hình ảnh, dự đoán bệnh.
- Marketing: Phân nhóm khách hàng, dự đoán churn.
- Sản xuất: Bảo trì dự đoán (predictive maintenance).
Tại sao Python và scikit-learn?
- Python: Cú pháp dễ đọc, cộng đồng lớn, tích hợp tốt với data stack.
- scikit-learn: API nhất quán, tài liệu xuất sắc, đủ thuật toán cho 80% bài toán tabular data.
- Jupyter Notebook: Thử nghiệm nhanh, visualize kết quả trực quan.
2. Kiến thức nền tảng cần có
Trước khi học ML, bạn cần nắm vững các kỹ năng sau. Không cần thành thạo tuyệt đối, nhưng càng vững nền thì học ML càng nhanh.
Python cơ bản
- Biến, hàm, class, vòng lặp, điều kiện.
- List comprehension, dictionary.
- Đọc/ghi file CSV.
- Cài package:
pip install scikit-learn pandas numpy.
NumPy — Tính toán số học
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr.mean()) # 3.0
print(arr.std()) # Độ lệch chuẩn
matrix = np.array([[1, 2], [3, 4]])
print(matrix.shape) # (2, 2)
print(matrix.T) # Transpose
Pandas — Xử lý dữ liệu dạng bảng
import pandas as pd
df = pd.read_csv('data.csv')
print(df.head())
print(df.info())
print(df.isnull().sum()) # Đếm missing values
print(df['price'].describe())
Thống kê cơ bản
| Khái niệm | Ý nghĩa | Khi nào dùng |
|---|---|---|
| Mean (trung bình) | Giá trị trung tâm | Dữ liệu phân phối chuẩn |
| Median (trung vị) | Giá trị giữa | Có outlier |
| Standard deviation | Độ phân tán | Đo biến động |
| Correlation | Mối quan hệ tuyến tính | Chọn features |
| Distribution | Hình dạng phân phối | Quyết định preprocessing |
Visualization — Hiểu dữ liệu trước khi model
import matplotlib.pyplot as plt
import seaborn as sns
sns.histplot(df['price'], bins=30)
plt.title('Phân phối giá')
plt.show()
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('Ma trận tương quan')
plt.show()
Quy tắc vàng: Đừng train model khi chưa hiểu dữ liệu. EDA (Exploratory Data Analysis) tiết kiệm hàng giờ debug sau này.
3. Workflow Machine Learning chuẩn
Mọi dự án ML — dù nhỏ hay lớn — đều tuân theo workflow sau:
1. Thu thập dữ liệu (Data Collection)
↓
2. Khám phá dữ liệu (EDA)
↓
3. Làm sạch & tiền xử lý (Preprocessing)
↓
4. Chọn features (Feature Selection/Engineering)
↓
5. Chia train/validation/test
↓
6. Chọn & train model
↓
7. Đánh giá model (Evaluation)
↓
8. Tinh chỉnh hyperparameters (Tuning)
↓
9. Triển khai (Deployment)
Chi tiết từng bước
Bước 1 — Thu thập dữ liệu: API, web scraping, database, file CSV, Kaggle dataset.
Bước 2 — EDA: Thống kê mô tả, visualization, phát hiện outlier, missing values, phân phối.
Bước 3 — Preprocessing: Xử lý missing (fillna, dropna), encode categorical, scale numerical, xử lý outlier.
Bước 4 — Feature Engineering: Tạo features mới có ý nghĩa (ví dụ: price_per_sqm = price / area).
Bước 5 — Chia dữ liệu:
- Train set (60-80%): Huấn luyện model.
- Validation set (10-20%): Tuning hyperparameters.
- Test set (10-20%): Đánh giá cuối cùng — chỉ dùng một lần.
Bước 6-7 — Train & Evaluate: Thử nhiều thuật toán, so sánh metrics.
Bước 8 — Tuning: GridSearchCV, RandomizedSearchCV tìm hyperparameters tốt nhất.
Bước 9 — Deploy: API (FastAPI), web app (Streamlit), batch prediction.
4. Tutorial scikit-learn đầy đủ: Dự đoán giá nhà
Chúng ta sẽ xây dựng pipeline hoàn chỉnh từ load dữ liệu đến đánh giá model, sử dụng dataset California Housing (có sẵn trong scikit-learn).
Bước 1: Cài đặt và import
# pip install scikit-learn pandas numpy matplotlib seaborn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from sklearn.pipeline import Pipeline
import warnings
warnings.filterwarnings('ignore')
# Thiết lập style
sns.set_style('whitegrid')
plt.rcParams['figure.figsize'] = (10, 6)
Bước 2: Load và khám phá dữ liệu
# Load dataset California Housing
housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing.target # Giá nhà (đơn vị: $100,000)
print(f"Kích thước: {df.shape}")
print(f"\nThông tin:\n{df.info()}")
print(f"\nThống kê mô tả:\n{df.describe()}")
# Kiểm tra missing values
print(f"\nMissing values:\n{df.isnull().sum()}")
# Phân phối target
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.histplot(df['MedHouseVal'], bins=50, kde=True, ax=axes[0])
axes[0].set_title('Phân phối giá nhà (MedHouseVal)')
axes[0].set_xlabel('Giá ($100,000)')
sns.boxplot(y=df['MedHouseVal'], ax=axes[1])
axes[1].set_title('Boxplot giá nhà')
plt.tight_layout()
plt.show()
Bước 3: Phân tích tương quan
# Ma trận tương quan
corr = df.corr()
sns.heatmap(corr, annot=True, cmap='coolwarm', center=0, fmt='.2f')
plt.title('Ma trận tương quan các features')
plt.show()
# Scatter plot features quan trọng nhất
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
sns.scatterplot(data=df, x='MedInc', y='MedHouseVal', alpha=0.3, ax=axes[0])
axes[0].set_title('Thu nhập vs Giá nhà')
sns.scatterplot(data=df, x='AveRooms', y='MedHouseVal', alpha=0.3, ax=axes[1])
axes[1].set_title('Số phòng trung bình vs Giá nhà')
sns.scatterplot(data=df, x='Latitude', y='MedHouseVal', alpha=0.3, ax=axes[2])
axes[2].set_title('Vĩ độ vs Giá nhà')
plt.tight_layout()
plt.show()
Bước 4: Chuẩn bị dữ liệu train/test
# Tách features và target
X = df.drop('MedHouseVal', axis=1)
y = df['MedHouseVal']
# Chia train/test (80/20)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"Train: {X_train.shape}, Test: {X_test.shape}")
# Chuẩn hóa dữ liệu
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Bước 5: Train nhiều model và so sánh
models = {
'Linear Regression': LinearRegression(),
'Ridge': Ridge(alpha=1.0),
'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingRegressor(n_estimators=100, random_state=42),
}
results = []
for name, model in models.items():
model.fit(X_train_scaled, y_train)
y_pred = model.predict(X_test_scaled)
mae = mean_absolute_error(y_test, y_pred)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
results.append({
'Model': name,
'MAE': round(mae, 4),
'RMSE': round(rmse, 4),
'R²': round(r2, 4),
})
print(f"\n{name}:")
print(f" MAE: {mae:.4f}")
print(f" RMSE: {rmse:.4f}")
print(f" R²: {r2:.4f}")
results_df = pd.DataFrame(results)
print(f"\n{'='*50}")
print("Bảng so sánh models:")
print(results_df.to_string(index=False))
Bước 6: Cross-validation
best_model = RandomForestRegressor(n_estimators=100, random_state=42)
cv_scores = cross_val_score(
best_model, X_train_scaled, y_train,
cv=5, scoring='neg_mean_absolute_error'
)
print(f"Cross-validation MAE: {-cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
Bước 7: Hyperparameter tuning
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10],
}
grid_search = GridSearchCV(
RandomForestRegressor(random_state=42),
param_grid,
cv=3,
scoring='neg_mean_absolute_error',
n_jobs=-1,
verbose=1,
)
grid_search.fit(X_train_scaled, y_train)
print(f"Best params: {grid_search.best_params_}")
print(f"Best CV MAE: {-grid_search.best_score_:.4f}")
# Đánh giá model tốt nhất trên test set
best_rf = grid_search.best_estimator_
y_pred_best = best_rf.predict(X_test_scaled)
print(f"\nTest MAE: {mean_absolute_error(y_test, y_pred_best):.4f}")
print(f"Test RMSE: {np.sqrt(mean_squared_error(y_test, y_pred_best)):.4f}")
print(f"Test R²: {r2_score(y_test, y_pred_best):.4f}")
Bước 8: Feature importance và visualization kết quả
# Feature importance
importance = pd.Series(
best_rf.feature_importances_,
index=X.columns
).sort_values()
importance.plot(kind='barh', title='Feature Importance — Random Forest')
plt.xlabel('Importance')
plt.show()
# So sánh predicted vs actual
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].scatter(y_test, y_pred_best, alpha=0.3)
axes[0].plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
axes[0].set_xlabel('Giá thực tế')
axes[0].set_ylabel('Giá dự đoán')
axes[0].set_title('Predicted vs Actual')
residuals = y_test - y_pred_best
sns.histplot(residuals, bins=50, kde=True, ax=axes[1])
axes[1].set_title('Phân phối Residuals')
axes[1].set_xlabel('Residual (thực tế - dự đoán)')
plt.tight_layout()
plt.show()
Bước 9: Pipeline hoàn chỉnh (best practice)
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
# Pipeline kết hợp preprocessing + model
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', RandomForestRegressor(
n_estimators=200,
max_depth=20,
min_samples_split=5,
random_state=42,
)),
])
pipeline.fit(X_train, y_train)
y_pred_pipeline = pipeline.predict(X_test)
print(f"Pipeline Test MAE: {mean_absolute_error(y_test, y_pred_pipeline):.4f}")
print(f"Pipeline Test R²: {r2_score(y_test, y_pred_pipeline):.4f}")
# Lưu model
import joblib
joblib.dump(pipeline, 'housing_price_model.pkl')
print("Model đã lưu: housing_price_model.pkl")
5. Bảng thuật toán ML cơ bản
Supervised Learning — Regression (dự đoán số)
| Thuật toán | scikit-learn class | Ưu điểm | Nhược điểm | Khi nào dùng |
|---|---|---|---|---|
| Linear Regression | LinearRegression | Đơn giản, giải thích được | Giả định tuyến tính | Baseline, quan hệ tuyến tính |
| Ridge / Lasso | Ridge, Lasso | Tránh overfitting | Cần scale features | Nhiều features, multicollinearity |
| Decision Tree | DecisionTreeRegressor | Dễ hiểu, không cần scale | Overfit dễ dàng | Cần interpretability |
| Random Forest | RandomForestRegressor | Chính xác cao, robust | Chậm, khó interpret | Tabular data phổ biến |
| Gradient Boosting | GradientBoostingRegressor | Rất chính xác | Chậm train, nhiều hyperparams | Competition, production |
| SVR | SVR | Hiệu quả không gian cao chiều | Chậm với data lớn | Feature phức tạp |
Supervised Learning — Classification (phân loại)
| Thuật toán | scikit-learn class | Ưu điểm | Nhược điểm | Khi nào dùng |
|---|---|---|---|---|
| Logistic Regression | LogisticRegression | Nhanh, probability output | Giả định tuyến tính | Binary/multiclass baseline |
| KNN | KNeighborsClassifier | Đơn giản, không train | Chậm predict, cần scale | Dataset nhỏ |
| Decision Tree | DecisionTreeClassifier | Dễ visualize | Overfit | Cần rules rõ ràng |
| Random Forest | RandomForestClassifier | Chính xác, ít tuning | Black box hơn DT | Phổ biến nhất cho tabular |
| SVM | SVC | Hiệu quả không gian cao chiều | Chậm data lớn | Text, image features |
| Naive Bayes | MultinomialNB | Rất nhanh | Giả định độc lập | Text classification |
Unsupervised Learning
| Thuật toán | scikit-learn class | Ứng dụng |
|---|---|---|
| K-Means | KMeans | Phân nhóm khách hàng, segmentation |
| DBSCAN | DBSCAN | Clustering hình dạng bất kỳ, phát hiện outlier |
| PCA | PCA | Giảm chiều, visualization, tăng tốc train |
| t-SNE | (không có trong sklearn) | Visualization high-dim data |
| Agglomerative | AgglomerativeClustering | Phân cấp cluster, dendrogram |
Cách chọn thuật toán nhanh
Dữ liệu dạng bảng (tabular)?
├── Regression → Linear Regression (baseline) → Random Forest → Gradient Boosting
└── Classification → Logistic Regression (baseline) → Random Forest → XGBoost
Dữ liệu text?
└── Naive Bayes → TF-IDF + Logistic Regression
Dữ liệu ảnh?
└── CNN (TensorFlow/PyTorch) — ngoài phạm vi scikit-learn
Cần phân nhóm không biết số nhóm?
└── K-Means (thử nhiều k) hoặc DBSCAN
6. Metrics đánh giá model
Chọn đúng metric quan trọng hơn chọn đúng thuật toán. Metric sai → kết luận sai.
Regression metrics
| Metric | Công thức ý niệm | Ý nghĩa | Khi nào dùng |
|---|---|---|---|
| MAE | Trung bình |thực tế - dự đoán| | Sai số tuyệt đối trung bình | Muốn interpret dễ (đơn vị gốc) |
| RMSE | √(trung bình (thực tế - dự đoán)²) | Phạt lỗi lớn nặng hơn | Outlier quan trọng |
| R² | 1 - SS_res/SS_tot | % variance được giải thích | So sánh models (0-1) |
| MAPE | Trung bình |sai số/thực tế| × 100% | Sai số phần trăm | Business reporting |
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
mae = mean_absolute_error(y_test, y_pred)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"MAE: {mae:.4f}") # Ví dụ: 0.45 → sai trung bình $45,000
print(f"RMSE: {rmse:.4f}")
print(f"R²: {r2:.4f}") # Ví dụ: 0.82 → giải thích 82% variance
Classification metrics
| Metric | Ý nghĩa | Khi nào dùng |
|---|---|---|
| Accuracy | Tỷ lệ dự đoán đúng | Dữ liệu cân bằng |
| Precision | Trong số dự đoán positive, bao nhiêu đúng | False positive tốn kém (spam filter) |
| Recall | Trong số thực tế positive, bắt được bao nhiêu | False negative nguy hiểm (bệnh ung thư) |
| F1 Score | Harmonic mean Precision & Recall | Dữ liệu mất cân bằng |
| ROC-AUC | Khả năng phân biệt classes | So sánh models tổng thể |
from sklearn.metrics import (
classification_report,
confusion_matrix,
roc_auc_score,
roc_curve,
)
# Giả sử y_test_class và y_pred_class đã có
print(classification_report(y_test_class, y_pred_class))
cm = confusion_matrix(y_test_class, y_pred_class)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('Confusion Matrix')
plt.ylabel('Thực tế')
plt.xlabel('Dự đoán')
plt.show()
# ROC Curve (binary classification)
y_prob = clf.predict_proba(X_test_scaled)[:, 1]
fpr, tpr, _ = roc_curve(y_test_class, y_prob)
auc = roc_auc_score(y_test_class, y_prob)
plt.plot(fpr, tpr, label=f'ROC (AUC = {auc:.3f})')
plt.plot([0, 1], [0, 1], 'k--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend()
plt.show()
Đọc Confusion Matrix
Dự đoán
Neg Pos
Thực tế Neg TN FP ← FP: báo nhầm có bệnh
Pos FN TP ← FN: bỏ sót bệnh nhân
- TN (True Negative): Dự đoán đúng negative.
- TP (True Positive): Dự đoán đúng positive.
- FP (False Positive): Báo nhầm positive — Type I error.
- FN (False Negative): Bỏ sót positive — Type II error.
7. Tránh Overfitting và Underfitting
Overfitting là gì?
Model học quá khớp training data — kể cả noise — nên performance trên test data kém.
Underfitting: Train error cao, Test error cao → Model quá đơn giản
Good fit: Train error thấp, Test error thấp → Lý tưởng
Overfitting: Train error rất thấp, Test error cao → Học thuộc training data
Dấu hiệu overfitting
- Train accuracy 99%, test accuracy 70%.
- Cross-validation score dao động lớn giữa các fold.
- Decision tree quá sâu với 100% train accuracy.
Cách phòng tránh overfitting
1. Chia dữ liệu đúng cách
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# KHÔNG dùng test set để tuning — chỉ đánh giá cuối cùng
2. Cross-validation
from sklearn.model_selection import cross_val_score
scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')
print(f"CV Accuracy: {scores.mean():.3f} (+/- {scores.std():.3f})")
3. Regularization
# L2 Regularization (Ridge)
ridge = Ridge(alpha=10.0) # alpha càng lớn, penalty càng mạnh
# L1 Regularization (Lasso) — có thể loại bỏ features
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=0.1)
4. Giới hạn độ phức tạp model
# Decision Tree — giới hạn độ sâu
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(max_depth=5, min_samples_split=10)
# Random Forest — giới hạn trees và depth
rf = RandomForestClassifier(n_estimators=100, max_depth=10, min_samples_leaf=5)
5. Feature selection
from sklearn.feature_selection import SelectKBest, f_classif
selector = SelectKBest(f_classif, k=10)
X_selected = selector.fit_transform(X_train, y_train)
6. Thu thập thêm dữ liệu
Nhiều data hơn → model khó overfit hơn. Đây thường là giải pháp hiệu quả nhất nhưng tốn kém nhất.
7. Early stopping (Gradient Boosting)
gb = GradientBoostingRegressor(
n_estimators=500,
validation_fraction=0.1,
n_iter_no_change=10, # Dừng nếu không cải thiện sau 10 iterations
random_state=42,
)
Learning curve — Chẩn đoán overfitting
from sklearn.model_selection import learning_curve
train_sizes, train_scores, val_scores = learning_curve(
RandomForestRegressor(n_estimators=100),
X, y, cv=5, scoring='neg_mean_absolute_error',
train_sizes=np.linspace(0.1, 1.0, 10),
)
train_mean = -train_scores.mean(axis=1)
val_mean = -val_scores.mean(axis=1)
plt.plot(train_sizes, train_mean, label='Train')
plt.plot(train_sizes, val_mean, label='Validation')
plt.xlabel('Training Size')
plt.ylabel('MAE')
plt.title('Learning Curve')
plt.legend()
plt.show()
8. Năm dự án thực hành gợi ý
Dự án 1: Phân loại hoa Iris (Beginner)
Mục tiêu: Học pipeline ML cơ bản — load data, train, evaluate.
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
Kỹ năng học được: Classification, KNN, train/test split, accuracy.
Dự án 2: Dự đoán giá nhà California Housing (Intermediate)
Mục tiêu: Regression thực tế, so sánh nhiều models, feature importance.
Dataset: sklearn.datasets.fetch_california_housing hoặc Kaggle.
Kỹ năng: Regression metrics (MAE, R²), Random Forest, visualization residuals, Pipeline.
Deliverable: Jupyter Notebook + README giải thích insight (ví dụ: MedInc là feature quan trọng nhất).
Dự án 3: Phân loại email Spam (Intermediate)
Mục tiêu: Text classification với dữ liệu thực tế.
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# Giả sử df có cột 'text' và 'label' (ham/spam)
X_train, X_test, y_train, y_test = train_test_split(
df['text'], df['label'], test_size=0.2, random_state=42
)
pipeline = Pipeline([
('tfidf', TfidfVectorizer(max_features=5000, stop_words='english')),
('clf', MultinomialNB()),
])
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred))
Dataset: SMS Spam Collection trên Kaggle.
Kỹ năng: Text preprocessing, TF-IDF, Naive Bayes, Precision/Recall.
Dự án 4: Phân nhóm khách hàng — Customer Segmentation (Intermediate)
Mục tiêu: Unsupervised learning, K-Means clustering, business insight.
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
# Giả sử df có: annual_spending, purchase_frequency, avg_order_value
features = ['annual_spending', 'purchase_frequency', 'avg_order_value']
X = df[features]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Elbow method tìm k tối ưu
inertias = []
for k in range(2, 11):
km = KMeans(n_clusters=k, random_state=42)
km.fit(X_scaled)
inertias.append(km.inertia_)
plt.plot(range(2, 11), inertias, 'bo-')
plt.xlabel('Số clusters (k)')
plt.ylabel('Inertia')
plt.title('Elbow Method')
plt.show()
# Train với k=4
kmeans = KMeans(n_clusters=4, random_state=42)
df['cluster'] = kmeans.fit_predict(X_scaled)
# Phân tích từng cluster
print(df.groupby('cluster')[features].mean())
Kỹ năng: K-Means, Elbow method, StandardScaler, business interpretation.
Dự án 5: Dự đoán Customer Churn (Advanced)
Mục tiêu: Classification với dữ liệu mất cân bằng — bài toán thực tế phổ biến.
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score
from imblearn.over_sampling import SMOTE # pip install imbalanced-learn
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
# Xử lý imbalanced data
smote = SMOTE(random_state=42)
X_train_balanced, y_train_balanced = smote.fit_resample(X_train, y_train)
clf = RandomForestClassifier(n_estimators=200, class_weight='balanced', random_state=42)
clf.fit(X_train_balanced, y_train_balanced)
y_pred = clf.predict(X_test)
y_prob = clf.predict_proba(X_test)[:, 1]
print(classification_report(y_test, y_pred))
print(f"ROC-AUC: {roc_auc_score(y_test, y_prob):.3f}")
Dataset: Telco Customer Churn trên Kaggle.
Kỹ năng: Imbalanced data, SMOTE, class_weight, ROC-AUC, F1 score, feature engineering (tenure, monthly_charges).
9. Tài nguyên học tập
Khóa học miễn phí (theo thứ tự khuyến nghị)
- Kaggle Learn — Intro to Machine Learning — Thực hành trực tiếp, ngắn gọn, miễn phí.
- Kaggle Learn — Intermediate ML — Cross-validation, pipelines, XGBoost.
- Google ML Crash Course — Khái niệm nền với video và bài tập.
- Machine Learning — Andrew Ng (Coursera) — Khóa kinh điển, giải thích toán học trực quan.
- fast.ai Practical Deep Learning — Nếu muốn học Deep Learning sau ML cơ bản.
Sách hay nhất cho Python ML
| Sách | Tác giả | Phù hợp |
|---|---|---|
| Hands-On Machine Learning | Aurélien Géron | Toàn diện nhất, nhiều code |
| Python Machine Learning | Sebastian Raschka | Giải thích thuật toán chi tiết |
| Introduction to Statistical Learning | James, Witten, et al. | Nền tảng thống kê vững |
Thực hành thực chiến
- Kaggle Competitions — Titanic, House Prices là điểm bắt đầu tốt.
- Scikit-learn Documentation — Tutorial chính thức, chất lượng cao.
- UCI Machine Learning Repository — Dataset đa dạng cho thực hành.
- Tự tạo project cá nhân — Giải quyết bài toán bạn quan tâm (dự đoán giá điện thoại cũ, phân loại tin tức...).
Lộ trình phát triển sau ML cơ bản
- Feature Engineering nâng cao — Polynomial features, target encoding, domain knowledge.
- XGBoost / LightGBM / CatBoost — Thuật toán mạnh nhất cho tabular data.
- Deep Learning — TensorFlow/Keras hoặc PyTorch cho image, text, audio.
- MLOps — Deploy model với FastAPI, Streamlit, Docker.
- Kaggle Competitions — Rèn kỹ năng end-to-end, học từ solution của người khác.
10. FAQ — Câu hỏi thường gặp
Tôi cần học toán nhiều không?
Cơ bản là đủ để bắt đầu: đại số tuyến tính (vector, ma trận), xác suất cơ bản, thống kê mô tả. Bạn có thể học ML song song với toán — mỗi lần gặp khái niệm mới (gradient descent, entropy) thì đào sâu thêm.
scikit-learn có đủ cho production không?
Có cho nhiều bài toán tabular data (phân loại, regression, clustering). scikit-learn models nhẹ, nhanh, dễ deploy với joblib. Với Deep Learning hoặc data cực lớn, cần TensorFlow/PyTorch và infrastructure khác.
Train/test split bao nhiêu phần trăm?
Thông dụng: 80/20 hoặc 70/30. Data ít (< 1000 mẫu): dùng cross-validation thay vì split cố định. Data nhiều (> 100,000): 90/10 vẫn đủ test samples.
Khi nào dùng Deep Learning thay vì scikit-learn?
| Tình huống | Chọn |
|---|---|
| Tabular data (bảng số) | scikit-learn / XGBoost |
| Hình ảnh | CNN (TensorFlow/PyTorch) |
| Text phức tạp | Transformer (BERT, GPT) |
| Âm thanh | Deep Learning |
| Dataset < 10,000 mẫu | scikit-learn thường đủ |
Làm sao biết model "đủ tốt"?
Không có ngưỡng magic. So sánh với:
- Baseline đơn giản (predict mean, Logistic Regression).
- Business requirement (ví dụ: "cần 90% recall cho phát hiện fraud").
- Benchmark trên Kaggle hoặc papers.
Overfitting nhưng đã thử mọi cách?
- Thu thập thêm data.
- Giảm số features (feature selection).
- Thử model đơn giản hơn.
- Kiểm tra data leakage (feature chứa thông tin tương lai).
- Ensemble nhiều models.
Jupyter Notebook hay Python script?
- Notebook: EDA, thử nghiệm, demo, học tập.
- Script (.py): Production, pipeline tự động, CI/CD.
- Best practice: Thử trong Notebook → refactor thành module
.pykhi ổn định.
Cần GPU để học ML cơ bản không?
Không. scikit-learn chạy trên CPU. GPU cần khi học Deep Learning với dataset lớn. Google Colab cung cấp GPU miễn phí nếu cần.
Kết luận
Machine Learning với Python không phải ma thuật — đó là quy trình có hệ thống: hiểu dữ liệu, preprocess, chọn model, đánh giá đúng metric, tránh overfitting, và lặp lại. scikit-learn cung cấp mọi công cụ bạn cần để bắt đầu hành trình này.
Hành động ngay hôm nay:
pip install scikit-learn pandas numpy matplotlib seaborn jupyter- Làm dự án Iris (30 phút).
- Hoàn thành tutorial California Housing trong bài viết này.
- Đăng ký Kaggle, làm khóa Intro to ML.
- Push project đầu tiên lên GitHub với README giải thích approach.
Mỗi model bạn train — dù accuracy thấp — là một bước tiến. Hãy bắt đầu với data, không phải với thuật toán phức tạp nhất.