反洗钱AI实战:从可疑交易识别到监管报送

简介: 银行人必看:AI如何自动识别"星型转账"洗钱模式 实战代码:基于 risk-compliance Skill | 关联图谱 | 反洗钱检测 什么是"星型转账"? 洗钱者的经典手法: `` ┌───┐ │ A │ ──→ 分散资金 └───┘ │ ┌─────┼─────┐ ↓ ↓ ↓ ┌─┐ ┌─┐ ┌─┐ │B│ │C│ │D│ → 汇聚到中心 └─┘ └─┘ └─┘ │ │ │

银行人必看:AI如何自动识别"星型转账"洗钱模式

实战代码:基于 risk-compliance Skill | 关联图谱 | 反洗钱检测

什么是"星型转账"?

洗钱者的经典手法:

        ┌───┐
        │ A │ ──→ 分散资金
        └───┘
          │
    ┌─────┼─────┐
    ↓     ↓     ↓
   ┌─┐   ┌─┐   ┌─┐
   │B│   │C│   │D│  → 汇聚到中心
   └─┘   └─┘   └─┘
    │     │     │
    └─────┼─────┘
          ↓
        ┌───┐
        │ E │ ──→ 集中转出
        └───┘
          │
    ┌─────┼─────┐
    ↓     ↓     ↓
   ┌─┐   ┌─┐   ┌─┐
   │F│   │G│   │H│  → 再次分散
   └─┘   └─┘   └─┘

特征:多个账户 → 中心账户 → 多个账户,形成"星型"结构。

检测算法

from knowledge_graph import KnowledgeGraphBuilder, FraudPatternDetector
import pandas as pd

# 1. 加载交易数据
df = pd.read_csv("transactions.csv")
print(f"交易笔数: {len(df)}")

# 2. 构建关联图谱
builder = KnowledgeGraphBuilder()
graph = builder.build_from_transactions(df)
print(f"节点数: {graph.number_of_nodes()}")
print(f"边数: {graph.number_of_edges()}")

# 3. 检测星型转账
detector = FraudPatternDetector(graph)
star_patterns = detector.detect_star_transfer()

print(f"发现星型网络: {len(star_patterns)}个")
for pattern in star_patterns:
    print(f"\n中心账户: {pattern.center}")
    print(f"关联账户: {len(pattern.participants)}个")
    print(f"总流入: ¥{pattern.total_inflow:,.0f}")
    print(f"总流出: ¥{pattern.total_outflow:,.0f}")
    print(f"风险等级: {pattern.risk_level}")

完整代码

"""
反洗钱星型转账检测
运行: python aml_star_detection.py --data transactions.csv
"""
import argparse
import pandas as pd
from datetime import datetime

class StarTransferDetector:
    def __init__(self, min_inflow=100000, min_outflow=100000, 
                 min_participants=5, max_depth=2):
        self.min_inflow = min_inflow
        self.min_outflow = min_outflow
        self.min_participants = min_participants
        self.max_depth = max_depth

    def detect(self, transactions_df):
        """检测星型转账网络"""
        # 构建转账网络
        networks = self._build_networks(transactions_df)

        # 识别星型结构
        stars = []
        for center, network in networks.items():
            if self._is_star_pattern(center, network):
                stars.append({
   
                    "center": center,
                    "participants": network["participants"],
                    "total_inflow": network["inflow"],
                    "total_outflow": network["outflow"],
                    "risk_level": self._calculate_risk(network)
                })

        return stars

    def _build_networks(self, df):
        """构建转账网络"""
        networks = {
   }
        for _, row in df.iterrows():
            from_acc = row["from_account"]
            to_acc = row["to_account"]
            amount = row["amount"]

            # 统计每个账户的流入流出
            for acc in [from_acc, to_acc]:
                if acc not in networks:
                    networks[acc] = {
   
                        "participants": set(),
                        "inflow": 0,
                        "outflow": 0
                    }

            networks[to_acc]["participants"].add(from_acc)
            networks[to_acc]["inflow"] += amount
            networks[from_acc]["outflow"] += amount

        return networks

    def _is_star_pattern(self, center, network):
        """判断是否为星型结构"""
        return (
            network["inflow"] >= self.min_inflow and
            network["outflow"] >= self.min_outflow and
            len(network["participants"]) >= self.min_participants
        )

    def _calculate_risk(self, network):
        """计算风险等级"""
        score = 0
        score += min(network["inflow"] / 1000000, 50)  # 流入金额
        score += min(network["outflow"] / 1000000, 50)  # 流出金额
        score += len(network["participants"]) * 5  # 参与账户数

        if score >= 80:
            return "极高"
        elif score >= 60:
            return "高"
        elif score >= 40:
            return "中"
        else:
            return "低"

# 主程序
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--data", required=True, help="交易数据CSV文件")
    parser.add_argument("--min-inflow", type=int, default=100000)
    parser.add_argument("--min-outflow", type=int, default=100000)
    parser.add_argument("--min-participants", type=int, default=5)
    args = parser.parse_args()

    # 加载数据
    df = pd.read_csv(args.data)
    print(f"📊 加载交易数据: {len(df)}笔")

    # 检测
    detector = StarTransferDetector(
        min_inflow=args.min_inflow,
        min_outflow=args.min_outflow,
        min_participants=args.min_participants
    )

    stars = detector.detect(df)

    # 输出报告
    print(f"\n🚨 发现星型转账网络: {len(stars)}个")
    for star in stars:
        print(f"\n{'='*50}")
        print(f"中心账户: {star['center']}")
        print(f"关联账户: {len(star['participants'])}个")
        print(f"总流入: ¥{star['total_inflow']:,.0f}")
        print(f"总流出: ¥{star['total_outflow']:,.0f}")
        print(f"风险等级: {star['risk_level']}")

    # 保存报告
    report = generate_report(stars)
    with open("aml_report.md", "w") as f:
        f.write(report)
    print(f"\n✅ 报告已保存: aml_report.md")

def generate_report(stars):
    """生成Markdown报告"""
    report = "# 反洗钱检测报告\n\n"
    report += f"生成时间: {datetime.now()}\n\n"
    report += f"## 检测结果\n\n"
    report += f"发现可疑星型网络: **{len(stars)}**个\n\n"

    for i, star in enumerate(stars, 1):
        report += f"### 网络 {i}\n\n"
        report += f"- 中心账户: `{star['center']}`\n"
        report += f"- 关联账户: {len(star['participants'])}个\n"
        report += f"- 总流入: ¥{star['total_inflow']:,.0f}\n"
        report += f"- 总流出: ¥{star['total_outflow']:,.0f}\n"
        report += f"- 风险等级: **{star['risk_level']}**\n\n"

    return report

if __name__ == "__main__":
    main()

运行效果

$ python aml_star_detection.py --data transactions.csv --min-inflow 500000

📊 加载交易数据: 12,847笔

🚨 发现星型转账网络: 3个

==================================================
中心账户: 6222****8888
关联账户: 12个
总流入: ¥2,340,000
总流出: ¥2,280,000
风险等级: 极高

==================================================
中心账户: 6222****6666
关联账户: 8个
总流入: ¥1,560,000
总流出: ¥1,490,000
风险等级: 高

==================================================
中心账户: 6222****9999
关联账户: 6个
总流入: ¥890,000
总流出: ¥850,000
风险等级: 中

可视化

import networkx as nx
import matplotlib.pyplot as plt

# 绘制星型网络
def visualize_star(star, df):
    G = nx.DiGraph()

    # 添加中心节点
    G.add_node(star["center"], node_color="red", size=1000)

    # 添加关联节点
    for participant in star["participants"]:
        G.add_node(participant, node_color="blue", size=500)
        G.add_edge(participant, star["center"])

    # 绘制
    pos = nx.spring_layout(G)
    colors = [G.nodes[n]["node_color"] for n in G.nodes()]
    sizes = [G.nodes[n]["size"] for n in G.nodes()]

    plt.figure(figsize=(10, 8))
    nx.draw(G, pos, node_color=colors, node_size=sizes, 
            with_labels=True, arrows=True)
    plt.title(f"星型转账网络: {star['center']}")
    plt.savefig(f"star_{star['center']}.png")
    plt.show()

# 可视化第一个网络
visualize_star(stars[0], df)

进阶:多层星型检测

# 检测多层星型(A→B→C→D)
def detect_multi_layer_star(df, max_layers=3):
    """检测多层星型转账"""
    G = nx.DiGraph()

    # 构建图
    for _, row in df.iterrows():
        G.add_edge(row["from_account"], row["to_account"], 
                   weight=row["amount"])

    # 查找多层路径
    patterns = []
    for node in G.nodes():
        # BFS查找星型结构
        for depth in range(2, max_layers + 1):
            paths = find_star_paths(G, node, depth)
            if paths:
                patterns.extend(paths)

    return patterns

def find_star_paths(G, center, depth):
    """查找以center为中心的depth层星型路径"""
    # 实现BFS查找
    pass

完整代码https://github.com/yuzhaopeng-up/financial-ai-skills/tree/main/skills/risk-compliance/examples

#反洗钱 #星型转账 #Python实战 #银行风控 #关联图谱

相关文章
|
2天前
|
人工智能 安全 测试技术
|
4天前
|
云安全 人工智能 安全
阿里云 Agentic SOC 位居 IDC MarketScape安全运营智能体2026领导者类别
以 Agentic AI 重构安全运营闭环,阿里云云安全在产品能力与市场份额
1172 3
|
3天前
|
数据采集 机器学习/深度学习 人工智能
田间杂草定位与检测4200张YOLO智慧农业数据集分享
本数据集含4200张真实农田图像,YOLO格式,单类别(杂草)高质量标注,覆盖多作物、多光照、多生长阶段等复杂场景,专为智慧农业杂草检测与智能除草设备研发设计,支持YOLOv5/v8/v10等主流模型训练。
355 94
|
5天前
|
缓存 UED 开发者
Codex109天重置23次,明天还要再送一次
Codex近109天完成23次额度重置,7月14日将迎来第24次。Tibo高频响应用户反馈:优化GPT-5.6高消耗问题、补发失效福利、调整重置时间——形成“反馈→回应→修复→补偿”正向闭环,彰显以用户为中心的产品哲学。(239字)
603 11
|
8天前
|
存储 人工智能 JSON
Qwen 本地部署搭配 ComfyUI 生成 AI 漫剧完整实操指南(小白零基础可落地,零成本无限生成+角色一致性天花板)
2026全网最优本地漫剧流水线:零成本、离线运行、角色统一、低配(8G显卡)可跑。融合Qwen本地大模型+ComfyUI双引擎,实现剧本生成→分镜绘图→动态成片全自动,隐私安全、无审核限流,新手30分钟上手,日更无忧。(239字)
|
8天前
|
人工智能 缓存 JSON
刚刚 GPT-5.6 发布,吊打 Claude 5 和 Grok 4.5?一手实测来啦!
GPT-5.6 刚发布,跑分号称超越 Fable 5,真的假的?附一手实测,让 3 个最强 AI 编程模型 GPT-5.6 Sol、Claude Fable 5、Grok 4.5 在 Cursor 里同时一把梭开发网页游戏,看看最新模型到底谁更能打。
369 0