Bạn đang xem thử công khai
Đăng nhập để lưu tiến độ, làm bài tập, thảo luận và nhận phản hồi.
Dữ liệu thật gần như luôn có ô trống. Bỏ qua chúng thì mô hình không chạy được; xử lý sai thì mô hình học phải thông tin bịa.
Không phải mọi ô trống đều giống nhau:
| Kiểu thiếu | Nghĩa là gì | Ví dụ |
|---|---|---|
| Thiếu ngẫu nhiên hoàn toàn | Ô trống không liên quan gì tới dữ liệu | Cảm biến mất điện vài phút |
| Thiếu có điều kiện | Xác suất thiếu phụ thuộc cột khác | Người thu nhập cao ngại khai thu nhập |
| Thiếu không ngẫu nhiên | Xác suất thiếu phụ thuộc chính giá trị bị thiếu | Bệnh nhân nặng bỏ dở khảo sát |
Hai kiểu sau nguy hiểm hơn: bản thân việc thiếu đã mang thông tin. Điền bừa vào đó là xoá mất tín hiệu.
1. Xoá dòng — chỉ nên dùng khi số dòng thiếu rất nhỏ (dưới ~5%) và thiếu ngẫu nhiên.
data = data.dropna() # xoá mọi dòng có bất kỳ ô trống nào
data = data.dropna(subset=["BMI"]) # chỉ xét cột BMI
2. Điền bằng thống kê (imputation) — giữ lại dòng, thay ô trống bằng một giá trị đại diện.
data["BMI"] = data["BMI"].fillna(data["BMI"].median()) # số: median an toàn hơn mean
data["city"] = data["city"].fillna(data["city"].mode()[0]) # hạng mục: giá trị hay gặp nhất
Vì sao median thường tốt hơn mean: mean bị kéo lệch bởi giá trị ngoại lai. Một căn biệt thự 100 tỷ trong tập giá nhà sẽ kéo mean lên cao, khiến mọi ô trống bị điền một giá trị phi thực tế. Median không bị vậy.
3. Thêm cột đánh dấu — khi việc thiếu tự nó có ý nghĩa:
data["BMI_missing"] = data["BMI"].isna().astype(int)
data["BMI"] = data["BMI"].fillna(data["BMI"].median())
Cách này giữ được cả hai: giá trị điền để mô hình chạy, và tín hiệu "chỗ này vốn trống".
Tính median trên toàn bộ dữ liệu rồi mới chia train/test. Khi đó median đã "nhìn thấy" tập test — rò rỉ dữ liệu. Phải chia trước, tính median trên tập train, rồi áp cùng giá trị đó cho tập test.
data.isna().sum() # đếm ô trống từng cột
data.isna().mean().sort_values() # tỉ lệ thiếu, sắp xếp tăng dần