О проекте
Команда: Hell Mode: The Hardcore Gamer Dominates in Another World with Garbage Balancing
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
AML-инструмент: объяснимые роли, кластеры и очередь проверки для 2 248 счетов, Streamlit-вьюер с сетью PyVis, карточками узлов и выгрузкой, запускаемый одной командой Docker Compose.
Как устроено
Пайплайн валидирует входы, считает графовые метрики NetworkX (PageRank, betweenness, seed reach в 4 хопа, межкластерная степень) и временные признаки (двухдневный relay ratio). Роль выбирается по порогам пригодности и взвешенному баллу на процентилях (минимум 0.55), кластеры — Louvain. Строгая валидация артефактов и провенанса с хешами источников и выходов; вьюер Streamlit + PyVis + Altair, опциональный AI-ассистент.
Ключевые решения
- NetworkX
- Louvain
- PageRank
- betweenness
- процентильный скоринг ролей
- двухдневный relay ratio
- сценарии удаления узлов (resilience)
- валидация провенанса с хешами
Особенности
Большой тестовый контур (по коммитам — 510 тестов, включая браузерную интеграцию) с отключённой сетью в тестовом сервисе; проверка хешей источников и выходов; раздел о масштабировании до 1 млн узлов (DuckDB/Polars, сэмплированная betweenness).
Стек
Python · pandas · NumPy · PyArrow · NetworkX · Streamlit · PyVis · Altair · Docker Compose
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-4ebde272-hell-mode-the-hardcore-gamer-dominates-in-another-world-with-garbage-balancing.
README
README.mdMoney Graph
Money Graph helps a bank's anti-money-laundering (AML) analyst answer: which of these 2,248 accounts should I review first, and why? It turns the supplied transaction files into explained roles, a priority list and a searchable directed network, reducing the need to trace each chain manually.
Run
Install Docker with Docker Compose. Place the supplied nodes.parquet,
edges.parquet and transactions.parquet files in data/, then run from the
repository root:
git clone https://github.com/BAITC-Hacks/hack-4ebde272-hell-mode-the-hardcore-gamer-dominates-in-another-world-with-garbage-balancing.git
cd hack-4ebde272-hell-mode-the-hardcore-gamer-dominates-in-another-world-with-garbage-balancing/
docker compose up --build -d
Open http://localhost:8501. The command calculates and validates the outputs before starting the viewer. No API key is required. The first build downloads dependencies; core analysis and viewing run locally.
Technologies
Python 3.11, pandas, NumPy and PyArrow process the data.
NetworkX computes graph metrics and Louvain communities. Streamlit,
PyVis and Altair provide the interface, network map and charts.
Docker Compose runs the pipeline and viewer together; dependency versions
are pinned in requirements.txt and constraints.txt.
How to verify the solution
-
Check the generated data after startup:
docker compose exec -T app python main.py --data /app/data --out /app/out --validate-onlyExpected result:
strict artifact and provenance validation: OK. This checks all 2,248 identifiers, required CSV schemas, scores, cluster/top-list consistency and source/output hashes.docker compose logs analyticsshows output row counts and runtime; the brief requires less than 300 seconds. -
Check the analyst workflow. Open Investigation queue and read a ranked account's reason. Copy any
gidfromout/nodes_roles.csvinto Node card → Search arbitrary gid. Inspect Role evidence, thresholds and priority contributions, then find its directed links in Network explorer. Repeat for three chosen gids; Cluster review shows their community summaries. -
Run automated checks, including the browser workflow:
docker compose --profile test run --build --rm testsThe test service disables runtime networking; no live AI API is needed.
See the architecture diagram and five-minute walkthrough for a guided review.
Role criteria and thresholds
Scores combine graph percentiles with available flow and temporal observations. A candidate must pass its eligibility rule and score at least 0.55.
| Role | Eligibility and supporting pattern |
|---|---|
| Consolidator | At least 2 incoming counterparties, and either reachability from at least 2 initial case accounts or incoming degree at/above the 80th percentile. Emphasizes incoming relationships, transfers and amounts. |
| Distributor | At least 2 outgoing counterparties. Emphasizes outgoing relationships, transfers, amounts and links across communities. |
| Transit | Both incoming and outgoing relationships, plus a valid outgoing/incoming amount ratio in [0.5, 1.5] or two-day relay ratio ≥0.5. |
| Coordinator | At least 1 observed relationship and at least 2 signals at/above the 90th percentile among seed reach, path bridging, PageRank and cross-community degree. |
| Terminal | Nonseed, depth <4, uncensored observations, positive inflow, and outgoing amount ≤10% of inflow; also requires zero outgoing degree or a valid outgoing/incoming ratio ≤0.10. |
| Peripheral | No structural role qualifies. Strength is the strongest structurally eligible score below 0.55, or 0 if no structural gate passes. |
“Seed reach” counts initial case accounts reaching a node within four directed hops. Two-day relay measures eligible incoming dates with outgoing activity on the same date or either of the next two dates.
The highest eligible score wins. Exact ties follow coordinator → consolidator → distributor → transit → terminal → peripheral. Percentiles use average tied ranks; missing score components are excluded and remaining role weights are renormalized. Invalid seed and boundary ratios are not treated as observed zeros.
The decision rules contain the full weighted formulas, priority weights and worked explanations.
Output
Files are generated in out/ with these exact submission schemas:
| File | Contents |
|---|---|
nodes_roles.csv | One row for each of the 2,248 nodes: role, strength, community, review priority and numeric evidence of at most 200 characters. |
clusters.csv | One row per community: population, seed count, internal turnover, leading accounts and a structural hypothesis. |
top_nodes.csv | 50 ranked accounts, ordered by descending priority then gid, with a separate explanation of why each deserves review. |
nodes_roles.csv: gid,role,role_score,cluster_id,priority_score,evidence
clusters.csv: cluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis
top_nodes.csv: rank,gid,role,priority_score,why
Scores are bounded by [0,1]. Gids remain exact int64 identifiers; import them as text in spreadsheet software to avoid rounding.
Additional files preserve detailed metrics and rule diagnostics
(node_features.parquet), removal scenarios (resilience.csv) and provenance
(run_metadata.json). The viewer provides gid search, directed links, role and
cluster views, node explanations and an analyst review-list download.
Limitations
- Hop-4 cutoff: missing outgoing transfers cannot establish a final recipient.
- Incomplete inflows: seed accounts and transfers outside the sample do not have complete observed balances; dependent seed ratios are unavailable.
- Restricted sample: July 2026 intrabank transfers of at least 5,000 KZT. Other banks, smaller transfers and activity outside the period are invisible.
- Date-only timing: overlap does not prove payment order or movement of the same funds. Incomplete two-day follow-up windows are excluded.
- No ground truth: roles, priorities and communities are investigation hypotheses, not calibrated probabilities or findings of guilt. No customer attributes are inferred. The supplied data is restricted to hackathon use.
- Dataset scope: the production pipeline expects 2,248 nodes; larger-scale performance has not been established.
Scaling to one million nodes
- Partition transactions and pre-aggregate edges and daily activity using a columnar engine such as DuckDB or Polars.
- Replace exact betweenness with reproducible sampling; use sparse PageRank and partitioned community/seed-reach calculations with explicit work limits.
- Replace per-node transaction scans with vectorized window joins; keep route searches bounded and preserve observation-availability flags.
- Precompute decisions, index gid lookups, paginate queues and render limited neighborhoods instead of the entire graph.
Benchmark memory, latency and approximation stability before claiming support for that scale.
Авторы коммитов
История коммитов
- 2026-09-23 17:50Update README with Docker setup instructionsLelouch
- 2026-09-23 17:49Revise README with updated clone and run commandsLelouch
- 2026-09-23 17:47readmeLamgy
- 2026-09-23 17:46Merge branch 'testing' of https://github.com/BAITC-Hacks/hack-4ebde272-hell-mode-the-hardcore-gamer-dominates-in-another-world-with-garbage-balancing into testingLamgy
- 2026-09-23 17:44readmeLamgy
- 2026-09-23 17:42Merge branch 'testing'danial
- 2026-09-23 17:39Record verified chart and tooltip releasedanial
- 2026-09-23 17:37Fit chart labels horizontally and render readable node tooltipsdanial
Все коммиты (32)
- 2026-09-23 17:29Merge pull request #1 from BAITC-Hacks/testingLelouch
- 2026-09-23 17:27Publish readable explanations and verified AI-ready releasedanial
- 2026-09-23 17:24Make investigation reasons readable and configure optional AIdanial
- 2026-09-23 16:52Publish final 510-test verified submission releasedanial
- 2026-09-23 16:50Complete local analyst case workflow and final correctness checksdanial
- 2026-09-23 16:26Record integrated brief verification and remaining limitsdanial
- 2026-09-23 16:22Honor feature validity flags in integrated decision scoringdanial
- 2026-09-23 16:13Publish final integrated submission and 434-test release recordIldar
- 2026-09-23 16:06Align analyst workflow with integrated feature and decision contractsIldar
- 2026-09-23 16:00Merge remote-tracking branch 'origin/codex/brief-data' into codex/brief-uiIldar
- 2026-09-23 16:00Merge remote-tracking branch 'origin/testing' into codex/brief-uiIldar
- 2026-09-23 16:00Deliver validated CSV package and clean-checkout verification recordIldar
- 2026-09-23 15:58Keep Streamlit startup local without external IP discoveryIldar
- 2026-09-23 15:57Enforce strict submission contracts and explain decision rulesLamgy
- 2026-09-23 15:55Complete analyst viewer, provenance and reproducible delivery workflowIldar
- 2026-09-23 15:50Validate graph inputs and expose deterministic observed-flow featuresdanial
- 2026-09-23 15:31mergeddanial
- 2026-09-23 14:45Merge branch 'feature/decision-engine' into testingdanial
- 2026-09-23 14:45Merge branch 'feature/analyst-ui' into testingdanial
- 2026-09-23 14:38implemented graph intelligencedanial
- 2026-09-23 14:37implemented decision-engineLamgy
- 2026-09-23 14:30implemented analyse uiIldar
- 2026-09-23 13:49refactor: restructure repository architecturedanial
- 2026-09-23 13:22added downloadable contentdanial
Структура репозитория (60 файлов)
.dockerignore .env.example .gitignore DEMO.md Dockerfile README.md app.py compose.yaml constraints.txt data/edges.parquet data/nodes.parquet data/transactions.parquet documentation/architecture.md documentation/data-quality.md documentation/decision-rules.md documentation/feature-contract.md documentation/final-acceptance.md documentation/integration-verification.md documentation/technical-brief-audit.md main.py pipeline.py requirements-ai.txt requirements-dev.txt requirements.txt src/.gitkeep src/ai_assistant.py src/clustering.py src/config.py src/explanations.py src/exports.py src/graph_features.py src/loader.py src/priority.py src/resilience.py src/roles.py src/schema.py src/temporal.py src/workspace.py starter.py submission/.gitattributes submission/RELEASE.md submission/clusters.csv submission/nodes_roles.csv submission/release_metadata.json submission/top_nodes.csv tests/.gitkeep tests/test_ai_assistant.py tests/test_ai_sdk.py tests/test_app.py tests/test_browser_integration.py tests/test_chart_layout.py tests/test_config.py tests/test_features.py tests/test_input.py tests/test_integration.py tests/test_network_tooltips.py tests/test_outputs.py tests/test_roles.py tests/test_workspace.py validate_submission.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.