← Tất cả các tuần · Phase 2: Mô tả · khoảng 270 phút
Tuần 5: Data quality, join và bẫy trung bình
Bản nháp, đang chờ duyệt nội dung
- Kiểm tra dữ liệu theo 5 chiều chất lượng: đủ, đúng, nhất quán, kịp thời, duy nhất.
- Nhận ra và chặn lỗi nhân dòng (fan-out) khi merge.
- Phân biệt weighted average và average of averages; biết cách nào đúng cho tỷ lệ.
- Giải thích Simpson's paradox bằng tỷ trọng (mix) giữa các nhóm.
- Trước khi xử lý missing values, luôn hỏi: vì sao thiếu?
- Đối soát tổng sau mỗi bước biến đổi bằng assert.
Video sắp có.
Audio tóm tắt tuần (NotebookLM) sắp có.
Tuần 4 dạy cách tóm tắt dữ liệu. Tuần này dạy cách không bị dữ liệu lừa: dữ liệu bẩn, join sai, và trung bình tính sai cách là ba nguồn gây ra con số sai phổ biến nhất trong báo cáo.
Bài 5.1. Năm chiều chất lượng dữ liệu [7]
| Chiều | Câu hỏi kiểm tra | Ví dụ lỗi | Check bằng pandas |
|---|---|---|---|
| Đủ (completeness) | Có thiếu dòng, thiếu giá trị không? | Cột Region bị trống | df.isna().sum() |
| Đúng (validity/accuracy) | Giá trị có hợp lệ không? | Sales âm, Quantity = 0, ngày giao trước ngày đặt | lọc điều kiện, describe() |
| Nhất quán (consistency) | Cùng một thứ có được ghi giống nhau không? | 1 Product ID có 2 tên; “HN” và “Hà Nội” | groupby(...).nunique() |
| Kịp thời (timeliness) | Dữ liệu có cập nhật đến kỳ cần không? | Báo cáo tháng 6 nhưng dữ liệu chỉ đến 20/6 | df["Order Date"].max() |
| Duy nhất (uniqueness) | Có dòng trùng không? | Một dòng bị nhập 2 lần | df.duplicated().sum() |
Thói quen: chạy bộ kiểm tra này mỗi khi nhận dữ liệu mới, trước khi tính bất cứ con số nào. Ghi lại lỗi tìm được và cách xử lý.
Bộ kiểm tra tìm ra 2 lỗi thật: 1 dòng trùng (Row ID 11) và 1 Product ID có 2 tên. Lỗi thứ hai sẽ gây ra fan-out ở bài tiếp theo.
Bài 5.2. Fan-out: lỗi nhân dòng khi join [7]
Bạn có bảng fact (mỗi dòng là một sản phẩm trong một đơn) và bảng dimension sản phẩm (mỗi mã một dòng). Merge hai bảng để lấy tên sản phẩm là việc làm hằng ngày.
Vấn đề: nếu bảng dimension có khóa bị trùng (một mã xuất hiện 2 dòng), mỗi dòng fact khớp với mã đó sẽ bị nhân đôi. Tổng Sales tăng lên mà không có lỗi nào được báo.
Hai cách chặn:
assert len(sau) == len(truoc)ngay sau merge (với left join từ fact sang dimension).pd.merge(..., validate="many_to_one"): pandas báo lỗi ngay nếu bảng bên phải có khóa trùng.
Trong thực tế, chọn tên nào cho mã bị trùng là quyết định nghiệp vụ (tên mới nhất, tên trong hệ thống gốc). Quan trọng là phát hiện được và ghi lại.
Bài 5.3. Weighted average và average of averages [7]
Hai cửa hàng:
| Cửa hàng | Doanh thu | Lợi nhuận | Margin |
|---|---|---|---|
| A | 1.000 | 200 | 20% |
| B | 100 | 0 | 0% |
- Average of averages: (20% + 0%) / 2 = 10%.
- Tỷ lệ tổng (weighted average): (200 + 0) / (1.000 + 100) = 18,2%.
Margin của cả công ty là 18,2%. Con số 10% coi cửa hàng nhỏ B nặng ngang cửa hàng lớn A. Khi các nhóm có quy mô khác nhau, trung bình của các tỷ lệ không bằng tỷ lệ tổng.
Cách 2 là margin thật của mỗi vùng. Cách 1 thấp hơn vì các dòng nhỏ (giá trị thấp, chiết khấu sâu, margin âm) được tính nặng ngang các dòng lớn.
Bài 5.4. Simpson’s paradox [7]
Simpson’s paradox: một xu hướng đúng trong từng nhóm lại đảo ngược khi gộp các nhóm lại.
Ví dụ nổi tiếng là tuyển sinh sau đại học UC Berkeley năm 1973. Tính chung, tỷ lệ đỗ của nam là 44,5%, của nữ là 30,4%. Nhìn vào thì có vẻ trường phân biệt giới tính. Nhưng khi tách theo khoa, ở phần lớn các khoa tỷ lệ đỗ của nữ bằng hoặc cao hơn nam.
Lý do là mix: nữ nộp đơn nhiều hơn vào các khoa khó đỗ (tỷ lệ đỗ chung thấp), còn nam nộp nhiều vào các khoa dễ đỗ. Tỷ lệ chung của nữ bị kéo xuống bởi chỗ họ nộp đơn, không phải bởi việc họ bị chấm khắt hơn.
Trong business: “giá trung bình mỗi đơn giảm” có thể chỉ vì tỷ trọng khách mua hàng rẻ tăng, trong khi giá ở mọi phân khúc đều tăng. Trước khi kết luận từ một con số gộp, hãy tách theo nhóm chính.
Thêm một bước: tính tỷ lệ đỗ chung của từng khoa và tỷ trọng đơn của nữ vào từng khoa. Bạn sẽ thấy hơn 90% đơn của nữ nộp vào C, D, E, F, nơi tỷ lệ đỗ chung chỉ 6–35%, trong khi một nửa đơn của nam nộp vào A, B (tỷ lệ đỗ trên 60%).
Bài 5.5. Missing values: hỏi “vì sao thiếu?” trước [6]
Có ba kiểu thiếu, và cách xử lý phụ thuộc vào kiểu:
| Kiểu thiếu | Ý nghĩa | Ví dụ | Xoá (dropna) có sao không? |
|---|---|---|---|
| Ngẫu nhiên hoàn toàn | Thiếu không liên quan đến gì cả | Lỗi đường truyền mất vài dòng | Ít ảnh hưởng, chỉ mất cỡ mẫu |
| Ngẫu nhiên theo biến khác | Thiếu liên quan đến một biến đã quan sát | Khách online hay bỏ trống số điện thoại | Lệch nếu không tách theo biến đó |
| Không ngẫu nhiên | Thiếu liên quan đến chính giá trị bị thiếu | Người thu nhập cao không khai thu nhập | Lệch nặng: mẫu còn lại không đại diện |
Hai câu hỏi bắt buộc trước khi xử lý: vì sao thiếu? Xoá đi thì mẫu còn đại diện không? Ghi câu trả lời ra trước, rồi mới viết code.
Các cách xử lý thường gặp: xoá dòng (dropna), điền giá trị (fillna bằng median, bằng giá trị theo nhóm, hoặc bằng 0 khi thiếu nghĩa là “không có”), hoặc giữ nguyên và báo cáo riêng nhóm thiếu.
Thực hành: pipeline có đối soát [7]
Mỗi bước biến đổi (lọc, xoá trùng, merge, groupby, pivot) đều có thể làm mất hoặc nhân dòng. Đối soát tổng sau từng bước là cách rẻ nhất để bắt lỗi. Nếu tổng thay đổi, bạn phải giải thích được vì sao.
Luyện tập tình huống
Tình huống: UC Berkeley 1973
Bối cảnh. Năm 1973, tỷ lệ đỗ sau đại học của UC Berkeley: nam 44,5% (1.198/2.691), nữ 30,4% (557/1.835). Một tờ báo viết: 'Berkeley phân biệt đối xử với nữ'. Bạn đã có số liệu theo 6 khoa ở ô code phía trên.
Câu hỏi. Tổng thể cho thấy gì? Theo từng khoa cho thấy gì? Vì sao hai cách nhìn lại ngược nhau, và kết luận của tờ báo có đúng không?
Câu trả lời đã nộp sẽ được khoá lại, không sửa được.
Đáp án mẫu
- Tổng thể: nam đỗ 44,5%, nữ 30,4%, có vẻ nữ bị bất lợi.
- Theo khoa: ở 4/6 khoa (A, B, D, F) nữ đỗ cao hơn nam; ở khoa A nữ đỗ 82% so với nam 62%. Hai khoa còn lại chênh lệch nhỏ.
- Vì sao: Simpson’s paradox do mix. Hơn 90% đơn của nữ nộp vào C, D, E, F, nơi tỷ lệ đỗ chung chỉ 6–35%; một nửa đơn của nam nộp vào A, B, nơi tỷ lệ đỗ trên 60%. Tỷ lệ tổng của nữ bị kéo xuống bởi lựa chọn khoa.
- Kết luận: dữ liệu không ủng hộ việc trường chấm khắt với nữ. Câu hỏi đúng hơn là vì sao nữ tập trung vào các khoa khó đỗ.
Lỗi hay gặp: kết luận từ tỷ lệ gộp; hoặc lấy trung bình 6 tỷ lệ của các khoa (average of averages) thay vì nhìn tỷ trọng.
Tình huống: dropna trong khảo sát thu nhập
Bối cảnh. Khảo sát 2.000 nhân viên về thu nhập. 30% người bỏ trống câu hỏi thu nhập. Analyst dùng dropna rồi tính thu nhập trung bình của 1.400 người còn lại, báo cáo đây là thu nhập trung bình của toàn công ty.
Câu hỏi. Cách làm này có vấn đề gì? Bạn sẽ làm gì khác?
Câu trả lời đã nộp sẽ được khoá lại, không sửa được.
Đáp án mẫu
- Vấn đề: phải hỏi “vì sao thiếu?”. Người thu nhập cao thường ngại khai, nên dữ liệu thiếu không ngẫu nhiên. Sau dropna, mẫu còn lại thiên về người thu nhập thấp, trung bình bị kéo xuống: đó là selection bias.
- Nên làm: so đặc điểm nhóm bỏ trống và nhóm trả lời (chức danh, phòng ban, thâm niên); nếu khác nhau rõ, nói rõ giới hạn trong báo cáo; cân nhắc điền theo nhóm (median theo chức danh), dùng dữ liệu lương từ hệ thống HR, hoặc hỏi lại theo khoảng thu nhập để giảm tỷ lệ bỏ trống.
- Báo median kèm mean, vì thu nhập lệch phải.
Lỗi hay gặp: coi dropna là “trung lập”; chỉ báo con số mà không nói 30% bị thiếu.
Tóm tắt tuần
- Nhận dữ liệu mới → chạy bộ kiểm tra 5 chiều chất lượng → ghi lỗi.
- Merge: kiểm tra khóa dimension duy nhất,
validate="many_to_one", assert số dòng. - Tỷ lệ tổng = cộng tử, cộng mẫu, rồi chia. Không lấy trung bình các tỷ lệ.
- Con số gộp đi ngược con số từng nhóm → nghĩ đến mix (Simpson).
- Missing: hỏi “vì sao thiếu?” trước khi dropna hay fillna.
- Đối soát tổng sau mỗi bước; chênh lệch phải giải thích được.