DHDataHọc
Lý thuyếtBài 1/85 phút đọc+10 XP

Hồ sơ dữ liệu

Bạn sẽ học được

  • Vì sao phải hồ sơ dữ liệu trước khi phân tích.
  • Các chỉ số hồ sơ cho từng cột: số dòng, NULL, distinct, khoảng giá trị.
  • Viết truy vấn hồ sơ bằng SQL.
  • Vẽ histogram nhanh để thấy hình dạng dữ liệu.
  • Ghi lại phát hiện để người khác kiểm chứng.

Khái niệm cốt lõi

Hồ sơ dữ liệu (data profiling) là bước đo đạc trước khi tin dữ liệu. Không hồ sơ, mọi phân tích đứng trên giả định chưa kiểm tra: cột này không có NULL, mã thành phố chỉ có 5 giá trị, ngày tháng đúng định dạng.

Bốn câu hỏi cho mỗi cột:

  1. Có bao nhiêu giá trị? Số dòng, số giá trị khác nhau.
  2. Có bao nhiêu thiếu? Tỷ lệ NULL và chuỗi rỗng.
  3. Giá trị nằm trong khoảng nào? Min, max, phân vị.
  4. Có hình dạng gì? Phân phối, giá trị xuất hiện nhiều bất thường.

Hồ sơ cơ bản

Với mỗi bảng, chạy một truy vấn tổng quan:

code
SELECT
  COUNT(*) AS so_dong,
  COUNT(*) FILTER (WHERE name IS NULL) AS name_null,
  COUNT(*) FILTER (WHERE email IS NULL) AS email_null,
  COUNT(DISTINCT city) AS so_thanh_pho,
  COUNT(DISTINCT lower(trim(city))) AS so_thanh_pho_chuan,
  MIN(signup_date) AS ngay_som_nhat,
  MAX(signup_date) AS ngay_muon_nhat
FROM customers;

Hai con số so_thanh_pho và so_thanh_pho_chuan lệch nhau là dấu hiệu đầu tiên của dữ liệu bẩn: cùng một thành phố được nhập nhiều kiểu.

Với bảng lớn, dùng mẫu để hồ sơ nhanh trước:

code
SELECT * FROM orders TABLESAMPLE SYSTEM (5);

Mẫu 5% đủ để thấy vấn đề lớn, nhưng không dùng mẫu để kết luận tổng số.

Tỷ lệ NULL và giá trị "giả"

NULL không phải cách duy nhất để biểu diễn thiếu. Trong dữ liệu thật thường gặp:

  • Chuỗi rỗng '' hoặc toàn khoảng trắng ' '.
  • Chuỗi 'N/A', 'NULL', '-', 'unknown', '0'.
  • Ngày giả 1900-01-01, 1970-01-01.
  • ID giả 0, -1.

Đếm riêng từng loại:

code
SELECT
  COUNT(*) FILTER (WHERE email IS NULL) AS null_that,
  COUNT(*) FILTER (WHERE trim(email) = '') AS rong,
  COUNT(*) FILTER (WHERE lower(trim(email)) IN ('n/a', 'na', 'null', '-')) AS gia_tri_gia
FROM customers;

Nếu chỉ đếm IS NULL, tỷ lệ thiếu sẽ bị báo thấp hơn thực tế.

Khoảng giá trị và phân vị

Min/max bắt được lỗi rõ ràng: tuổi 200, giá âm, doanh thu 10 tỷ cho một đơn lẻ. Nhưng min/max bỏ qua giá trị sai nằm trong khoảng hợp lệ. Thêm phân vị:

code
SELECT
  percentile_cont(0.01) WITHIN GROUP (ORDER BY quantity) AS p01,
  percentile_cont(0.50) WITHIN GROUP (ORDER BY quantity) AS p50,
  percentile_cont(0.99) WITHIN GROUP (ORDER BY quantity) AS p99,
  MAX(quantity) AS max
FROM order_items;

Lệch lớn giữa P99 và max là dấu hiệu đuôi dài hoặc ngoại lai. Ví dụ P99 = 10 nhưng max = 10.000 — cần xem xét từng dòng max.

Histogram nhanh

Không cần công cụ ngoài; chia khoảng và đếm:

code
SELECT
  width_bucket(price, 0, 2000000, 10) AS khoang,
  COUNT(*) AS so_dong
FROM products
GROUP BY 1
ORDER BY 1;

Với dữ liệu phân loại, đếm trực tiếp:

code
SELECT status, COUNT(*) AS n
FROM orders
GROUP BY 1
ORDER BY 2 DESC;

Histogram cho thấy phân phối lệch, khoảng trống, và cụm giá trị bất thường (ví dụ nhiều dòng đúng bằng 0).

Kiểm tra tính duy nhất

Khóa chính không có nghĩa là không có trùng lặp nghiệp vụ:

code
SELECT email, COUNT(*) AS n
FROM customers
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY n DESC;

Kiểm tra cả khóa tổng hợp:

code
SELECT customer_id, order_date, COUNT(*) AS n
FROM orders
GROUP BY 1, 2
HAVING COUNT(*) > 1;

Hai đơn cùng khách cùng ngày có thể hợp lệ (đặt hai lần), nhưng nếu mỗi khách thường chỉ đặt một lần mỗi ngày thì cần xem lại.

Ghi lại phát hiện

Hồ sơ chỉ có giá trị khi được ghi lại. Một bảng ngắn:

CộtVấn đềTỷ lệHành động
city12 biến thể cho 5 thành phố8% dòngChuẩn hoá, map
email3% NULL, 1% chuỗi rỗng4%Đánh dấu không liên lạc được
price2 dòng âm0,1%Xem gốc, sửa
order_date1.200 dòng là text sai định dạng2%Parse, gắn cờ lỗi

Bảng này là đầu vào cho bước làm sạch; không có nó, việc làm sạch dựa trên phỏng đoán.

Thực hành

  1. Viết truy vấn hồ sơ cho bảng products.
  2. Đếm NULL thật và giá trị giả cho cột email.
  3. Tính P01, P50, P99 của quantity trong order_items.
  4. Vẽ histogram giá sản phẩm theo 10 khoảng.
  5. Tìm các cặp (customer_id, order_date) trùng.

Lỗi thường gặp

Triệu chứngNguyên nhânCách sửa
Phân tích sai từ đầuBỏ qua hồ sơChạy hồ sơ trước mọi việc
Tỷ lệ thiếu thấp bất thườngChỉ đếm NULLĐếm cả chuỗi rỗng, giá trị giả
Bỏ sót ngoại laiChỉ xem min/maxThêm phân vị và histogram
Không thấy trùng lặpChỉ kiểm tra khóa chínhKiểm tra khóa nghiệp vụ
Không tái lập đượcKhông ghi lạiGhi bảng phát hiện
Chậm với bảng lớnQuét toàn bảngDùng mẫu để hồ sơ nhanh

Tóm tắt

  • Hồ sơ dữ liệu là bước bắt buộc trước phân tích.
  • Đo số dòng, NULL thật và giả, distinct, phân vị, histogram.
  • Kiểm tra duy nhất theo khóa nghiệp vụ, không chỉ khóa chính.
  • Ghi lại phát hiện thành bảng có tỷ lệ và hành động.
  • Dùng mẫu để hồ sơ nhanh, nhưng kết luận trên toàn bộ dữ liệu.

Dùng ← → để chuyển bài