【Flink银行反欺诈系统设计方案】7.反欺诈离线分析场景及代码实现
离线分析在反欺诈中用于对历史数据进行深度挖掘,识别复杂模式和长期行为异常。以下是5个典型场景及实现示例(基于 Spark 和 Python)。
1. 场景1:团伙欺诈检测(共同IP/设备关联)
案例说明
- 目标:识别同一IP或设备在短时间内被多个账户使用,可能为团伙作案。
- 分析逻辑:
- 统计同一IP/设备在1天内关联的账户数。
- 若超过阈值(如5个账户),标记为高风险。
代码实现
from pyspark.sql import SparkSession
from pyspark.sql.functions import count, col
df = spark.read.parquet("hdfs://path/to/transactions")
grouped = df.groupBy("ip", "device_id") \
.agg(count("user_id").alias("user_count")) \
.filter(col("user_count") > 5)
grouped.write.parquet("hdfs://path/to/risk_ips_devices")
表设计
| 字段名 | 类型 | 说明 |
|---|
| ip | STRING | IP地址 |
| device_id | STRING | 设备ID |
| user_count | INT | 关联账户数 |
| date | DATE | 日期 |
2. 场景2:用户行为模式分析(交易时间分布异常)
案例说明
- 目标:分析用户历史交易时间分布,发现异常时间段交易(如凌晨3点大额交易)。
- 分析逻辑:
- 计算用户历史交易时间分布(小时级)。
- 标记在低概率时间段(如凌晨)的大额交易。
代码实现
from pyspark.sql.functions import hour
user_hour_dist = df.groupBy("user_id", hour("timestamp").alias("hour")) \
.agg(count("*").alias("count")) \
.groupBy("user_id") \
.pivot("hour") \
.sum("count")
anomalies = df.filter(
(hour("timestamp").between(3, 5)) &
(col("amount") > 10000)
).join(user_hour_dist, "user_id", "left")
anomalies.write.parquet("hdfs://path/to/time_anomalies")
表设计
| 字段名 | 类型 | 说明 |
|---|
| user_id | STRING | 用户ID |
| hour | INT | 交易小时 |
| count | INT | 交易次数 |
| amount | DECIMAL | 交易金额 |
3. 场景3:交易网络图谱分析(资金环检测)
案例说明
- 目标:识别资金环形流动(A→B→C→A),可能为洗钱行为。
- 分析逻辑:
- 构建交易网络图,检测环路。
- 使用图算法(如强连通分量)识别环路。
代码实现
from graphframes import GraphFrame
edges = df.selectExpr("payer_id as src", "payee_id as dst")
vertices = df.selectExpr("payer_id as id").union(df.selectExpr("payee_id as id")).distinct()
graph = GraphFrame(vertices, edges)
scc = graph.stronglyConnectedComponents(maxIter=10)
scc.filter(size(collect_set("id").over(Window.partitionBy("component"))) >= 3) \
.write.parquet("hdfs://path/to/cycles")
表设计
| 字段名 | 类型 | 说明 |
|---|
| payer_id | STRING | 付款方ID |
| payee_id | STRING | 收款方ID |
| amount | DECIMAL | 交易金额 |
| timestamp | TIMESTAMP | 交易时间 |
4. 场景4:历史交易异常聚合分析(金额突变)
案例说明
- 目标:统计用户历史交易金额的均值和标准差,标记近期交易金额突增。
- 分析逻辑:
- 计算用户历史交易金额的均值和标准差。
- 标记近期交易金额超过均值3倍标准差。
代码实现
from pyspark.sql.window import Window
from pyspark.sql.functions import avg, stddev
window = Window.partitionBy("user_id").orderBy("timestamp").rowsBetween(-100, -1)
stats = df.withColumn("hist_avg", avg("amount").over(window)) \
.withColumn("hist_std", stddev("amount").over(window))
anomalies = stats.filter(
col("amount") > (col("hist_avg") + 3 * col("hist_std"))
)
anomalies.write.parquet("hdfs://path/to/amount_anomalies")
表设计
| 字段名 | 类型 | 说明 |
|---|
| user_id | STRING | 用户ID |
| amount | DECIMAL | 交易金额 |
| hist_avg | DECIMAL | 历史均值 |
| hist_std | DECIMAL | 历史标准差 |
5. 场景5:机器学习模型训练(欺诈分类)
案例说明
- 目标:训练分类模型(如随机森林),预测欺诈交易。
- 分析逻辑:
- 特征工程:提取用户行为特征(交易频率、金额分布等)。
- 使用历史标签数据训练模型,预测新交易风险。
代码实现
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.classification import RandomForestClassifier
from pyspark.ml import Pipeline
features = df.groupBy("user_id").agg(
avg("amount").alias("avg_amount"),
count("*").alias("total_txns"),
sum(when(col("is_fraud") == 1, 1).otherwise(0)).alias("fraud_count")
)
assembler = VectorAssembler(
inputCols=["avg_amount", "total_txns", "fraud_count"],
outputCol="features"
)
rf = RandomForestClassifier(labelCol="is_fraud", featuresCol="features")
pipeline = Pipeline(stages=[assembler, rf])
model = pipeline.fit(training_data)
predictions = model.transform(test_data)
predictions.write.parquet("hdfs://path/to/fraud_predictions")
表设计
| 字段名 | 类型 | 说明 |
|---|
| user_id | STRING | 用户ID |
| avg_amount | DECIMAL | 历史平均金额 |
| total_txns | INT | 总交易次数 |
| is_fraud | INT | 欺诈标签(0/1) |
总结
- 离线分析场景:团伙检测、时间分布、网络图谱、统计聚合、机器学习。
- 实现工具:Spark SQL、GraphFrames、MLlib。
- 核心逻辑:通过批处理挖掘历史数据中的复杂模式,结合统计方法和算法增强欺诈检测能力。