GIS 6 — Phân tích không gian nâng cao
GIS 6 — Phân tích không gian nâng cao
Ở bài truy vấn không gian ta đã biết cách nối và lọc dữ liệu theo vị trí: giao dịch nằm ở quận nào, chi nhánh nào gần khách nhất, bao nhiêu khách trong bán kính 5km. Đó mới là bước "hỏi đáp". Bài này bước sang phân tích không gian (spatial analysis) — dùng vị trí để ra quyết định kinh doanh: đặt ATM ở đâu, mở PGD (phòng giao dịch) tại quận nào, thị trường nào đang bị bỏ trống, danh mục tín dụng có đang dồn cục về một địa bàn rủi ro hay không.
Khác biệt cốt lõi: truy vấn trả lời "cái gì ở đâu", phân tích trả lời "nên làm gì". Và câu trả lời phải quy đổi được ra tiền: một ATM đặt sai chỗ tốn vài trăm triệu chi phí vận hành/năm mà giao dịch thấp; một PGD mở đúng vùng trắng có thể thu hút hàng nghìn khách mới.
Lưu ý sandbox: PostGIS không được cài trên sandbox Knowledge Base (chỉ có PostgreSQL read-only chuẩn). Do đó mọi block SQL không gian (
ST_ClusterDBSCAN,ST_ClusterKMeans...) trong bài là MINH HOẠ — cú pháp PostGIS thật nhưng không đánh dấu-- ▶ Chạy được. Chỉ có một câu non-spatial gộp theocitytrên schema thật ở cuối là chạy được, làm phép loại suy cho ý "xếp hạng địa bàn để mở rộng".
Phân tích mật độ & gom cụm
Hotspot — điểm nóng
Câu hỏi kinh doanh đầu tiên luôn là: khách hàng / giao dịch của tôi tập trung ở đâu? Một bản đồ rải điểm (dot map) hàng chục nghìn điểm chỉ thành một vệt đen vô nghĩa. Ta cần tổng hợp mật độ.
Có hai cách:
- Binning (gộp lưới): chia không gian thành ô vuông hoặc lục giác (hexbin) đều nhau, đếm số điểm mỗi ô. Đơn giản, nhanh, dễ giải thích. PostGIS có
ST_SquareGrid/ST_HexagonGridsinh lưới rồi spatial join đếm. - Kernel Density (KDE — ước lượng mật độ hạt nhân): thay vì đếm cứng theo ô, mỗi điểm "toả" một vùng ảnh hưởng mờ dần theo khoảng cách, cộng chồng lên nhau thành một bề mặt mật độ liên tục (heatmap). Mượt hơn binning, không lệ thuộc ranh giới ô, nhưng cần chọn bandwidth (bán kính toả) hợp lý — quá nhỏ thì lỗ chỗ, quá lớn thì bết hết. KDE thường tính ở tầng GIS/Python (rasterio, scipy), PostGIS làm binning là chính.
Hotspot là các ô/vùng có mật độ cao vượt trội — nơi giao dịch ATM dày đặc, nơi khách VIP tụ về, nơi phát sinh nhiều đơn tín dụng. Đó là ứng viên đầu tiên để cân nhắc tăng năng lực phục vụ (thêm ATM, nâng hạn mức tiền mặt) hoặc để cảnh báo (điểm nóng giao dịch bất thường — xem thêm giám sát giao dịch AML).
Gom cụm không gian (spatial clustering)
Hotspot cho biết "vùng nào nóng", nhưng đôi khi ta cần nhóm các điểm rời rạc thành cụm có ý nghĩa: nhóm khách theo khu dân cư để phân tuyến sales, nhóm ATM theo địa bàn để chia đội bảo trì, phát hiện chùm giao dịch đáng ngờ dồn về một khu.
PostGIS cung cấp hai thuật toán gom cụm ngay trong SQL, chạy như window function:
ST_ClusterDBSCAN — gom cụm theo mật độ. Hai tham số:
eps: bán kính lân cận (đơn vị theo SRID; nếu là mét thì dùng geometry đã chiếu về hệ mét như UTM 32648).minpoints: số điểm tối thiểu để tạo thành cụm.
DBSCAN có ưu điểm lớn: tự phát hiện số cụm, cụm có hình dạng bất kỳ (không ép tròn), và tự đánh dấu nhiễu (điểm lẻ loi không thuộc cụm nào → cluster_id = NULL). Rất hợp với dữ liệu thực có điểm rác.
-- MINH HOẠ PostGIS (KHÔNG chạy trên sandbox)
-- Gom cụm vị trí khách trong bán kính 300m, cụm >= 20 khách.
-- geom_utm là geometry đã chiếu về hệ mét (SRID 32648) để eps tính bằng mét.
SELECT
customer_id,
ST_ClusterDBSCAN(geom_utm, eps := 300, minpoints := 20)
OVER () AS cluster_id
FROM cust_geo_utm;
Gộp thêm một tầng để mô tả từng cụm — tâm cụm, số khách, phạm vi:
-- MINH HOẠ PostGIS (KHÔNG chạy trên sandbox)
WITH clustered AS (
SELECT
customer_id,
geom_utm,
ST_ClusterDBSCAN(geom_utm, eps := 300, minpoints := 20) OVER () AS cid
FROM cust_geo_utm
)
SELECT
cid,
COUNT(*) AS so_khach,
ST_Centroid(ST_Collect(geom_utm)) AS tam_cum,
ST_ConvexHull(ST_Collect(geom_utm)) AS ranh_cum
FROM clustered
WHERE cid IS NOT NULL -- bỏ điểm nhiễu
GROUP BY cid
ORDER BY so_khach DESC;
ST_ClusterKMeans — gom cụm theo số cụm định trước k. Chia các điểm thành đúng k nhóm sao cho tổng khoảng cách tới tâm nhóm nhỏ nhất. Hợp khi bạn đã biết muốn bao nhiêu nhóm — ví dụ "chia khách toàn thành phố thành 8 vùng để giao cho 8 đội chăm sóc", hoặc "gom ATM thành 5 tuyến tiếp quỹ".
| Tiêu chí | ST_ClusterDBSCAN | ST_ClusterKMeans |
|---|---|---|
| Số cụm | Tự phát hiện | Phải định trước k |
| Hình cụm | Bất kỳ | Xu hướng tròn/lồi |
| Điểm nhiễu | Đánh dấu NULL | Ép vào cụm gần nhất |
| Tham số chính | eps, minpoints | k |
| Hợp cho | Phát hiện tụ điểm tự nhiên, lọc rác | Phân vùng đều theo số đội/tuyến |
Tự tương quan không gian (spatial autocorrelation)
Một định luật nền tảng của địa lý (Tobler): "mọi thứ đều liên quan với nhau, nhưng thứ gần nhau thì liên quan nhiều hơn". Nói cách khác: gần nhau thì giống nhau. Tỷ lệ nợ xấu ở một phường thường giống các phường liền kề hơn là một phường ở đầu kia thành phố; thu nhập, mật độ khách VIP, tỷ lệ dùng thẻ tín dụng... đều có xu hướng "kết đám" theo không gian.
Chỉ số kinh điển đo hiện tượng này là Moran's I — một con số trong khoảng khoảng [-1, +1]:
- I ≈ +1: tự tương quan dương mạnh — vùng giá trị cao nằm cạnh vùng giá trị cao, vùng thấp cạnh thấp (dữ liệu "kết đám" rõ). Ví dụ: các quận nợ xấu cao dồn thành một mảng liền kề.
- I ≈ 0: phân bố ngẫu nhiên, không có cấu trúc không gian.
- I ≈ -1: tự tương quan âm — cao cạnh thấp xen kẽ như bàn cờ (hiếm gặp trong dữ liệu ngân hàng).
Ý nghĩa nghiệp vụ: nếu rủi ro tín dụng có Moran's I cao, rủi ro không rải đều mà tập trung địa lý — một cú sốc kinh tế vùng (khu công nghiệp đóng cửa, giá bất động sản một quận lao dốc) sẽ kéo cả cụm chi nhánh/khách trong vùng cùng xấu đi. Đây chính là rủi ro tập trung địa lý của danh mục, cần đưa vào mô hình chấm điểm và phân bổ hạn mức (liên hệ scorecard tín dụng). Moran's I toàn cục cho bức tranh chung; biến thể Local Moran's I (LISA) chỉ ra cụ thể cụm nào đang là điểm nóng rủi ro. Tính toán thường ở tầng phân tích (PySAL/GeoDa) chứ không trong SQL thuần.
Phân tích mạng lưới & chọn địa điểm (site selection)
Đây là bài toán "đắt tiền" nhất và cũng tạo giá trị rõ nhất: đặt ATM/chi nhánh mới ở đâu?
Vùng phục vụ (service area / catchment)
Với mỗi điểm phục vụ (ATM, PGD), ta xác định vùng phục vụ — tập khách/dân cư mà nó "chịu trách nhiệm". Cách đơn giản: gán mỗi khách về điểm gần nhất (Voronoi/Thiessen polygon — chia mặt phẳng thành các ô, mỗi ô là vùng gần một điểm nhất). Cách sát thực tế: dùng khoảng cách/thời gian đi đường (xem isochrone bên dưới).
Khoảng cách tới điểm gần nhất
Đo mức độ được phục vụ của từng khách: khách phải đi bao xa mới tới ATM gần nhất? Đây là truy vấn nearest-neighbor đã học ở bài truy vấn không gian (toán tử <-> + LATERAL). Kết quả cho phân phối khoảng cách — nếu 15% khách cách ATM gần nhất > 3km, đó là cầu chưa được đáp ứng.
Phủ & khoảng trống (coverage & gaps)
Chồng vùng phục vụ (buffer bán kính đi được) của toàn bộ điểm hiện có lên bản đồ dân cư/khách. Phần dân cư nằm ngoài mọi vùng phục vụ là khoảng trống (gap) — thị trường bị bỏ trống. Đặt điểm mới ưu tiên nơi vừa có gap vừa có mật độ khách/dân số cao.
-- MINH HOẠ PostGIS (KHÔNG chạy trên sandbox)
-- Khách nằm NGOÀI mọi vùng phủ 2km của ATM hiện hữu => cầu chưa phục vụ.
WITH phu AS (
SELECT ST_Union(ST_Buffer(geom_utm, 2000)) AS vung_phu
FROM atms_utm
)
SELECT c.customer_id, c.geom_utm
FROM cust_geo_utm c, phu
WHERE NOT ST_Intersects(c.geom_utm, phu.vung_phu);
Tối ưu vị trí
Bài toán trở thành: chọn tập vị trí mới để tối đa hoá số khách/dân số chưa phục vụ được phủ, dưới ràng buộc ngân sách. Đây là bài toán tối ưu tổ hợp (dạng maximal covering location) — không giải bằng SQL mà bằng solver tối ưu (liên hệ lập lịch & tối ưu mạng lưới). SQL/PostGIS lo phần chuẩn bị đầu vào: đo gap, đếm dân số/khách trong từng vùng ứng viên, chấm điểm.
Isochrone & khoảng cách đường đi
Cạm bẫy lớn nhất của người mới: dùng khoảng cách chim bay (Euclid, đường thẳng) để đo "gần". Thực tế khách đi theo mạng đường — có sông chắn, đường một chiều, tắc nghẽn. 500m chim bay có thể là 3km đi đường nếu bị con sông cắt ngang.
- Khoảng cách/thời gian đường đi (network distance): đo dọc theo đồ thị đường sá.
- Isochrone: vùng bao gồm mọi điểm đến được trong X phút từ một điểm gốc theo đường thật (ví dụ "vùng 10 phút xe máy quanh PGD"). Hình dạng méo mó bám theo mạng đường, khác hẳn hình tròn buffer.
Cả hai cần dữ liệu mạng đường và một engine định tuyến — phổ biến là OSRM hoặc pgRouting (extension của PostgreSQL, xem extension Postgres) trên nền dữ liệu OpenStreetMap (OSM). PostGIS thuần không tự tính đường đi; ở đây chỉ nêu khái niệm và công cụ.
Overlay nhiều lớp (multi-criteria overlay)
Không quyết định nào chỉ dựa một tiêu chí. Overlay là chồng nhiều lớp bản đồ lên nhau rồi tính điểm tổng hợp cho mỗi khu vực. Ví dụ chấm điểm sức hấp dẫn khu vực để mở PGD, mỗi khu (phường/ô lưới) được điểm từ nhiều lớp:
| Lớp | Nguồn | Chiều tác động |
|---|---|---|
| Mật độ dân số | Điều tra dân số / GADM | Cao → tốt |
| Thu nhập bình quân | Khảo sát / proxy | Cao → tốt |
| Khách hiện hữu chưa phục vụ tốt | Nội bộ | Cao → tốt |
| Mật độ đối thủ (chi nhánh bank khác) | POI/OSM | Cao → xấu (cạnh tranh) |
| Khoảng cách tới PGD của chính mình | Nội bộ | Xa → tốt (tránh tự ăn) |
Chuẩn hoá từng lớp về thang 0–1, gán trọng số theo chiến lược, cộng lại thành điểm sức hấp dẫn. Đây chính là phân vùng thị trường: xếp hạng mọi khu để biết mở ở đâu trước.
Interpolation (nội suy)
Nhiều biến chỉ đo được ở một số điểm rời rạc (thu nhập khảo sát tại vài phường, giá đất tại vài giao dịch mẫu) nhưng ta cần giá trị ở mọi nơi. Nội suy không gian ước lượng giá trị tại điểm chưa đo từ các điểm đã đo lân cận. Kỹ thuật thường gặp: IDW (Inverse Distance Weighting — điểm càng gần càng ảnh hưởng mạnh) và Kriging (nội suy thống kê dựa trên cấu trúc tự tương quan không gian). Dùng khi cần bề mặt liên tục (ví dụ bản đồ ước lượng thu nhập) làm đầu vào cho lớp overlay. Thực hiện ở tầng GIS (QGIS/Python), không phải SQL thuần.
Quy trình chọn địa điểm chi nhánh
Ba nguyên tắc xuyên suốt: (1) luôn chiếu về hệ mét (UTM) trước khi đo khoảng cách/diện tích; (2) ưu tiên khoảng cách đường đi hơn chim bay khi ra quyết định thật; (3) mọi lớp phân tích phải quy được về một điểm số so sánh được, nếu không hội đồng đầu tư không dùng được.
Phép loại suy chạy được: xếp hạng thành phố để mở rộng
Trên sandbox không có PostGIS, nhưng ý tưởng "xếp hạng địa bàn theo tiềm năng để ưu tiên mở rộng" có thể minh hoạ bằng dữ liệu phi-không-gian có sẵn: gộp khách và dư nợ (số dư tài khoản) theo city. Thành phố nhiều khách nhưng dư nợ/khách còn thấp là ứng viên khai thác sâu; thành phố đông khách là nơi đáng cân nhắc thêm điểm phục vụ.
-- ▶ Chạy được
SELECT
c.city,
COUNT(DISTINCT c.id) AS so_khach,
COUNT(a.id) AS so_tai_khoan,
ROUND(COALESCE(SUM(a.balance), 0)::numeric, 2) AS tong_du_no,
ROUND(AVG(a.balance)::numeric, 2) AS du_no_tb_tk
FROM customers c
LEFT JOIN accounts a ON a.customer_id = c.id
GROUP BY c.city
ORDER BY so_khach DESC, tong_du_no DESC;
Đây là xương sống nghiệp vụ của cả bài phân tích không gian — chỉ khác là bản GIS thay city (thô) bằng ô lưới/phường (mịn) và bổ sung lớp dân số, thu nhập, đối thủ, mạng đường để ra điểm số không gian thực sự.
Use case thực tế
Bài toán: NCB có ngân sách mở 3 PGD mới tại một thành phố lớn trong năm, cần chọn vị trí tối ưu.
Các bước:
- Dữ liệu: ranh giới 30 phường (GADM), dân số + thu nhập ước lượng (nội suy IDW từ khảo sát 12 phường), 45.000 khách hiện hữu đã geocode, 22 PGD/chi nhánh của NCB, 60 điểm đối thủ lấy từ OSM, mạng đường OSM.
- Chuẩn hoá: chiếu tất cả về UTM 32648; gộp thành lưới hexbin cạnh ~500m.
- Phân tích:
- Hotspot khách bằng binding mật độ → 4 cụm khách lớn (ST_ClusterDBSCAN, eps=400m, minpoints=50).
- Service area 10 phút xe máy (isochrone qua pgRouting) cho 22 PGD hiện có → phát hiện 6.800 khách nằm ngoài mọi service area (gap).
- Local Moran's I trên tỷ lệ khách VIP → xác nhận 2 cụm phường "giàu" liền kề chưa có PGD.
- Overlay & chấm điểm: chồng 5 lớp (dân số, thu nhập, khách chưa phục vụ, mật độ đối thủ, khoảng cách tới PGD nhà) với trọng số 25/20/25/15/15, chuẩn hoá 0–1 → điểm sức hấp dẫn từng ô.
- Kết quả: 3 ô điểm cao nhất đều nằm trong gap và cụm thu nhập cao, mật độ đối thủ trung bình. Khảo sát thực địa xác nhận mặt bằng khả thi ở 2/3 vị trí; vị trí thứ 3 chuyển sang cụm ATM vì gap ở đó chủ yếu là nhu cầu tiền mặt.
Giá trị: thay vì mở theo cảm tính hoặc "chỗ nào có mặt bằng đẹp", quyết định dựa trên gap + tiềm năng định lượng, giảm rủi ro PGD ế và tối đa hoá khách mới tiếp cận. Đồng thời lớp Local Moran's I được đưa ngược vào cảnh báo tập trung địa lý danh mục tín dụng cho khối rủi ro.
Ghi nhớ
- Truy vấn trả lời "cái gì ở đâu"; phân tích không gian trả lời "nên làm gì" — và phải quy được ra tiền/quyết định.
- Mật độ: binning (hexbin) đơn giản, KDE mượt hơn nhưng phải chọn bandwidth. Hotspot = vùng mật độ cao vượt trội.
- Gom cụm:
ST_ClusterDBSCAN(mật độ, tự tìm số cụm, đánh dấu nhiễu) vsST_ClusterKMeans(định trướck). Nhớ chiếu về hệ mét đểepstính bằng mét. - Moran's I đo "gần nhau thì giống nhau" ([-1,+1]); I cao = rủi ro/giá trị tập trung địa lý → liên quan rủi ro tập trung danh mục tín dụng. Local Moran's I (LISA) chỉ ra cụm cụ thể.
- Site selection: service area/catchment → khoảng cách tới điểm gần nhất → phủ & gap → tối ưu vị trí (solver, không phải SQL).
- Isochrone/khoảng cách đường đi khác chim bay — cần mạng đường (OSM) + OSRM/pgRouting; PostGIS thuần không tự định tuyến.
- Overlay đa lớp: chuẩn hoá + trọng số → một điểm số so sánh được. Interpolation (IDW/Kriging) điền giá trị giữa các điểm đo rời rạc.
- Sandbox: SQL PostGIS trong bài là minh hoạ; chỉ câu gộp theo
citylà chạy được — nhớ ép::numerickhiROUND(AVG(...)).
Bài viết liên quan
Biến dữ liệu không gian thành bản đồ để ra quyết định. Bản đồ chuyên đề: choropleth (phải chuẩn hoá), symbol/bubble, heatmap, cluster, flow map — chọn theo dữ liệu. Công cụ: QGIS, Leaflet/Mapbox GL/deck.gl/Kepler.gl, bản đồ trong Power BI & Superset; tile OSM, level of detail. Luồng PostGIS → GeoJSON (ST_AsGeoJSON) → web map, nguyên tắc thiết kế và cạm bẫy. Bối cảnh NCB: dashboard dư nợ/huy động/khách theo tỉnh cho lãnh đạo.
PostGIS biến PostgreSQL thành cơ sở dữ liệu không gian đầy đủ. Bài này đi từ cài đặt CREATE EXTENSION, kiểu geometry vs geography, SRID/EPSG:4326, cách nhập điểm bằng ST_MakePoint/ST_GeomFromText, các hàm cốt lõi (ST_Distance, ST_DWithin, ST_Contains, ST_Buffer, ST_Transform...), chỉ mục GIST bắt buộc cho hiệu năng, tới bài toán tìm ATM/chi nhánh trong bán kính quanh khách hàng NCB.
Nhập môn dữ liệu không gian (spatial/geospatial): dữ liệu gắn vị trí trên Trái Đất, các loại hình học điểm/đường/vùng, hệ toạ độ CRS/SRID (WGS84, UTM/VN2000), vector vs raster, quan hệ và phép đo không gian. Đặt nền cho cả series GIS và giá trị của nó với ngân hàng NCB: mạng lưới chi nhánh/ATM, phân tích khách hàng theo địa bàn, rủi ro và gian lận theo vị trí.
Bài kết series: tổng hợp năm nhóm ứng dụng dữ liệu không gian (location intelligence) trong ngân hàng — tối ưu mạng lưới chi nhánh/ATM, phân tích khách theo địa bàn, rủi ro tín dụng theo vùng, gian lận/AML theo vị trí, marketing địa điểm. Kèm kiến trúc dữ liệu không gian (geocoding, PostGIS, dashboard bản đồ), quyền riêng tư dữ liệu vị trí, và lộ trình áp dụng cho NCB từ chuẩn hoá địa chỉ đến phân tích nâng cao.