Graph 6 — Phát hiện gian lận & AML bằng đồ thị

13 thg 7, 2026 2 lượt xem
#fraud
#sql
#aml
#graph-database
#neo4j

Graph 6 — Phát hiện gian lận & AML bằng đồ thị

Đây là bài ứng dụng có giá trị cao nhất của cả series. Ở bài thuật toán GDS ta có công cụ; bài này cho biết chĩa chúng vào đâu. Luận điểm trung tâm: gian lận và rửa tiền (AML — Anti-Money Laundering) về bản chất là hiện tượng MẠNG LƯỚI. Một giao dịch đơn lẻ nhìn hoàn toàn bình thường — số tiền hợp lý, đúng giờ, đúng hạn mức. Cái bất thường chỉ lộ ra khi ta nhìn quan hệ giữa các thực thể: ai gửi cho ai, tiền quay về đâu, những "khách hàng khác nhau" hoá ra dùng chung một chiếc điện thoại.

Tội phạm tài chính chủ động che giấu qua nhiều lớp trung gian (layering): tiền bẩn không đi thẳng từ A tới Z mà qua B, C, D, tách ra, gộp lại để cắt đứt liên hệ với nguồn gốc. Với mô hình bảng quan hệ, truy vết ba-bốn bậc như vậy phải viết chuỗi JOIN tự thân ngày càng dài, càng sâu càng chậm — đúng vấn đề mà bài tổng quan đồ thị đã chỉ ra. Đồ thị coi quan hệ là công dân hạng nhất: đi từ node này sang node kia sâu bao nhiêu cũng được, và nhiều mẫu gian lận trở thành hình dạng nhìn thấy được.

Lưu ý: mọi block cypher trong bài là cú pháp Neo4j/Cypher (và GDS), không phải SQL Postgreskhông chạy được trên sandbox Knowledge Base. Đây là bài về mô hình mạng lưới, không có block SQL đánh dấu -- ▶ Chạy được.

Vì sao đồ thị vượt trội cho fraud/AML

Ba đặc điểm khiến bài toán này sinh ra dành cho đồ thị:

  • Gian lận là quan hệ, không phải thuộc tính. Rủi ro không nằm ở cột nào của một dòng khách hàng, mà ở vị trí của họ trong mạng: gần blacklist tới đâu, thuộc cụm dày nào, chia sẻ định danh với ai. Đây chính là ý "network structure → number → feature" mà bài GDS nhấn mạnh.
  • Che giấu qua nhiều bậc. Layering cố ý kéo dài chuỗi trung gian. Truy vấn 5-6 bậc là chuyện thường trong AML; trên đồ thị đó là một pattern [:SENT*1..6], trên SQL là sáu lần self-join.
  • Kết nối nhiều loại thực thể. Khách hàng, tài khoản, thiết bị, số điện thoại, địa chỉ, CCCD, merchant — mẫu gian lận thường bắc cầu qua nhiều loại node. Đồ thị dị chất (heterogeneous) biểu diễn tự nhiên; bảng thì mỗi loại một schema, ghép lại rất cồng kềnh.

Data model điển hình (xem bài data model) gồm các node Customer, Account, Device, Phone, Address, Identity (CCCD), Merchant, và các cạnh SENT {amount, txnAt}, OWNS, USED_DEVICE, HAS_PHONE, HAS_ADDRESS, SAME_ID. Toàn bộ typology dưới đây chạy trên mô hình này.

Typology 1 — Mạng tài khoản mule (fan-in / fan-out)

Money mule là tài khoản trung gian nhận rồi chuyển tiền hộ — thường là tài khoản thật của người bị dụ hoặc tài khoản mở bằng giấy tờ giả. Mẫu kinh điển:

  • Fan-in (gom tiền): nhiều tài khoản cùng gửi tiền về một điểm trong khoảng thời gian ngắn — dấu hiệu điểm tập kết (collector). In-degree cao bất thường.
  • Fan-out (phân tán): một tài khoản nhận cục tiền lớn rồi xé nhỏ gửi ra nhiều tài khoản — dấu hiệu phân phối/tẩu tán. Out-degree cao bất thường.

Trên đồ thị, đây là hình ngôi sao (star): tâm là mule, cánh là các đối tác. Cypher đếm bậc trong cửa sổ thời gian:

// Fan-in: tài khoản nhận tiền từ >= 8 nguồn khác nhau trong 24 giờ
MATCH (src:Account)-[s:SENT]->(hub:Account)
WHERE s.txnAt >= datetime() - duration('P1D')
WITH hub, count(DISTINCT src) AS soNguon, sum(s.amount) AS tongVao
WHERE soNguon >= 8
RETURN hub.accountNo, soNguon, tongVao
ORDER BY tongVao DESC

Điểm mạnh của đồ thị là ghép fan-in fan-out thành chuỗi mule (mule chain): tiền vào tâm rồi ra ngay lập tức, hầu như không đọng lại. Đó mới là chân dung mule thực sự — khác với một tài khoản lương chỉ nhận tiền:

// Mule chain: nhận từ nhiều nguồn RỒI đẩy ra nhiều đích, đọng lại rất ít
MATCH (in:Account)-[si:SENT]->(m:Account)-[so:SENT]->(out:Account)
WHERE si.txnAt >= datetime() - duration('P7D')
  AND so.txnAt >= si.txnAt AND so.txnAt <= si.txnAt + duration('PT48H')
WITH m,
     count(DISTINCT in) AS nguon, count(DISTINCT out) AS dich,
     sum(si.amount) AS vao, sum(so.amount) AS ra
WHERE nguon >= 5 AND dich >= 5 AND ra >= 0.9 * vao   // ~90% tiền chảy tiếp
RETURN m.accountNo, nguon, dich, vao, ra
ORDER BY vao DESC

Gắn thuật toán từ bài GDS: Degree Centrality để xếp hạng nhanh in/out-degree toàn mạng; PageRank để tìm điểm gom tiền có ảnh hưởng (nhận từ nhiều nguồn quan trọng), không chỉ nhiều nguồn.

Typology 2 — Vòng rửa tiền (cycle detection)

Rửa tiền thường tạo chu trình: tiền rời tài khoản nguồn, đi qua chuỗi trung gian, rồi quay về chính nguồn (hoặc một tài khoản do cùng người kiểm soát) — trông như "doanh thu hợp pháp" đã được rửa sạch nguồn gốc. Trên đồ thị SENT, đây là một cycle: đường đi đóng kín về điểm xuất phát.

Cypher tìm vòng có độ dài tới 6 bậc quay về nguồn:

// Vòng dòng tiền: A -> ... -> A, độ dài 3..6, mỗi bước tiền lớn
MATCH path = (a:Account)-[:SENT*3..6]->(a)
WHERE ALL(r IN relationships(path) WHERE r.amount >= 50000000)
WITH a, path,
     reduce(s = 0.0, r IN relationships(path) | s + r.amount) AS tongVong,
     length(path) AS soBuoc
RETURN a.accountNo, soBuoc, tongVong
ORDER BY tongVong DESC
LIMIT 50

Trên đồ thị lớn, tìm vòng bằng pattern thuần có thể tốn kém (bùng nổ tổ hợp), nên thực chiến hay dùng Strongly Connected Components (SCC) trong GDS trước để thu hẹp: một SCC nghĩa là các node đều tới được nhau theo đúng hướng cạnh — điều kiện cần để có vòng. Chỉ những tài khoản nằm trong SCC ≥ 3 thành viên mới đáng chạy pattern cycle chi tiết. Đây đúng chiến lược "sàng thô bằng thuật toán, soi kỹ bằng Cypher".

Typology 3 — Smurfing / structuring

Structuring (ở dạng chia người thực hiện gọi là smurfing) là chia một khoản lớn thành nhiều khoản nhỏ dưới ngưỡng báo cáo để né giám sát. Ở Việt Nam, giao dịch tiền mặt hoặc chuyển khoản từ một mức nhất định phải báo cáo; kẻ gian giữ mỗi lần ngay dưới ngưỡng đó. Trên đồ thị: nhiều node (hoặc nhiều lần) gửi các khoản na ná nhau, sát-nhưng-dưới ngưỡng, hội tụ về một node trong thời gian ngắn.

// Structuring: nhiều khoản 'ngay dưới ngưỡng' đổ về một tài khoản trong 3 ngày
WITH 500000000 AS nguong     // ngưỡng báo cáo (minh hoạ)
MATCH (src:Account)-[s:SENT]->(hub:Account)
WHERE s.txnAt >= datetime() - duration('P3D')
  AND s.amount >= 0.8 * nguong AND s.amount < nguong    // 80%..<100% ngưỡng
WITH hub, nguong, count(s) AS soLan, sum(s.amount) AS tong,
     count(DISTINCT src) AS soNguon
WHERE soLan >= 6 AND tong >= nguong        // gộp lại thì vượt xa ngưỡng
RETURN hub.accountNo, soLan, soNguon, tong
ORDER BY tong DESC

Tín hiệu cốt lõi: tổng gộp vượt ngưỡng nhưng từng lần đều dưới ngưỡng — không một giao dịch đơn lẻ nào bị luật báo cáo bắt, nhưng nhìn tổng thể mạng thì lộ rõ ý đồ. Đây là ví dụ điển hình vì sao truy vấn một dòng một (row-by-row) bỏ sót, còn nhìn cụm quan hệ thì thấy.

Typology 4 — Chia sẻ định danh đáng ngờ (shared identity)

Mẫu mạnh và thực dụng nhất trong thực tế. Nhiều "khách hàng khác nhau" nhưng dùng chung số điện thoại / địa chỉ / thiết bị / CCCD → nhiều khả năng là thực thể giả (synthetic identity) hoặc một người điều khiển nhiều tài khoản mượn. Đồ thị dị chất tỏ sáng ở đây: chỉ cần đi từ Customer qua node định danh và quay lại các Customer khác.

// Nhiều khách chung 1 thiết bị: cụm định danh đáng ngờ
MATCH (c1:Customer)-[:USED_DEVICE]->(d:Device)<-[:USED_DEVICE]-(c2:Customer)
WHERE c1 <> c2
WITH d, collect(DISTINCT c1.id) + collect(DISTINCT c2.id) AS khach
WITH d, size(apoc.coll.toSet(khach)) AS soKhach
WHERE soKhach >= 4                      // 1 thiết bị, >= 4 khách khác nhau
RETURN d.deviceId, soKhach
ORDER BY soKhach DESC

Kết hợp nhiều loại định danh làm tín hiệu mạnh hơn: hai khách chung cả điện thoại lẫn địa chỉ lẫn thiết bị thì gần như chắc chắn là cùng thực thể. Đây là cửa ngõ tự nhiên sang entity resolution (mục dưới).

Typology 5 — Đường tiền tới thực thể rủi ro / blacklist

Câu hỏi tuân thủ (compliance) kinh điển: "Tài khoản này có dính, dù gián tiếp, tới một thực thể trong danh sách đen (sanction/blacklist) không?" — và gián tiếp qua bao nhiêu bậc. Layering sinh ra chính để đẩy khoảng cách này ra xa cho khó thấy. Đồ thị trả lời bằng shortest path:

// Khoảng cách dòng tiền ngắn nhất từ tài khoản nghi vấn tới bất kỳ node blacklist
MATCH (susp:Account {accountNo: $tk})
MATCH (bad:Account) WHERE bad.blacklisted = true
MATCH p = shortestPath( (susp)-[:SENT*1..6]->(bad) )
RETURN bad.accountNo AS toiThucTheXau,
       length(p) AS soBac,
       [n IN nodes(p) | n.accountNo] AS duongTien
ORDER BY soBac ASC
LIMIT 10

Số bậc tới blacklist gần nhất là một feature rủi ro rất mạnh: càng gần càng đáng ngờ. Với GDS, gds.shortestPath.dijkstra cho phép đặt trọng số cạnh (theo số tiền, độ trễ, phí) để tìm đường tiền khả dĩ nhất thay vì chỉ ngắn nhất về số bước. Đây là điểm nối trực tiếp với giám sát giao dịch AML và khung tổng quan ở AML overview.

Kết hợp thuật toán GDS: soi cùng một mạng nhiều góc

Các typology trên là pattern; thuật toán GDS cho cấu trúc toàn cục. Thực chiến luôn dùng cả hai, bổ trợ nhau:

Thuật toánVai trò trong fraud/AMLTypology liên quan
Community Detection (Louvain)Khoanh fraud ring — cụm tài khoản dính chặt bất thườngVòng rửa tiền, mule network
SCCSàng nhanh ứng viên có vòng dòng tiềnCycle detection
BetweennessTìm trung gian/layering — node nằm trên nhiều luồngMule chain
shortestPath / DijkstraTruy vết đường tiền tới blacklist / giữa hai điểmĐường tới thực thể rủi ro
Degree / PageRankXếp hạng điểm gom/phát tiềnFan-in / fan-out

Ví dụ Louvain gán mỗi tài khoản một communityId; sau đó một truy vấn Cypher thường lọc cộng đồng nào có tỷ lệ tài khoản gắn cờ cao và dòng tiền nội bộ lớn — biến "cụm đáng ngờ" thành một bộ lọc chạy được. Đó là fraud ring cần điều tra viên vào cuộc.

Entity resolution bằng đồ thị

Trước khi phát hiện gian lận, thường phải hợp nhất thực thể: nhiều bản ghi khách hàng thực ra là một người. Đồ thị làm việc này rất tự nhiên bằng Connected Components (WCC): nối các Customer chia sẻ định danh mạnh (cùng CCCD, cùng thiết bị + điện thoại) bằng cạnh SAME_ID, rồi mỗi component liên thông chính là một thực thể gộp (resolved entity). Sau khi gộp, mạng phản ánh đúng "một người điều khiển 12 tài khoản" thay vì "12 khách hàng độc lập" — làm mọi typology phía trên chính xác hơn nhiều, và tránh false negative khi kẻ gian núp sau danh tính rời rạc.

Feature đồ thị làm đầu vào cho mô hình ML

Đỉnh cao của cách tiếp cận: đồ thị không thay thế mô hình chấm điểm rủi ro, mà nuôi feature cho nó. Mỗi tài khoản/khách hàng được gắn thêm các graph feature, đứng cạnh feature bảng truyền thống (tuổi tài khoản, số dư, thu nhập, lịch sử tín dụng):

  • Số bậc (degree) in/out trong cửa sổ thời gian — cường độ gom/phát.
  • Kích thước cộng đồng (community size)tỷ lệ node gắn cờ trong cộng đồng — độ "bẩn" của hàng xóm.
  • Khoảng cách tới blacklist gần nhất — số bậc shortest path tới thực thể xấu.
  • Betweenness / PageRank score — vai trò cầu nối, mức ảnh hưởng dòng tiền.
  • Graph embedding (FastRP/node2vec) — nén toàn bộ vị trí mạng thành vector, đưa thẳng vào XGBoost/logistic regression.

Chuỗi feature này xuất ra feature store rồi hoà vào mô hình chấm điểm — nối liền với MLOps/triển khai và tinh thần scorecard ở chấm điểm rủi ro tín dụng. Kết quả thực nghiệm phổ biến: thêm graph feature thường nâng khả năng bắt gian lận so với chỉ dùng feature phẳng, vì mạng mang thông tin mà từng dòng riêng lẻ không có.

Sơ đồ: mule network, vòng rửa tiền và chia sẻ định danh

Đọc sơ đồ: M nhận từ ba nguồn (fan-in) rồi bơm vào cụm A-B-C — cụm này là SCC (A→B→C→A, vòng rửa tiền). Từ Cđường tiền tới node Blacklist, chỉ vài bậc. Bên dưới, ba "khách hàng" cùng dùng một thiết bị (shared identity) và thiết bị đó lại nối tới chính M. Một mạng — bốn tín hiệu chồng lên nhau: mule fan-in, vòng SCC, đường tới blacklist, và định danh giả. Đây chính là lý do đồ thị mạnh: các mẫu cộng hưởng trên cùng một cấu trúc, điều mà truy vấn bảng rời rạc rất khó ghép lại.

Cảnh báo: false positive và vai trò điều tra viên

Không typology nào là bằng chứng phạm tội — chúng là tín hiệu để điều tra. Fan-in cao có thể là tài khoản thu hộ hợp pháp; vòng dòng tiền có thể là dòng vốn nội bộ doanh nghiệp; chung địa chỉ có thể là người trong một gia đình. Vì vậy:

  • Hệ thống đồ thị sinh cảnh báo có xếp hạng rủi ro, không tự kết luận. Cân ngưỡng: chặt → sót (false negative); lỏng → ngập cảnh báo rác (false positive), làm kiệt sức đội điều tra.
  • Điều tra viên (investigator/SAR analyst) ra quyết định cuối, xem xét bối cảnh nghiệp vụ trước khi lập báo cáo giao dịch đáng ngờ (SAR). Đồ thị thu hẹp không gian tìm kiếm và trực quan hoá liên hệ, chứ không thay họ.
  • Kết hợp graph feature vào mô hình ML giúp hạ false positive: thay vì luật cứng "in-degree ≥ 8 → cảnh báo", mô hình cân nhiều feature cùng lúc nên chọn lọc hơn.

Use case thực tế

Bối cảnh. Đội AML của NCB nhận từ hệ thống giám sát giao dịch một cảnh báo: một tài khoản mở mới có dòng tiền vào-ra bất thường, nghi là mule. Cần trả lời: (a) nó thuộc mạng lưới nào, (b) tiền có quay vòng hay chạm blacklist không, (c) rủi ro tổng hợp bao nhiêu để quyết định lập SAR. Dữ liệu (:Account)-[:SENT {amount, txnAt}] cùng node định danh đã có trong Neo4j.

Bước 1 — Entity resolution. Chạy WCC trên các cạnh SAME_ID (chung CCCD/thiết bị+điện thoại). Tài khoản nghi vấn hoá ra thuộc một thực thể gộp gồm 4 tài khoản đứng tên 3 "khách hàng" khác nhau nhưng chung một thiết bị (số minh hoạ).

Bước 2 — Khoanh cụm bằng Louvain. Chiếu đồ thị SENT 90 ngày, chạy Louvain. Thực thể gộp nằm trong một cộng đồng 17 tài khoản, trong đó tỷ lệ tài khoản đã-gắn-cờ cao gấp ~6 lần nền chung — ứng viên fraud ring.

Bước 3 — Tìm vòng và trung gian. Chạy SCC trên cộng đồng đó: phát hiện một chu trình 5 tài khoản luân chuyển ~1,8 tỷ VND vòng tròn trong 2 tuần. Betweenness chỉ ra 2 tài khoản cầu nối điểm cao bất thường — mule điều phối.

Bước 4 — Đường tới blacklist. shortestPath cho thấy từ một node trong vòng có đường tiền 3 bậc tới một tài khoản trong danh sách sanction nội bộ. Đây là tín hiệu nặng nhất.

Bước 5 — Chấm điểm & chuyển điều tra viên. Gắn các feature (degree, community-flag-ratio, betweenness, khoảng cách-tới-blacklist, embedding FastRP) vào mô hình chấm điểm mule. Điểm rủi ro của thực thể gộp vào nhóm cao nhất → hồ sơ kèm sơ đồ mạng chuyển cho điều tra viên. Từ một cảnh báo mơ hồ, quy trình khoanh được nguyên một mạng lưới trong vài phút chạy GDS — nhưng quyết định lập SAR vẫn do người.

Ghi nhớ

  • Gian lận/AML là hiện tượng MẠNG LƯỚI. Giao dịch đơn lẻ nhìn bình thường; bất thường chỉ lộ khi nhìn quan hệ. Tội phạm cố che qua nhiều lớp trung gian (layering) — địa hạt tự nhiên của đồ thị.
  • Typology cốt lõi: (1) mule fan-in/fan-out (ngôi sao gom/phát tiền, mule chain), (2) vòng rửa tiền (cycle → tiền quay về nguồn; sàng bằng SCC), (3) smurfing/structuring (nhiều khoản dưới ngưỡng, gộp lại vượt), (4) chia sẻ định danh (nhiều khách chung SĐT/thiết bị/CCCD → thực thể giả), (5) đường tiền tới blacklist (shortest path, số bậc là feature rủi ro).
  • Kết hợp thuật toán GDS: Louvain khoanh fraud ring, SCC bắt vòng, Betweenness tìm trung gian, shortestPath truy vết, Degree/PageRank xếp hạng gom tiền. Sàng thô bằng thuật toán, soi kỹ bằng Cypher.
  • Entity resolution bằng WCC trên cạnh định danh: gộp nhiều bản ghi thành một thực thể thật, làm mọi typology chính xác hơn và tránh false negative.
  • Graph feature cho ML: số bậc, community size + tỷ lệ gắn cờ, khoảng cách tới blacklist, betweenness/PageRank, embedding — đứng cạnh feature bảng, nâng khả năng bắt gian lận vì mang thông tin mạng.
  • Cảnh báo là tín hiệu, không phải kết luận. Cân ngưỡng để tránh ngập false positive; điều tra viên ra quyết định SAR cuối cùng. Liên hệ aml-03 giám sát giao dịchaml-01 tổng quan.

Bài viết liên quan

Cách index hoạt động (B-Tree), đọc EXPLAIN, seq scan vs index scan và mẫu tối ưu truy vấn.

13 thg 7, 2026 4

Khoá, ràng buộc, quan hệ và chuẩn hoá 1NF/2NF/3NF — thiết kế lược đồ đúng từ đầu.

13 thg 7, 2026 4

Kết nhiều bảng đúng cách: các loại JOIN, bẫy thường gặp và phép hợp tập.

13 thg 7, 2026 3

Truy vấn lồng, CTE (WITH), CTE đệ quy và hàm cửa sổ — vũ khí cho phân tích nâng cao.

13 thg 7, 2026 3