Chương 1·Bài 1.6

Regression và ranking metrics

Với bài toán dự đoán một con số (regression), như đoán số người đến buổi học, sai số đo bằng khoảng cách: đoán 32 khi thực tế là 30 thì sai 2. Với bài toán xếp hạng (ranking), như gợi ý ba bài luyện phù hợp nhất cho mỗi học sinh, điều quan trọng là bài phù hợp có nằm gần đầu danh sách không. Bài này học các metric cho hai loại bài toán đó: MAE, MSE, RMSE, R2R^2, MAPE và MAP@k, và phân biệt metric dùng để chấm với loss dùng để huấn luyện.

Độ lớn lỗi và đơn vị

Gọi phần dư ri=y^i−yir_i=\hat y_i-y_i. Với nn mẫu,

MAE⁡=1n∑i∣ri∣,MSE⁡=1n∑iri2,RMSE⁡=MSE⁡.\operatorname{MAE}=\frac1n\sum_i|r_i|,\qquad \operatorname{MSE}=\frac1n\sum_i r_i^2,\qquad \operatorname{RMSE}=\sqrt{\operatorname{MSE}}.

MAE giữ cùng đơn vị với target. Nếu target là số người, MAE cũng là số người. MSE có đơn vị người bình phương, nên khó đọc trực tiếp; RMSE đưa về người. Cả ba đều càng thấp càng tốt. RMSE 0.5 tỉ đồng cho giá nhà nghĩa là dự đoán thường lệch cỡ nửa tỉ, với lỗi lớn được tính nặng hơn.

Lỗi 4 góp 16 vào MSE nhưng chỉ 4 vào MAE.0481216-4-2024phần dư rr² = 16|r| = 4
Lỗi 4 góp 16 vào MSE nhưng chỉ 4 vào MAE.
Ba mẫu của ví dụ trong bài, chỉ mẫu 3 lệch ngày càng xa: MAE tăng theo đúng phần lệch chia 3, RMSE tăng nhanh hơn vì bình phương dồn trọng số vào lỗi lớn.

Bình phương khiến lỗi 4 đóng góp 16, gấp 16 lần lỗi 1; trong MAE chỉ gấp bốn lần. MSE/RMSE nhạy với sai số lớn và outlier. Điều ấy có thể phù hợp nếu lỗi rất lớn đắt giá; cũng có thể bị một nhãn nhập nhầm chi phối. Không coi outlier mặc nhiên là rác: cần kiểm ý nghĩa và nguồn ghi nhãn.

RMSE không phải trung bình căn của từng lỗi bình phương. Làm theo cách ấy sẽ thành MAE, vì ri2=∣ri∣\sqrt{r_i^2}=|r_i|. Thứ tự lấy trung bình và căn quan trọng.

Huber loss nằm giữa hai cách: bằng 12e2\tfrac12 e^2 khi ∣e∣≤δ|e|\le\delta và bằng δ(∣e∣−12δ)\delta(|e|-\tfrac12\delta) khi xa hơn. Gần 0 nó trơn như MSE, ở xa tăng tuyến tính như MAE, nên một điểm ngoại lai không kéo lệch cả mô hình: với δ=1\delta=1, lỗi e=3e=3 chỉ góp 2.5 thay vì 4.5.

Hỏi nhanh

Đổi target từ giờ sang phút, nên mọi target và mọi dự đoán đều nhân 60. MSE thay đổi thế nào?

R²: so với mốc đoán trung bình

Ba buổi có target (10,20,30)(10,20,30) và dự đoán (12,18,27)(12,18,27). Phần dư là (2,−2,−3)(2,-2,-3), nên MAE =7/3≈2.333=7/3\approx2.333, MSE =17/3≈5.667=17/3\approx5.667, RMSE =17/3≈2.380=\sqrt{17/3}\approx2.380.

R2R^2 so tổng bình phương lỗi với phương án dự đoán trung bình của tập đang chấm:

R2=1−∑i(yi−y^i)2∑i(yi−yˉ)2.R^2=1-\frac{\sum_i(y_i-\hat y_i)^2}{\sum_i(y_i-\bar y)^2}.

Trong ví dụ yˉ=20\bar y=20, mẫu số là 100+0+100=200100+0+100=200, nên R2=1−17/200=0.915R^2=1-17/200=0.915. Mốc “đoán trung bình tập chấm” chỉ dùng để định nghĩa metric: một model thật không được biết trung bình ấy. Baseline thật học trung bình train, nên trên validation nó thường có R2R^2 hơi dưới 0 chứ không đúng bằng 0.

Tổng lỗi bình phương: model 17, đoán trung bình 200.model4494 + 4 + 9 = 17đoán trung bình 201000100100 + 0 + 100 = 200R² = 1 − 17 / 200 = 0.915
Tổng lỗi bình phương: model 17, đoán trung bình 200.
Python
import numpy as np
from sklearn.metrics import (
    mean_absolute_error, mean_squared_error, r2_score,
    mean_absolute_percentage_error,
)

y = np.array([10.0, 20.0, 30.0])
prediction = np.array([12.0, 18.0, 27.0])
residual = prediction - y
print('Phần dư:', residual)
print(f'MAE={mean_absolute_error(y, prediction):.3f}')
print(f'MSE={mean_squared_error(y, prediction):.3f}')
print(f'RMSE={np.sqrt(mean_squared_error(y, prediction)):.3f}')
print(f'R2={r2_score(y, prediction):.3f}')

Các dòng phải khớp phép tính tay. R2=1R^2=1 là dự đoán đúng hết; bằng 0 là ngang mốc trung bình tập chấm; âm là tệ hơn mốc ấy. Nó không phải phần trăm số mẫu đoán đúng. Chẳng hạn R2=0.915R^2=0.915 không nói rằng 91.5% buổi có số người dự đoán chính xác.

Nếu mọi target của tập chấm bằng nhau, mẫu số bằng 0 và R2R^2 không xác định; scikit-learn khi đó trả về 0 hoặc 1 theo quy ước riêng. Ngoài ra, R2R^2 phụ thuộc độ phân tán của tập chấm, nên không so R2R^2 của hai bộ dữ liệu khác hẳn nhau để nói model nào tốt hơn.

Hỏi nhanh

Mô hình có R2=−0.5R^2 = -0.5 trên validation. Con số này nói lên điều gì?

MAPE: tỉ lệ lỗi nhưng có mẫu số nguy hiểm

Mean absolute percentage error dùng độ lớn tương đối so với target:

MAPE⁡=1n∑i∣yi−y^i∣∣yi∣,yi≠0.\operatorname{MAPE}=\frac1n\sum_i\frac{|y_i-\hat y_i|}{|y_i|},\qquad y_i\ne0.

Muốn biểu diễn phần trăm, nhân kết quả với 100. Mẫu số là giá trị thật, không phải dự đoán: đoán 453 khi thật là 488 lệch 35/488≈7.2%35/488\approx7.2\%. Với ba buổi trên, các lỗi tương đối là 0.2, 0.1, 0.1: trung bình khoảng 0.1333, tức 13.33%.

Target nhỏ khiến cùng một lỗi tuyệt đối bị phạt lớn hơn. Đoán 2 khi thật là 1 sai 100%; đoán 101 khi thật là 100 chỉ sai 1%, dù cả hai sai một đơn vị. Nếu có y=0y=0, công thức này chia 0. Thư viện thay mẫu số bằng một số rất nhỏ nên có thể trả số hữu hạn khổng lồ; đó không có nghĩa metric đã trở nên dễ diễn giải.

Python
print(f'MAPE dạng tỉ lệ={mean_absolute_percentage_error(y, prediction):.4f}')
print(f'MAPE phần trăm={100 * mean_absolute_percentage_error(y, prediction):.2f}%')
zero_case = mean_absolute_percentage_error([0.0, 10.0], [1.0, 9.0])
print(f'MAPE với target 0 theo thư viện={zero_case:.3e}')

Dòng cuối cho thấy: có target bằng 0 thì MAPE của thư viện ra một số khổng lồ, chẳng còn ý nghĩa. Vì vậy trước khi dùng MAPE, kiểm xem target có số 0 không. Nếu đề có cách xử lý riêng, như cộng thêm một số nhỏ vào mẫu số hay dùng sMAPE, thì cài đúng như đề.

Cùng lỗi tuyệt đối 1, lỗi tương đối phụ thuộc độ lớn target.thật 1, đoán 2100%thật 10, đoán 1110%thật 100, đoán 1011%cùng sai 1 đơn vị
Cùng lỗi tuyệt đối 1, lỗi tương đối phụ thuộc độ lớn target.

Để thấy việc chọn metric làm đổi quyết định, xét hai dự đoán sau trên cùng target (1,100)(1,100).

Python
small_large = np.array([1.0, 100.0])
candidate_a = np.array([2.0, 100.0])
candidate_b = np.array([1.0, 104.0])
for name, pred in [('A', candidate_a), ('B', candidate_b)]:
    mae = mean_absolute_error(small_large, pred)
    mape = mean_absolute_percentage_error(small_large, pred)
    print(f'{name}: MAE={mae:.3f}, MAPE={mape:.3f}')

Theo MAE, A tốt hơn vì tổng lỗi chỉ là 1 thay vì 4. Theo MAPE, B tốt hơn vì tránh lỗi trên target 1. Không có mâu thuẫn: hai metric đặt trọng số khác nhau cho hai buổi.

Hỏi nhanh

Trong dữ liệu có những target bằng 0, mà đề chấm bằng MAPE. Ta xử lý thế nào?

Loss học và metric chấm có thể khác nhau

Loss là hàm mà thuật toán làm nhỏ nhất khi học trên train. Metric là thước đo dùng để chấm trên validation và test, theo đúng yêu cầu của đề. Hai thứ có thể trùng nhau, nhưng không bắt buộc: một model học bằng MSE vẫn có thể được chấm bằng MAE.

Loss quyết định model đoán về đâu. Nếu chỉ được đoán một hằng số, MSE nhỏ nhất khi đoán bằng trung bình (mean), còn MAE nhỏ nhất khi đoán bằng trung vị (median). Train có target (10,10,10,50)(10, 10, 10, 50): mean bằng 20, bị mẫu 50 kéo lên; median vẫn là 10.

Loss còn phải có đạo hàm dùng được (bài 0.6). Accuracy thì không: nhích trọng số một chút thường không đổi nhãn nào, nên đạo hàm gần như luôn bằng 0. Vì vậy bộ phân loại học bằng cross-entropy (bài 2.3) rồi mới chấm bằng accuracy.

Target 10, 10, 10, 50: mean bị điểm 50 kéo lên, median thì không.01020304050median 10 · tối ưu MAEmean 20 · tối ưu MSE
Target 10, 10, 10, 50: mean bị điểm 50 kéo lên, median thì không.
Python
train_targets = np.array([10.0, 10.0, 10.0, 50.0])
for name, value in [('mean', train_targets.mean()), ('median', np.median(train_targets))]:
    constant_prediction = np.full(len(train_targets), value)
    print(
        f'{name}: giá trị={value:.1f}, '
        f'MAE={mean_absolute_error(train_targets, constant_prediction):.1f}, '
        f'MSE={mean_squared_error(train_targets, constant_prediction):.1f}'
    )

Mean có MSE thấp hơn, median có MAE thấp hơn: mỗi loss kéo dự đoán về “tâm” riêng của nó. Muốn chọn model thì vẫn đo trên validation bằng metric của đề. Riêng MSE và RMSE luôn xếp hạng các model giống nhau, vì RMSE chỉ là căn bậc hai của MSE.

Hỏi nhanh

Muốn phạt lỗi lớn còn mạnh hơn MSE, một bạn đề xuất học linear regression bằng trung bình lập phương của phần dư, 1n∑i(y^i−yi)3\frac1n\sum_i(\hat y_i - y_i)^3. Cách này sai ở đâu?

Phỏng theoCMU 10-601 · Exam 1 Practice · Q5.4

Ranking: một danh sách, không phải một số

Câu lạc bộ muốn gợi ý ba bài luyện cho mỗi học sinh. Với một query, tức một yêu cầu gợi ý của một học sinh, ta có tập bài thật sự phù hợp (relevant). Một danh sách tốt đặt nhiều bài phù hợp gần đầu. Xét tập relevant {A,C,E} và danh sách [A,B,C]: vị trí 1 đúng, vị trí 2 sai, vị trí 3 đúng.

Precision@r là số bài relevant trong rr vị trí đầu chia rr. Average precision ở top kk cần một quy ước mẫu số. Trong bài này chọn

AP@⁡k=∑r=1kP@r⋅rel⁡(r)min⁡(R,k),R>0,\operatorname{AP@}k=\frac{\sum_{r=1}^{k} P@r\cdot\operatorname{rel}(r)}{\min(R,k)},\qquad R>0,

Ở đây RR là số bài thật sự phù hợp, rel⁡(r)\operatorname{rel}(r) bằng 1 nếu bài ở vị trí rr phù hợp, bằng 0 nếu không. Nói cách khác: tại mỗi vị trí có bài đúng, lấy precision tính đến vị trí đó, cộng lại, rồi chia cho số bài đúng tối đa có thể có trong top kk.

Mỗi đề có thể định nghĩa AP hơi khác: có đề chia cho RR thay vì min⁡(R,k)\min(R, k), có đề bỏ query không có bài phù hợp nào, có đề quy định riêng khi một bài bị lặp. Vì vậy đọc kỹ công thức của đề trước khi viết hàm chấm. Code trong bài cho AP bằng 0 khi R=0R = 0, và không cho phép bài lặp trong top kk.

Cùng hai bài đúng trong top 3; đặt bài đúng sớm hơn cho AP cao hơn.A1/1BC2/3AP@3 = 5/9C1/1E2/2BAP@3 = 2/3relevant: A, C, EP@3 cả hai = 2/3
Cùng hai bài đúng trong top 3; đặt bài đúng sớm hơn cho AP cao hơn.

Với [A,B,C], tử số là 1+2/3=5/31+2/3=5/3, mẫu số là 3, nên AP@3 =5/9=5/9. Với [C,E,B], tử số là 1+1=21+1=2, mẫu số 3, nên AP@3 =2/3=2/3. Precision@3 của cả hai bằng 2/32/3, nhưng AP thích cách đặt bài đúng sớm hơn.

Tìm kiếm và hệ gợi ý (recommender) đều là bài xếp hạng: quan trọng là thứ tự, không phải con số chính xác. Ngoài AP còn hai metric xếp hạng hay gặp:

  • MRR: trung bình của 1/hạng1/\text{hạng} của đáp án đúng đầu tiên. Ba câu hỏi có đáp án đúng ở hạng 1, hạng 3 và không có, cho MRR =(1+1/3+0)/3≈0.44= (1 + 1/3 + 0)/3 \approx 0.44.
  • nDCG: dùng khi độ phù hợp có nhiều mức. DCG=∑rrelr/log⁡2(r+1)\mathrm{DCG} = \sum_r \mathrm{rel}_r / \log_2(r + 1) cộng điểm phù hợp, giảm dần theo vị trí; nDCG chia DCG cho DCG của thứ tự lý tưởng để ra một số trong [0,1][0, 1].

Hỏi nhanh

Các bài liên quan (relevant) là {A,C,E}. So hai danh sách xếp hạng [B,A,C] và [A,B,C] ở top 3. Precision@3 và AP@3 của hai danh sách khác nhau thế nào?

Cài một scorer nhỏ và kiểm tay

MAP@k (mean average precision) là trung bình AP@k của mọi query, mỗi query nặng như nhau. Đừng nối mọi danh sách lại rồi tính AP một lần: mỗi học sinh có tập bài phù hợp riêng.

Python
def ap_at_k(ranking, relevant, k):
    assert k >= 1, 'k phải dương'
    top = list(ranking[:k])
    assert len(top) == len(set(top)), 'Không cho duplicate trong top k'
    relevant = set(relevant)
    if not relevant:
        return 0.0
    hits = 0
    total = 0.0
    for rank, item in enumerate(top, start=1):
        if item in relevant:
            hits += 1
            total += hits / rank
    return total / min(len(relevant), k)

rankings = [['A', 'B', 'C'], ['B', 'D', 'E']]
relevant_sets = [{'A', 'C', 'E'}, {'D'}]
ap_scores = [ap_at_k(rank, rel, 3) for rank, rel in zip(rankings, relevant_sets)]
print('AP@3 từng query:', np.round(ap_scores, 6))
print(f'MAP@3={np.mean(ap_scores):.6f}')
assert np.isclose(ap_scores[0], 5 / 9)
assert np.isclose(ap_scores[1], 1 / 2)

Query thứ hai có một bài relevant ở hạng 2 nên AP@3 =1/2=1/2. MAP của hai query là (5/9+1/2)/2=19/36≈0.527778(5/9+1/2)/2=19/36\approx0.527778. Các assert đối chiếu với phép tính độc lập, giống kiểm một hàm CP bằng vài trường hợp nhỏ có đáp án chắc chắn.

Hỏi nhanh

Bỏ dòng assert chặn mục trùng trong ap_at_k, rồi gọi ap_at_k(['A', 'A', 'C'], {'A', 'C'}, 3). Kết quả là bao nhiêu?

Chọn model gợi ý cũng cần chia dữ liệu như bài 1.3: theo người mới hoặc theo thời gian, và không đưa tương tác ở tương lai vào feature. Metric đúng mà cách chia sai thì điểm vẫn không đáng tin.

Khi đi thi

  • Viết hàm chấm theo đúng công thức của đề, kiểm bằng vài ví dụ tính tay có đáp án chắc chắn.
  • Trước khi dùng MAPE, kiểm target có bằng 0 không; có outlier thì RMSE tăng mạnh hơn MAE.
  • Ranking: tính AP từng query rồi mới lấy trung bình, và chặn mục trùng trong top kk.

Tóm tắt

  • MAE giữ đơn vị; MSE phạt lỗi lớn; RMSE là căn của MSE.
  • R2R^2 dùng mốc trung bình tập chấm và có thể âm.
  • MAPE đặt trọng số lớn lên target nhỏ và cần quy ước khi target 0.
  • AP@k thưởng bài relevant ở gần đầu; MAP trung bình theo query.
  • Loss trên train và metric chọn/chấm phải được phân biệt rõ.

Kiểm tra cuối bài

Câu 1

Trên năm buổi, lỗi tuyệt đối của mô hình A là (1,1,1,1,8)(1, 1, 1, 1, 8), của mô hình B là (3,3,3,3,3)(3, 3, 3, 3, 3). Theo MAE thì mô hình nào tốt hơn, theo RMSE thì sao?

Câu 2

Mô hình đoán số người đến có MSE bằng 9, đơn vị là “người bình phương”. RMSE bằng bao nhiêu?

Câu 3

Một đề tính điểm theo RMSE: điểm=Xbaseline−XXbaseline−Xbest×100%\text{điểm} = \dfrac{X_\text{baseline} - X}{X_\text{baseline} - X_\text{best}} \times 100\%, và bằng 0 nếu XX tệ hơn baseline. Baseline có RMSE 2.0, bài tốt nhất có 1.0, đội mình có 1.4. Điểm hiện tại là bao nhiêu, và nếu RMSE giảm còn 1.2 thì được bao nhiêu?

Phỏng theoUSA-NA-AIO 2026 · Vòng 2 · Ngày 2

Câu 4

Lỗi của mỗi mẫu được tính bằng 103⋅evị trıˊ+3⋅10−3⋅etrường10^3 \cdot e_\text{vị trí} + 3 \cdot 10^{-3} \cdot e_\text{trường}. Ở đây evị trıˊe_\text{vị trí} là tổng sai số tuyệt đối của tọa độ nguồn, còn etrườnge_\text{trường} là RMSE của 100 giá trị cường độ. Trên validation, trung bình evị trıˊ=0.02e_\text{vị trí} = 0.02 và etrường=50e_\text{trường} = 50. Ta chỉ đủ thời gian làm một việc. Việc nào giảm lỗi nhiều hơn?

Phỏng theoUSA-NA-AIO 2026 · Vòng 2 · Ngày 1

Câu 5

Hai buổi có target là 2 và 50, mô hình đoán 3 và 60. Ta chỉ được sửa một dự đoán về đúng giá trị thật. Muốn MAPE giảm nhiều nhất thì sửa buổi nào? Muốn MAE giảm nhiều nhất thì sửa buổi nào?

Câu 6

Target train là (0,0,0,8,12)(0, 0, 0, 8, 12). Nếu chỉ được đoán một hằng số cho mọi mẫu, hằng số nào cho MAE nhỏ nhất, hằng số nào cho MSE nhỏ nhất?

Phỏng theoCMU 10-601 · Exam 1 Practice · Q5.5

Câu 7

Các mục relevant là B, D, E, F. Hệ thống trả về thứ hạng [A, B, C, D]. AP@4 dùng mẫu số min⁡(R,4)\min(R, 4), với RR là tổng số mục relevant. AP@4 bằng bao nhiêu?

Câu 8

Hai query có AP là 0.8 và 0.2. Query đầu có 1 mục relevant, query sau có 9. MAP, tức trung bình đều theo query, bằng bao nhiêu?

Câu 9

Có R=5R = 5 mục relevant. Hệ thống chỉ trả về k=3k = 3 kết quả, và cả ba đều relevant. Nếu chia cho RR thì AP@3 bằng bao nhiêu? Nếu chia cho min⁡(R,k)\min(R, k) thì sao?

Câu 10

Trên cùng validation, mô hình A có MAE 2.0 và MSE 10. Mô hình B có MAE 2.4 và MSE 8. Cả hai đều học bằng MSE, nhưng đề chấm bằng MAE. Ta chọn mô hình nào?

Đọc thêm