Danh sách bài viết

Bài 5: Dataset đầu tiên — load_iris và làm quen với feature / label

Iris dataset của Fisher 1936 — 150 sample, 3 loài hoa, 4 feature. Cách load bằng sklearn (3 style: dict, return_X_y, as_frame), cấu trúc data object, phân biệt feature / label / sample / class, shape convention (n_samples, n_features), EDA bằng Pandas, các dataset built-in khác và giới hạn của iris.

24/05/2026
12 phút đọc
0 lượt xem
1

Mục tiêu bài học

Sau bài học, bạn sẽ:

  • Hiểu vai trò của dataset trong workflow ML, vì sao không thể "học" mà không có data.
  • Biết lịch sử và cấu trúc của iris dataset — 150 sample, 4 feature, 3 class.
  • Load iris bằng 3 style: dict-like, return_X_y, as_frame.
  • Đọc được mọi thuộc tính trong data object: data, target, feature_names, target_names, DESCR.
  • Phân biệt 4 khái niệm: feature (X), label (y), sample, class.
  • Áp shape convention chuẩn: X là 2D (n_samples, n_features), y là 1D (n_samples,).
  • EDA cơ bản trên iris bằng Pandas: head, describe, value_counts.
  • Biết các dataset built-in khác (load_digits, load_wine, load_breast_cancer, load_diabetes) và generators (make_classification, make_blobs).
  • Hiểu giới hạn của iris và lý do không dùng nó làm benchmark thực tế.
2

Vì sao cần dataset để học ML

Bài 1 đã định nghĩa Machine Learning là tiếp cận "lập trình bằng dữ liệu" — thay vì viết rule, ta cung cấp ví dụ và để thuật toán tự rút quy luật. Hệ quả trực tiếp: không có dữ liệu thì không có ML. Mọi thuật toán, từ Linear Regression tới Transformer, đều cần một bộ dữ liệu để học.

Khi nhập môn, ta cần một dataset có 4 đặc điểm:

  • Nhỏ — chạy được trên laptop trong vài giây.
  • Sạch — không có missing value, không cần xử lý nặng.
  • Có nhãn rõ ràng — để minh hoạ supervised learning.
  • Dễ visualize — số chiều thấp, có thể vẽ scatter để thấy được pattern.

Iris đáp ứng cả 4 yêu cầu trên và đã trở thành dataset chuẩn cho mọi tutorial ML kể từ năm 1936. Bài này dùng nó để giới thiệu các khái niệm mà mọi bài sau (từ Linear Regression Bài 15 tới SVM Bài 31) đều sẽ dùng lại: feature, label, sample, shape convention.

3

Iris — "Hello World" của ML

Iris dataset xuất hiện lần đầu trong bài báo của Ronald A. Fisher (1936): "The use of multiple measurements in taxonomic problems", Annals of Eugenics, 7(2). Dữ liệu thực tế do nhà thực vật học Edgar Anderson đo, Fisher dùng để minh hoạ phương pháp Linear Discriminant Analysis. 90 năm sau, nó vẫn là dataset đầu tiên mà phần lớn người học ML chạm vào.

Cấu trúc

  • 150 sample (150 bông hoa) — 50 mẫu cho mỗi loài.
  • 3 class (3 loài hoa diên vĩ): setosa, versicolor, virginica.
  • 4 feature đo bằng cm: sepal length (chiều dài đài hoa), sepal width (chiều rộng đài hoa), petal length (chiều dài cánh hoa), petal width (chiều rộng cánh hoa).

Một sample điển hình trong dataset:

sepal_length  sepal_width  petal_length  petal_width   target
     5.1          3.5           1.4           0.2         0  (setosa)
     7.0          3.2           4.7           1.4         1  (versicolor)
     6.3          3.3           6.0           2.5         2  (virginica)

Lý do iris được xem là "Hello World" của ML:

  • Kích thước nhỏ, load trong 1 dòng code, train trong dưới 1 giây.
  • Số chiều thấp (4), dễ visualize qua scatter plot từng cặp feature.
  • Class setosa tách biệt tuyến tính khỏi 2 class còn lại — model đơn giản nhất cũng nhìn ra. versicolorvirginica chồng lấn nhẹ — vừa đủ để tạo "thử thách" cho model.
  • Perfectly balanced (50/50/50) — không cần xử lý imbalance.
4

Load iris bằng sklearn — 3 style

Iris có sẵn trong sklearn, không cần download. Hàm load nằm trong module sklearn.datasets. Có 3 style gọi, dùng tuỳ tình huống:

Style 1 — dict-like (mặc định)

from sklearn.datasets import load_iris

data = load_iris()
# data là một Bunch object — giống dict nhưng truy cập được bằng .attr
print(type(data))          # <class 'sklearn.utils._bunch.Bunch'>
print(data.data.shape)     # (150, 4)
print(data.target.shape)   # (150,)

Style này trả về tất cả: data, target, tên feature, tên class, mô tả. Dùng khi cần truy cập metadata (ví dụ in tên feature để báo cáo).

Style 2 — return_X_y

from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
print(X.shape, y.shape)    # (150, 4) (150,)

Trả thẳng tuple (X, y). Dùng khi chỉ cần ma trận feature và vector label — không quan tâm tên. Đây là style ngắn nhất, hay gặp trong tutorial.

Style 3 — as_frame (Pandas)

from sklearn.datasets import load_iris

data = load_iris(as_frame=True)
df = data.frame             # DataFrame 150 dòng x 5 cột (4 feature + target)
X = data.data               # DataFrame 150 x 4
y = data.target             # Series 150 phần tử
print(df.head())

Khi as_frame=True, sklearn trả về Pandas DataFrame thay vì NumPy array. Dùng khi muốn EDA bằng Pandas (xem mục 8). Yêu cầu Pandas đã cài.

Cả 3 style đều dùng cùng một dữ liệu — chỉ khác kiểu container. Chọn style nào phụ thuộc bạn cần metadata, cần tốc độ NumPy, hay cần tiện ích DataFrame.

5

Cấu trúc data object

Với data = load_iris(), các thuộc tính chính:

  • data.data — feature matrix, NumPy array shape (150, 4). Mỗi dòng là 1 bông hoa, mỗi cột là 1 feature.
  • data.target — label array, shape (150,). Giá trị là số nguyên 0 / 1 / 2 tương ứng 3 loài.
  • data.feature_names — list 4 chuỗi: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'].
  • data.target_names — list 3 chuỗi: ['setosa', 'versicolor', 'virginica']. Index trùng với giá trị trong target.
  • data.DESCR — chuỗi mô tả đầy đủ dataset: nguồn, số sample, statistics, citation.
  • data.filename — đường dẫn file CSV gốc trong package sklearn.

Code in toàn bộ:

from sklearn.datasets import load_iris

data = load_iris()
print("Shape X     :", data.data.shape)         # (150, 4)
print("Shape y     :", data.target.shape)       # (150,)
print("Features    :", data.feature_names)
print("Classes     :", data.target_names)
print("5 dòng đầu  :\n", data.data[:5])
print("5 label đầu :", data.target[:5])         # [0 0 0 0 0]
print("Mô tả (200 ký tự đầu):\n", data.DESCR[:200])

Output (rút gọn):

Shape X     : (150, 4)
Shape y     : (150,)
Features    : ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
Classes     : ['setosa' 'versicolor' 'virginica']
5 dòng đầu  :
 [[5.1 3.5 1.4 0.2]
  [4.9 3.  1.4 0.2]
  [4.7 3.2 1.3 0.2]
  [4.6 3.1 1.5 0.2]
  [5.  3.6 1.4 0.2]]
5 label đầu : [0 0 0 0 0]

Lưu ý: data.target là số nguyên, không phải chuỗi. Để hiển thị tên class, ánh xạ qua target_names: data.target_names[data.target[0]]'setosa'.

6

Thuật ngữ: feature, label, sample, class

Bốn thuật ngữ cốt lõi mà mọi bài ML sẽ dùng đi dùng lại:

Feature (X)

Biến đầu vào — thông tin model dùng để dự đoán. Iris có 4 feature: 4 phép đo trên hoa. Tên gọi khác trong các tài liệu:

  • Attribute — quen trong tài liệu data mining cũ.
  • Predictor — quen trong thống kê.
  • Independent variable — biến độc lập, thuật ngữ thống kê cổ điển.
  • Input variable / covariate / explanatory variable — ít gặp hơn.

Ký hiệu chuẩn: X (in hoa, vì là ma trận).

Label (y)

Biến đầu ra — thứ model phải dự đoán. Iris: loài hoa (0 / 1 / 2). Tên gọi khác:

  • Target — phổ biến nhất trong sklearn.
  • Response — quen trong thống kê.
  • Dependent variable — biến phụ thuộc, đối lập với independent.
  • Ground truth — nhấn mạnh đây là giá trị thật, dùng để chấm điểm model.
  • Class — chỉ dùng trong classification.

Ký hiệu chuẩn: y (thường, vì là vector).

Sample / instance / observation

Một quan sát — một dòng trong dataset. Iris có 150 sample. "Sample" trong ML khác với "sample" trong thống kê (mẫu = tập hợp các quan sát). Khi cần phân biệt, dùng từ instance hoặc data point.

Class

Giá trị rời rạc của label trong bài classification. Iris có 3 class: setosa, versicolor, virginica. Số class viết là n_classes. Bài regression không có "class" — label là số liên tục.

Bảng tổng kết theo từng tên gọi và tài liệu hay gặp:

Khái niệm   | sklearn      | thống kê         | ML tutorials
------------|--------------|------------------|-------------
input       | X, features  | predictors,      | features,
            |              | independent vars | attributes
output      | y, target    | response,        | label,
            |              | dependent var    | ground truth
1 quan sát  | sample       | observation      | instance,
            |              |                  | data point

Bài này (và các bài sau trong series) sẽ dùng cặp feature / label và ký hiệu X / y theo chuẩn sklearn.

7

Shape convention trong ML

Quy ước về kích thước (shape) của Xy trong sklearn là bắt buộc. Sai shape là lỗi đầu tiên mọi người mới học gặp phải.

  • X: 2D array, shape (n_samples, n_features). Mỗi dòng là 1 sample, mỗi cột là 1 feature.
  • y: 1D array, shape (n_samples,). Một label cho mỗi sample.
  • n_classes: số class khác nhau trong y. Với iris = 3.

Áp dụng cho iris:

from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)
print("X shape :", X.shape)               # (150, 4)
print("y shape :", y.shape)               # (150,)
print("n_samples  =", X.shape[0])         # 150
print("n_features =", X.shape[1])         # 4
print("n_classes  =", len(np.unique(y)))  # 3

Một số quy ước phụ:

  • Mọi method trong sklearn (fit, predict, transform) đều nhận X 2D. Nếu bạn chỉ có 1 sample (1 dòng), phải reshape thành (1, n_features): X_one = X[0].reshape(1, -1).
  • Với regression, y vẫn là 1D shape (n_samples,). Một số task multi-output có thể dùng 2D, nhưng đó là ngoại lệ.
  • Quy ước này đối lập với một số framework DL hình ảnh (PyTorch/TensorFlow) cho CNN dùng (N, C, H, W); nhưng sklearn luôn 2D (n_samples, n_features).

Lý do của quy ước "1 dòng = 1 sample, 1 cột = 1 feature": phù hợp với cách dữ liệu được lưu trong CSV / SQL — mỗi record là 1 dòng, mỗi field là 1 cột. Quen tay với convention này từ sớm sẽ tránh được hàng loạt lỗi ValueError: Expected 2D array về sau.

8

EDA iris bằng Pandas

EDA — Exploratory Data Analysis — là bước "nhìn" dữ liệu trước khi train. Với iris, EDA chỉ vài dòng là xong. Pandas (đã dùng ở Series 1) là công cụ tự nhiên cho việc này.

Cách 1 — dùng as_frame=True:

from sklearn.datasets import load_iris

data = load_iris(as_frame=True)
df = data.frame                # DataFrame 150 x 5 (4 feature + target)
print(df.shape)                # (150, 5)
print(df.columns.tolist())
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)',
#  'petal width (cm)', 'target']

Cách 2 — build DataFrame thủ công từ NumPy:

import pandas as pd
from sklearn.datasets import load_iris

data = load_iris()
df = pd.DataFrame(data.data, columns=data.feature_names)
df["target"] = data.target
df["species"] = df["target"].map(dict(enumerate(data.target_names)))
print(df.head())

3 lệnh EDA cơ bản

1. df.head() — xem 5 dòng đầu:

   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)  target
0                5.1               3.5                1.4               0.2       0
1                4.9               3.0                1.4               0.2       0
2                4.7               3.2                1.3               0.2       0
3                4.6               3.1                1.5               0.2       0
4                5.0               3.6                1.4               0.2       0

2. df.describe() — thống kê 4 feature:

       sepal length  sepal width  petal length  petal width
count        150.00       150.00        150.00       150.00
mean           5.84         3.06          3.76         1.20
std            0.83         0.44          1.77         0.76
min            4.30         2.00          1.00         0.10
25%            5.10         2.80          1.60         0.30
50%            5.80         3.00          4.35         1.30
75%            6.40         3.30          5.10         1.80
max            7.90         4.40          6.90         2.50

Quan sát: petal lengthpetal width có độ lệch chuẩn (std) lớn hơn so với mean — biến thiên rộng, có thể chứa nhiều thông tin phân biệt class.

3. Class balance — value_counts:

print(df["target"].value_counts().sort_index())
# 0    50
# 1    50
# 2    50

Cân bằng tuyệt đối 50/50/50 — không cần xử lý imbalance (sẽ học ở Bài 42).

Correlation giữa các feature:

print(df.drop(columns=["target"]).corr().round(2))
# petal length và petal width tương quan ~0.96 — gần như tuyến tính
# sepal length và petal length tương quan ~0.87

Tương quan cao giữa petal lengthpetal width báo hiệu hai feature này gần như mang cùng thông tin — gợi ý PCA (Bài 36) có thể giảm chiều mà giữ được hầu hết variance.

9

Visualization sự khác biệt giữa class

Visualize trước khi train là thói quen tốt — giúp đoán trước model có khả thi không.

Scatter plot 2 feature

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

data = load_iris()
X, y = data.data, data.target

# Vẽ petal length (col 2) vs petal width (col 3)
for cls in range(3):
    mask = y == cls
    plt.scatter(X[mask, 2], X[mask, 3], label=data.target_names[cls])
plt.xlabel("petal length (cm)")
plt.ylabel("petal width (cm)")
plt.legend()
plt.show()

Ấn tượng đầu: setosa tách hẳn ở góc dưới-trái (petal nhỏ). versicolorvirginica nằm sát nhau nhưng vẫn có ranh giới mờ. Đây là lý do iris được gọi là "gần linearly separable".

Pair plot (Seaborn)

Pair plot vẽ scatter cho mọi cặp feature trong một grid — 4 feature thành ma trận 4x4. Mỗi ô off-diagonal là scatter của 2 feature, mỗi ô diagonal là histogram của 1 feature.

import seaborn as sns
sns.pairplot(df, hue="species")

Pair plot là cách "nhìn" toàn bộ 4 feature trong 1 hình. Với dataset nhỏ (<10 feature), đây là EDA mạnh nhất mà tốn ít công.

10

Các dataset built-in khác

Sklearn đi kèm khoảng chục dataset nhỏ (gọi là "toy datasets"), dùng để demo. Tất cả nằm trong sklearn.datasets:

  • load_iris() — 150 sample, 4 feature, 3 class. Classification.
  • load_digits() — 1797 ảnh chữ số viết tay 8x8 pixel (flatten thành 64 feature). 10 class (0–9). Classification.
  • load_wine() — 178 sample rượu, 13 feature hoá học, 3 class. Classification.
  • load_breast_cancer() — 569 sample, 30 feature, 2 class (u lành / u ác). Binary classification.
  • load_diabetes() — 442 sample, 10 feature, label là chỉ số tiến triển bệnh sau 1 năm. Regression.
  • load_linnerud() — 20 sample, multi-output regression (3 chỉ số sinh lý theo 3 bài tập).

Mọi hàm load_* đều có cùng signature: trả về Bunch object với .data, .target, .feature_names, .target_names (nếu là classification), .DESCR. Hỗ trợ return_X_y=Trueas_frame=True.

fetch_openml — dataset thực tế hơn

OpenML là một repository dataset cộng đồng. Sklearn có hàm fetch_openml để tải bất kỳ dataset nào từ đó:

from sklearn.datasets import fetch_openml

# MNIST: 70.000 ảnh chữ số viết tay 28x28
mnist = fetch_openml("mnist_784", version=1, as_frame=False, parser="auto")
print(mnist.data.shape)      # (70000, 784)
print(mnist.target.shape)    # (70000,)

Khác biệt: load_* kèm theo package, không cần internet; fetch_* tải về và cache ở ~/scikit_learn_data/. Lần đầu chạy mất 1–2 phút (MNIST ~55 MB), lần sau dùng cache.

11

Datasets generators — tạo data tổng hợp

Ngoài dataset thật, sklearn cung cấp các hàm make_* sinh dữ liệu tổng hợp với tham số tự chọn. Hữu ích khi muốn prototype thuật toán mà chưa có dataset thật, hoặc khi cần dataset với đặc tính cụ thể (số class, độ noise, cấu trúc cụm…).

  • make_classification(n_samples, n_features, n_classes, ...) — sinh dataset classification có thể tuỳ chỉnh độ khó.
  • make_regression(n_samples, n_features, noise, ...) — sinh dataset regression theo quan hệ tuyến tính + noise.
  • make_blobs(n_samples, centers, cluster_std) — sinh các cụm Gaussian, dùng cho clustering / classification dễ.
  • make_moons(noise), make_circles(noise) — sinh 2 class có hình dạng phi tuyến (hai trăng lưỡi liềm / vòng tròn lồng nhau). Dùng để minh hoạ vì sao cần kernel SVM hoặc neural network.

Ví dụ tạo dataset 1000 sample, 20 feature, 5 class:

from sklearn.datasets import make_classification

X, y = make_classification(
    n_samples=1000,
    n_features=20,
    n_informative=10,    # 10/20 feature thực sự có ý nghĩa
    n_classes=5,
    random_state=42      # tái lập kết quả
)
print(X.shape, y.shape)  # (1000, 20) (1000,)

random_state là seed cho random — fix giá trị này để cùng một script luôn sinh ra cùng một dataset, giúp kết quả tái lập được. Quy ước này xuất hiện ở mọi hàm có yếu tố random trong sklearn.

12

Giới hạn của iris

Iris hữu ích để học khái niệm, không đại diện cho dataset thực tế. Bốn giới hạn cần ghi nhớ:

  • Quá nhỏ. 150 sample — vài chục lần nhỏ hơn dataset thực tế nhỏ nhất. Không đủ để đánh giá model phức tạp (overfitting xảy ra với tập tí xíu).
  • Quá sạch. Không missing value, không outlier, không feature dạng chuỗi. Workflow ML thực tế dành 60–80% thời gian cho data cleaning — iris bỏ qua hoàn toàn phần đó.
  • Quá separable. Setosa tách tuyến tính khỏi 2 class kia; versicolor / virginica chỉ chồng lấn nhẹ. Đa số model (kể cả các thuật toán đơn giản nhất) đạt accuracy > 95%. Bạn không phân biệt được model "tốt" và model "rất tốt" trên iris.
  • Không có dữ liệu kiểu thực tế. Không có time series, không có text, không có ảnh, không có dữ liệu phân loại (categorical). Toàn số thực dương 1 chiều.

Hệ quả thực dụng:

  • Dùng iris để học khái niệm (feature, label, split, fit/predict) — tốt.
  • Dùng iris để chấm điểm một thuật toán mới — vô nghĩa. Mọi paper ML hiện đại đều dùng dataset thực (MNIST, CIFAR, ImageNet, Tabular benchmarks từ OpenML).
  • Khi xong Series 2, sẽ làm project trên dataset thực ở Series 5 (capstone) — Titanic, House Prices, Tabular Playground… kích thước hàng chục nghìn dòng, có missing, có categorical, không sạch.

Lời khuyên: học khái niệm trên iris thật nhanh, đừng dừng ở đây. Bài 6 sẽ chia iris thành train/val/test; từ Bài 7 trở đi sẽ gặp các dataset lớn hơn dần.

13

Preview end-to-end — train LogisticRegression trên iris

Một vòng ML đầy đủ trên iris chỉ tốn ~10 dòng code. Đây là preview cho Bài 22 (Logistic Regression). Bạn chưa cần hiểu chi tiết — chỉ cần thấy 5 bước workflow đã có trong sklearn:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# Bước 1: Load data
X, y = load_iris(return_X_y=True)

# Bước 2: Chia train/test (Bài 6 sẽ học kỹ)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Bước 3: Khởi tạo và train model
model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)

# Bước 4: Predict trên test set
y_pred = model.predict(X_test)

# Bước 5: Đánh giá
acc = accuracy_score(y_test, y_pred)
print(f"Accuracy: {acc:.4f}")    # ~0.9667

Output thường khoảng 96–100% accuracy — đúng như mục 12 đã cảnh báo: iris quá dễ. Nhưng pattern load → split → fit → predict → score này sẽ lặp lại ở mọi bài sau, chỉ thay model và metric.

Quan sát: 4 import, 5 dòng "logic" chính — đó là vẻ đẹp của sklearn. API thống nhất khiến mọi model (Decision Tree, Random Forest, SVM, KNN…) đều dùng được với cùng 5 dòng này, chỉ thay class model.

14

Bài tập

  1. Load load_wine(). In số sample, số feature, số class, và tên các class. Kiểm tra class có balanced không (gợi ý: dùng numpy.unique(y, return_counts=True) hoặc Pandas value_counts).
  2. Với iris, tính mean của từng feature theo từng class. Kết quả mong đợi: một bảng 3 dòng (3 class) × 4 cột (4 feature). Gợi ý: chuyển sang DataFrame rồi df.groupby("target").mean().
  3. Convert iris sang Pandas DataFrame (5 cột: 4 feature + target_name) và export ra file iris.csv. Đọc lại bằng pd.read_csv("iris.csv") để kiểm tra đúng.
  4. Dùng make_classification tạo dataset 500 sample, 10 feature, 4 class. In shape, in value_counts của y. Thử thay random_state và quan sát dataset thay đổi.
  5. So sánh shape của X trong load_iris() (4 feature) và load_digits() (64 feature). Vì sao digits có nhiều feature đến vậy? Hint: 8x8 = ?
Đáp án ngắn
  1. load_wine: 178 sample, 13 feature, 3 class (class_0, class_1, class_2). Class count: [59, 71, 48] — không cân bằng tuyệt đối nhưng không quá lệch (~1.5:1).
  2. Mean theo class (giá trị xấp xỉ): setosa có petal length ≈ 1.46, versicolor ≈ 4.26, virginica ≈ 5.55. Petal length là feature phân biệt 3 class rõ nhất.
  3. df.to_csv("iris.csv", index=False). Đọc lại bằng pd.read_csv("iris.csv") phải ra DataFrame 150 dòng giống ban đầu.
  4. X.shape == (500, 10), y.shape == (500,). value_counts trả về ~125 sample / class (cân bằng mặc định). Đổi random_state → dataset hoàn toàn khác.
  5. Digits có 64 feature vì mỗi ảnh 8x8 pixel được flatten thành vector 64 chiều. Mỗi pixel = 1 feature, giá trị 0–16 (mức độ "đậm" của mực).
15

Tóm tắt

  • Iris (Fisher 1936): 150 sample, 4 feature (sepal/petal length/width, cm), 3 class (setosa, versicolor, virginica), 50/50/50 balanced.
  • Load 3 style: load_iris() trả Bunch (dict-like), return_X_y=True trả tuple (X, y), as_frame=True trả Pandas DataFrame.
  • Bunch chứa: data, target, feature_names, target_names, DESCR.
  • 4 thuật ngữ cốt lõi: feature (X, predictor, attribute) — label (y, target, response) — sample (instance, observation) — class (giá trị rời rạc của label).
  • Shape convention sklearn: X 2D (n_samples, n_features), y 1D (n_samples,). Sai shape → lỗi Expected 2D array.
  • EDA cơ bản trên iris bằng Pandas: head(), describe(), value_counts(), corr(). Petal length / width tương quan ~0.96.
  • Dataset built-in khác: load_digits (1797 ảnh 8x8), load_wine (178, 13 feature, 3 class), load_breast_cancer (569, 30 feature, binary), load_diabetes (regression). fetch_openml cho dataset từ OpenML.
  • Generators (make_classification, make_regression, make_blobs, make_moons) — sinh data tổng hợp khi prototype thuật toán.
  • Giới hạn iris: quá nhỏ, quá sạch, quá separable, không đại diện thực tế. Học khái niệm thì ổn, không dùng để benchmark.
  • Bài 6 sẽ chia iris thành train / validation / test — bước đầu tiên của mọi pipeline ML thật.