Những cái bẫy dữ liệu khi làm dự án data

Những cái bẫy dữ liệu

Những cái bẫy dữ liệu khi làm dự án data không phải lúc nào cũng là những lỗi khiến chương trình dừng chạy, SQL báo error hay mô hình Machine Learning không train được. Ngược lại, nhiều cái bẫy nguy hiểm nhất lại xuất hiện khi mọi thứ trông có vẻ hoàn toàn bình thường: code vẫn chạy, biểu đồ vẫn đẹp, số liệu vẫn được tính toán và model thậm chí còn cho kết quả rất tốt.

Vấn đề nằm ở chỗ chúng ta có thể không nhìn thấy hết những gì đang có trong dữ liệu, hiểu sai điều dữ liệu thực sự thể hiện hoặc dừng phân tích quá sớm nên bỏ mất các quy luật nằm sâu bên trong.

Khi đó, có thể nói dữ liệu đang bị “câm”.

Không phải vì dữ liệu không có gì để nói, mà bởi vì:

  • chúng ta không nghe thấy;
  • chúng ta nghe sai;
  • hoặc chúng ta chưa nghe hết.

Đó cũng là lý do khi làm một dự án Data hay AI, biết Python, SQL, Visualization hay Machine Learning là chưa đủ. Người làm dữ liệu còn phải biết nhận diện những chi tiết rất nhỏ nhưng có khả năng làm thay đổi hoàn toàn cách hiểu về dataset.

Cái bẫy dữ liệu là gì?

Có thể hiểu đơn giản: Cái bẫy dữ liệu là những chi tiết dễ sót, dễ nhầm hoặc dễ bị bỏ qua trong quá trình làm dự án, khiến người phân tích không hiểu đầy đủ những vấn đề, bất thường, mối quan hệ và quy luật đang tồn tại trong dữ liệu.

Điểm đáng chú ý là chúng không nhất thiết gây ra lỗi kỹ thuật. Bạn vẫn có thể:

  • đọc được file CSV;
  • chạy được câu SQL;
  • JOIN được các bảng;
  • tính được AVG(), SUM(), COUNT();
  • vẽ được histogram, boxplot, heatmap;
  • train được model;
  • thậm chí đạt metric rất cao.

Nhưng toàn bộ kết quả phía sau vẫn có thể được xây dựng trên một cách hiểu chưa đầy đủ hoặc sai bản chất dữ liệu.

Có thể chia những cái bẫy này thành ba nhóm như sau:

  • Dễ sót : Dữ liệu có điều muốn nói nhưng ta không nghe thấy.
  • Dễ nhầm: Dữ liệu nói một điều nhưng ta nghe thành điều khác.
  • Dễ bỏ qua: Ta đã nghe thấy lớp đầu tiên nhưng chưa nghe hết câu chuyện.
  • Ngoài ra, trong các dự án AI còn có một cái bẫy đặc biệt: Data Leakage.

I. Các bẫy Dễ Sót

1. Bẫy “Không thấy = không có”

Đây là một trong những bẫy dễ gặp nhất. Khi kiểm tra dữ liệu, chúng ta thường tìm:

df.isnull().sum()

Nhưng vấn đề không chỉ nằm ở những ô có giá trị NULL. Nguy hiểm hơn là:

Một thứ đáng lẽ phải xuất hiện nhưng lại hoàn toàn không tồn tại trong dataset. Ví dụ:

  • mất nguyên một khoảng ngày;
  • thiếu dữ liệu của một khu vực;
  • một nhóm khách hàng hoàn toàn không xuất hiện;
  • một trường dữ liệu chỉ bắt đầu được ghi nhận từ một thời điểm nào đó;
  • bảng chính có record nhưng bảng phụ không có dữ liệu tương ứng;
  • một biến quan trọng về nghiệp vụ hoàn toàn không được thu thập;
  • một nguồn dữ liệu bị bỏ qua trong quá trình tổng hợp.

Khi đó, isnull() có thể vẫn không cho chúng ta thấy vấn đề.

Ví dụ một cửa hàng không có bất kỳ record nào trong ngày 15/07. Không thể ngay lập tức kết luận: “Ngày đó cửa hàng không có hoạt động.” Mà có thể:

  • cửa hàng đóng cửa;
  • hệ thống không ghi nhận dữ liệu;
  • file truyền dữ liệu bị lỗi;
  • record bị loại trong một bước tiền xử lý trước đó;
  • dữ liệu thực sự bị mất.

Vì vậy: Không xuất hiện trong dữ liệu không có nghĩa là không tồn tại trong thực tế.

Đây là loại bẫy rất nguy hiểm bởi thứ bị thiếu thường không tự báo rằng nó đang bị thiếu.

2. Bẫy “Số đông che tiếng nhóm nhỏ”

Các báo cáo thường bắt đầu bằng những số liệu tổng hợp:

  • tổng doanh thu;
  • doanh thu trung bình;
  • tổng số khách hàng;
  • tỷ lệ chuyển đổi chung;
  • giá trị trung bình toàn hệ thống.

Những con số này rất hữu ích. Nhưng chúng cũng có khả năng che mất những câu chuyện đang diễn ra bên trong. Ví dụ:

Doanh thu toàn hệ thống tăng 8%. Nghe có vẻ rất tốt. Nhưng khi chia nhỏ:

  • miền Nam: +25%;
  • miền Bắc: −12%;
  • nhóm cửa hàng mới: +40%;
  • nhóm cửa hàng cũ: −7%.

Con số +8% không sai. Nhưng nếu chỉ nhìn nó, chúng ta đã bỏ qua hai nhóm đang giảm.

Đây chính là điểm đáng lưu ý: Một kết quả tổng thể có thể hoàn toàn đúng nhưng vẫn chưa đủ để hiểu dữ liệu.

Trong dự án Data, đôi khi dữ liệu tổng thể nói rất nhỏ nhưng một nhóm nhỏ bên trong lại đang nói rất lớn.

Nếu không phân nhóm và so sánh, tiếng nói đó rất dễ biến mất.

3. Bẫy “Cái bất thường bị coi là rác”

Khi học Data Cleaning, chúng ta thường gặp: Outlier → phát hiện → xử lý.

Nhưng một outlier có thể thuộc hai trường hợp hoàn toàn khác nhau.

Trường hợp 1: Dữ liệu sai Ví dụ:

  • nhập dư một số 0;
  • sai đơn vị;
  • lỗi cảm biến;
  • lỗi nhập liệu.

Với trường hợp này đúng là cần xử lý.

Trường hợp 2: Dữ liệu đúng nhưng hiếm Ví dụ:

  • một sự kiện đặc biệt;
  • ngày lễ;
  • chương trình khuyến mãi lớn;
  • một hành vi hiếm;
  • một hiện tượng mới;
  • một giao dịch gian lận;
  • một nhóm khách hàng rất đặc biệt.

Nếu chúng ta áp dụng IQR hoặc một quy tắc thống kê rồi xóa máy móc, rất có thể: thứ bị xóa lại chính là thứ đáng để điều tra nhất.

Thay vì hỏi: “Điểm này có phải outlier không?” hãy hỏi thêm:

  • Nó xuất hiện khi nào?
  • Thuộc nhóm nào?
  • Có lặp lại không?
  • Các biến xung quanh có gì đặc biệt?
  • Có lý do nghiệp vụ nào giải thích được không?

Một outlier sau khi điều tra có thể vẫn là rác. Nhưng cũng có thể từ “rác” biến thành insight.

Đôi khi điểm dữ liệu nói to nhất lại chính là điểm chúng ta định xóa đầu tiên.

II. Các bẫy Dễ Nhầm

4. Bẫy “Cùng giá trị nhưng khác ý nghĩa”

Máy tính nhìn thấy: 0 . Nhưng con người phải hiểu: 0 này có nghĩa là gì?

Một số 0 có thể đại diện cho:

  • thực sự bằng 0;
  • không xảy ra;
  • không áp dụng;
  • chưa ghi nhận;
  • không biết;
  • giá trị mặc định.

Ví dụ trong dữ liệu bán lẻ:

Trường hợp A

  • Sales = 0
  • Open = 0
  • Cửa hàng đóng cửa.

Trường hợp B

  • Sales = 0
  • Open = 1
  • Cửa hàng đang mở nhưng doanh số bằng 0.

Hai dòng có cùng: Sales = 0 nhưng ý nghĩa hoàn toàn khác nhau.

Do đó: Một con số không tự mang đầy đủ ý nghĩa. Ý nghĩa đến từ context.

5. Bẫy “Khác hình thức nhưng cùng ý nghĩa”

Đây là bẫy ngược lại. Ví dụ cùng một địa điểm có thể được ghi:

  • TP.HCM;
  • TP HCM;
  • Hồ Chí Minh;
  • Ho Chi Minh City;
  • HCMC.

Con người nhìn vào và hiểu: đây là cùng một thành phố. Nhưng đối với máy tính, nếu chưa chuẩn hóa: đây có thể là 5 category khác nhau.

Điều tương tự xảy ra với:

  • tên khách hàng;
  • tên sản phẩm;
  • giới tính;
  • địa chỉ;
  • trạng thái đơn hàng;
  • tên công ty;

Nếu không phát hiện, dữ liệu sẽ kể một câu chuyện sai.

Chẳng hạn hệ thống báo có 5 khu vực khác nhau trong khi thực tế chỉ có một.

Trước khi nghe dữ liệu nói, phải chắc rằng dữ liệu đang nói cùng một ngôn ngữ.

6. Bẫy “Con số đúng nhưng sai ngữ cảnh”

Một phép tính hoàn toàn có thể đúng về toán học nhưng vẫn dẫn đến kết luận sai. Ví dụ:

  • doanh số trung bình cửa hàng A: 7.000;
  • doanh số trung bình cửa hàng B: 5.000.

Phép tính không sai. Nhưng trước khi kết luận A hoạt động tốt hơn B, cần hỏi:

  • A và B có cùng loại cửa hàng không?
  • số ngày hoạt động có giống nhau không?
  • tần suất khuyến mãi có khác nhau không?
  • lượng khách hàng có khác nhau không?
  • vị trí có khác không?
  • thời điểm quan sát có tương đương không?

Một ví dụ phổ biến khác:

Average Sales ngày có Promotion cao hơn Average Sales ngày không Promotion.

Điều đó cho phép nói: Trong dataset, Sales của hai nhóm có sự khác biệt.

Nhưng chưa đủ để khẳng định: Promotion làm Sales tăng X%.

Từ quan sát đến kết luận nguyên nhân là một bước rất dài.

Con số có thể đúng, nhưng câu chuyện chúng ta gắn vào con số đó có thể sai.

7. Bẫy “JOIN đúng nhưng dữ liệu sai”

Đây là một bẫy rất thực tế khi bạn làm việc với SQL. Câu lệnh:

SELECT *
FROM sales
JOIN stores
ON …

chạy thành công. Không error.

Nhưng: SQL chạy thành công không có nghĩa dữ liệu sau JOIN là đúng.

Ví dụ bảng A có 100.000 dòng. Sau JOIN trở thành 120.000 dòng.

Nếu chúng ta không kiểm tra, các bước tiếp theo vẫn hoạt động:

  • SUM(Sales)
  • AVG(Sales)
  • COUNT(*)
  • Biểu đồ vẫn được vẽ.
  • Model vẫn có thể train.

Nhưng dữ liệu đã bị nhân dòng.

Nguyên nhân có thể là:

  • key không unique;
  • quan hệ one-to-many bị hiểu thành one-to-one;
  • JOIN sai grain;
  • bảng bên phải có duplicate;

Một nguyên tắc rất đơn giản nhưng đáng nhớ: Trước JOIN bao nhiêu dòng? Sau JOIN bao nhiêu dòng? Và tại sao?

Đây là loại lỗi rất đúng nghĩa “cái bẫy”: Chương trình không báo lỗi nhưng toàn bộ kết quả sau join có thể sai.

8. Bẫy “Có mối liên hệ → tưởng đã tìm thấy nguyên nhân”

Hai biến có correlation cao thường khiến người phân tích rất dễ kể một câu chuyện.

Ví dụ: A tăng thì B cũng tăng.  Sau đó kết luận: A làm B tăng.

Nhưng hoàn toàn có thể tồn tại biến thứ ba C tác động đến cả A và B. Ví dụ kinh điển:

  • doanh số bán kem tăng;
  • số người đi bơi cũng tăng.

Hai biến có thể có tương quan. Nhưng không phải:  ăn kem khiến con người đi bơi. Mà một yếu tố khác như thời tiết nóng có thể đồng thời làm cả hai tăng.

Trong dự án Data/AI: Correlation rất giỏi nói: “Hãy nhìn chỗ này.”

Nhưng nó không đủ để nói: “Đây là nguyên nhân.”

Có thể diễn đạt bẫy này theo đúng tinh thần “Data Speak”:

Dữ liệu đang nói “hai thứ này có liên quan”, nhưng chúng ta lại nghe thành “cái này gây ra cái kia”.

Dữ liệu không câm.  Có điều chúng ta nghe sai.

III. Nhóm bẫy Dễ Bỏ Qua

9. Bẫy “Trung bình che mất câu chuyện”

Trung bình là một chỉ số rất hữu ích. Nhưng nó cũng có khả năng che rất nhiều thông tin.

Ví dụ hai nhóm cùng có: Thu nhập trung bình = 20 triệu đồng.

Nhóm A 10 người đều có thu nhập xung quanh 20 triệu.

Nhóm B 9 người có thu nhập 5 triệu và một người có thu nhập rất cao.

Hai nhóm có thể tạo ra cùng một giá trị trung bình. Nhưng cấu trúc dữ liệu hoàn toàn khác.

Điều tương tự xảy ra với Sales: Average Sales ≈ 6.000

Nhóm A có thể tập trung quanh 6.000.

Nhóm B có thể có: rất nhiều ngày ở mức 2.000, một số ít ngày đạt 15.000 hoặc cao hơn.

Nếu chỉ nhìn mean(), chúng ta cho rằng hai nhóm tương tự nhau. Nhưng nhìn:

  • histogram;
  • median;
  • percentile;
  • boxplot;
  • skewness;

thì câu chuyện sẽ khác.

Thống kê tổng hợp là một cách nén dữ liệu. Mỗi lần nén, chúng ta có nguy cơ làm mất một phần câu chuyện.

10. Bẫy “Bỏ mất chiều thời gian”

Một dataset có cột Date nhưng nếu ta đối xử với các record như những dòng độc lập, một phần rất lớn cấu trúc của dữ liệu có thể biến mất. Dữ liệu theo thời gian có thể chứa:

  • trend;
  • seasonality;
  • chu kỳ;
  • day-of-week pattern;
  • holiday effect;
  • thay đổi trước và sau một sự kiện.

Ví dụ khác: Sales trung bình cả năm có vẻ ổn định.

Nhưng khi vẽ theo thời gian, có thể thấy: tăng mạnh → ổn định → giảm.

Hoặc:  cuối tuần luôn cao hơn ngày thường.

Hoặc: doanh số thay đổi rõ rệt trước các kỳ nghỉ.

Khi đó: Một con số tổng cho biết trạng thái. Thời gian mới cho biết câu chuyện diễn ra như thế nào.

Có thể nói: Xóa chiều thời gian không chỉ là mất một feature; đôi khi là xóa mất cốt truyện của dữ liệu.

11. Bẫy “Nhìn từng biến riêng nên không thấy quy luật kết hợp”

Đây là lý do phân tích đa biến rất quan trọng. Giả sử ta lần lượt xem:

  • Promotion → Sales
  • StoreType → Sales
  • DayOfWeek → Sales

Mỗi phân tích riêng lẻ đều có thể cho một số thông tin.

Nhưng quy luật thực sự có thể nằm ở: Promotion × StoreType × DayOfWeek → Sales

Có thể Promotion chỉ thực sự hiệu quả:

  • với một loại cửa hàng nhất định;
  • trong một số ngày nhất định;
  • hoặc khi kết hợp với một điều kiện khác.

Nếu chỉ phân tích từng feature riêng lẻ, pattern đó có thể không bao giờ xuất hiện.

Đây là một nguyên tắc quan trọng trong EDA và Feature Engineering:

Dữ liệu đôi khi không giấu quy luật trong một cột. Nó giấu quy luật trong mối quan hệ giữa nhiều cột.

IV. Bẫy đặc biệt trong AI: data leakage

12. Model học quá tốt vì chúng ta vô tình cho nó biết đáp án

Trong AI và Machine Learning có một loại bẫy đặc biệt nguy hiểm: Data Leakage.

Nó xảy ra khi model được sử dụng thông tin mà tại thời điểm dự đoán thực tế, hệ thống lẽ ra chưa thể biết. Kết quả là:

  • accuracy rất đẹp;
  • RMSE rất thấp;
  • R² rất cao;
  • model có vẻ cực kỳ tốt.

Nhưng khi đưa ra thực tế, hiệu quả giảm mạnh.

Ví dụ 1: dùng thông tin của tương lai

Giả sử muốn dự báo Sales của ngày mai. Ta sử dụng số Customers của chính ngày mai làm feature.

Vấn đề là: Tại thời điểm dự báo, chúng ta đã biết số khách của ngày mai chưa?

Nếu chưa thì feature đó không hợp lệ. Vì model đang được cung cấp thông tin mà hệ thống thực tế không có.

Ví dụ 2: Rolling feature bị “nhìn trước”

Giả sử tạo: avg_sales_last_7 để dự báo Sales ngày D.

Nếu cách tính rolling không cẩn thận và Sales của chính ngày D được đưa vào trung bình, model đã vô tình được nhìn thấy một phần đáp án.

Nguyên tắc phải là: Dự báo ngày D thì feature lịch sử chỉ được sử dụng thông tin tồn tại trước ngày D.

Data Leakage đặc biệt nguy hiểm bởi vì nó tạo ra một nghịch lý: Model càng đẹp, chúng ta càng dễ tin rằng mọi thứ đang đúng.

Trong một số trường hợp: Điều đáng nghi nhất không phải model quá tệ, mà là model tốt một cách bất thường.

Tóm tắt 12 cái bẫy dữ liệu

Có thể ghi nhớ toàn bộ bài viết bằng ba nhóm chính.

Dễ sót – Không nghe thấy

  1. Không thấy = không có
  2. Số đông che tiếng nhóm nhỏ
  3. Cái bất thường bị coi là rác

Nhóm Dễ nhầm – Nghe sai

  • Cùng giá trị nhưng khác ý nghĩa
  • Khác hình thức nhưng cùng ý nghĩa
  • Con số đúng nhưng sai ngữ cảnh
  • JOIN đúng nhưng dữ liệu sai
  • Có mối liên hệ nhưng tưởng đã tìm thấy nguyên nhân

Dễ bỏ qua – Chưa nghe hết

  • Trung bình che mất câu chuyện
  • Bỏ mất chiều thời gian
  • Nhìn từng biến riêng nên không thấy quy luật kết hợp

Bẫy đặc biệt trong AI

  1. Data Leakage – model vô tình nhìn thấy thông tin không nên biết.

Vì sao những cái bẫy này làm dữ liệu bị “câm”?

Điểm chung của cả 12 trường hợp không phải là: dữ liệu không tồn tại. Mà là:

  • Dễ sót: Dữ liệu có điều muốn nói nhưng: chúng ta không nghe thấy.
  • Dễ nhầm : Dữ liệu nói một điều nhưng: chúng ta nghe thành điều khác.
  • Dễ bỏ qua:  Chúng ta đã nghe lớp đầu tiên nhưng: chưa nghe hết câu chuyện.

Đó là lúc dữ liệu trở nên “câm”.

Không phải vì nó không chứa thông tin, mà bởi người làm dữ liệu chưa đặt nó dưới đúng góc nhìn.

Code chạy đúng chưa chắc dự án Data đã đúng

Đây có lẽ là điều quan trọng nhất mà sinh viên Data và AI nên nhớ. Một dự án có thể:

  • không có exception;
  • SQL chạy hết;
  • notebook chạy từ đầu đến cuối;
  • chart nhìn rất chuyên nghiệp;
  • model có metric tốt;

nhưng vẫn có thể tồn tại những vấn đề nghiêm trọng về cách hiểu dữ liệu.

Vì vậy chất lượng của một dự án Data không nên chỉ được đánh giá bằng câu: “Code có chạy không?”

  1. Mà phải hỏi thêm: Dữ liệu đã đủ chưa?
  2. Các giá trị thực sự có nghĩa gì?
  3. Grain của dữ liệu là gì?
  4. JOIN có giữ đúng dữ liệu không?
  5. Có nhóm nhỏ nào đang bị che không?
  6. Có bất thường nào đáng điều tra không?
  7. Có pattern theo thời gian không?
  8. Có mối quan hệ đa biến nào bị bỏ qua không?
  9. Model có đang nhìn thấy thông tin của tương lai không?

Đó mới là lúc người làm Data bắt đầu đi từ xử lý dữ liệu sang hiểu dữ liệu.

Kết luận

Những cái bẫy dữ liệu khi làm dự án data nguy hiểm không phải vì chúng luôn làm hệ thống báo lỗi, mà chính vì nhiều khi chúng âm thầm tồn tại trong một dự án tưởng như đang hoạt động rất tốt.

  • Code vẫn chạy nhưng ta có thể bỏ sót dữ liệu.
  • Biểu đồ vẫn đẹp nhưng ta có thể hiểu sai ngữ cảnh.
  • Giá trị trung bình vẫn đúng nhưng một nhóm quan trọng có thể đang bị che mất.

Model vẫn đạt metric cao nhưng có thể đang bị Data Leakage.

Vì vậy, làm Data không chỉ là đọc dữ liệu – làm sạch – vẽ biểu đồ – train model.

Quan trọng hơn là phải nhận ra: Dữ liệu có thể đang nói rất nhiều điều, nhưng người phân tích phải biết cách để nghe thấy, nghe đúng và nghe đủ.

Đó cũng chính là bước đầu tiên để biến một dataset từ những dòng và cột đơn thuần thành thông tin, quy luật và insight thực sự có giá trị.