2、Spark评分模型基础:Spark MLlib简介、DataFrame与RDD在评分建模中的应用、特征工程与Spark Pipeline
2.1 Spark MLlib 概述与催收评分场景适配
Spark MLlib 是 Apache Spark 生态中原生的分布式机器学习库,专为大规模数据处理与模型训练设计。在催收评分场景中,MLlib 的核心价值在于:
- 海量样本处理:支持千万级逾期客户记录的全量训练,无需采样。
- 端到端流水线:从特征加工到模型评估,统一在 Spark 集群内完成。
- 生产级稳定性:与 Spark 核心引擎深度集成,适合每日/每周评分模型重训。
| 维度 | 传统单机建模 | Spark MLlib 建模 |
|---|---|---|
| 数据规模 | 受内存限制,通常 < 100 万行 | 可扩展至 10 亿+ 行 |
| 特征工程 | 依赖 Python/R 逐列处理 | 分布式 Transformer + Estimator |
| 模型算法 | 逻辑回归、XGBoost 等 | 逻辑回归、随机森林、GBT、FM |
| 生产部署 | 需额外封装 API | PipelineModel 直接加载评分 |
催收场景提示: MLlib 的 LogisticRegression 和 RandomForestClassifier 是催收评分最常用的两类算法。前者可解释性强,适合监管合规;后者对缺失值和异常值鲁棒,适合高维逾期特征。
2.2 DataFrame 与 RDD 在评分建模中的角色
Spark 提供两种核心数据抽象:RDD(弹性分布式数据集)和 DataFrame。在催收评分建模中,两者的定位与使用场景有明确分工。
2.2.1 RDD:底层计算引擎
RDD 是 Spark 最底层的分布式数据集合,提供细粒度的转换操作(map、filter、reduceByKey)。在评分建模中,RDD 主要用于:
- 自定义复杂特征逻辑(如按客户 ID 聚合逾期天数序列)。
- 非结构化数据解析(如催收通话录音元数据)。
- 与旧版 Spark 代码兼容。
2.2.2 DataFrame:结构化建模首选
DataFrame 在 RDD 之上增加了 Schema 信息和 Catalyst 优化器,是 MLlib 评分建模的标准数据载体。其优势包括:
- 自动优化:Catalyst 优化器自动选择最佳执行计划。
- 丰富 API:支持 SQL 风格操作(select、groupBy、join)。
- MLlib 原生支持:Pipeline 组件直接接受 DataFrame 作为输入。
最佳实践: 在催收评分项目中,始终优先使用 DataFrame。仅当需要实现 Spark SQL 无法表达的自定义聚合逻辑时,才降级使用 RDD,并通过
.toDF() 快速转回 DataFrame。
// 示例:RDD 转 DataFrame 用于 MLlib 训练
import org.apache.spark.sql.Row
import org.apache.spark.sql.types._
val rdd = sc.parallelize(Seq(
("C001", 30, 1.0),
("C002", 45, 0.0)
))
val schema = StructType(Seq(
StructField("customer_id", StringType, true),
StructField("overdue_days", IntegerType, true),
StructField("label", DoubleType, true)
))
val df = spark.createDataFrame(rdd.map(r => Row(r._1, r._2, r._3)), schema)
df.show()
2.3 特征工程与 Spark Pipeline
催收评分模型的特征工程通常包含:缺失值填充、类别编码、数值分箱、特征缩放、特征选择等步骤。Spark MLlib 通过 Pipeline 机制将这些步骤串联为可复用的工作流。
2.3.1 核心 Pipeline 组件
| 组件类型 | 常用类 | 催收场景示例 |
|---|---|---|
| Transformer | StringIndexer, OneHotEncoder, MinMaxScaler | 将催收员等级编码为数值特征 |
| Estimator | LogisticRegression, RandomForestClassifier | 训练逾期概率预测模型 |
| Evaluator | BinaryClassificationEvaluator | 计算 AUC、KS 等催收核心指标 |
| Pipeline | Pipeline | 串联特征加工 → 模型训练 → 评估 |
2.3.2 催收特征工程典型步骤
- 缺失值处理:使用
Imputer用中位数或众数填充逾期金额、联系次数等字段。 - 类别特征编码:
StringIndexer+OneHotEncoder处理催收地区、产品类型。 - 连续特征分箱:
QuantileDiscretizer将逾期天数分为 0-30、31-60、61-90 等区间。 - 特征缩放:
MinMaxScaler或StandardScaler统一量纲,加速模型收敛。 - 特征选择:
ChiSqSelector基于卡方检验筛选 Top-K 强相关特征。
常见陷阱: 在 Pipeline 中使用
StringIndexer 时,必须设置 setHandleInvalid("keep") 或 "skip",否则预测阶段遇到未见过的类别会抛出异常。催收场景中新产品或新地区频繁出现,此设置至关重要。
2.3.3 完整 Pipeline 代码示例
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.feature._
import org.apache.spark.ml.classification.LogisticRegression
// 1. 定义特征工程阶段
val indexer = new StringIndexer()
.setInputCol("product_type")
.setOutputCol("product_idx")
.setHandleInvalid("keep")
val encoder = new OneHotEncoder()
.setInputCol("product_idx")
.setOutputCol("product_vec")
val imputer = new Imputer()
.setInputCols(Array("overdue_days", "contact_count"))
.setOutputCols(Array("overdue_days_imp", "contact_count_imp"))
.setStrategy("median")
val scaler = new MinMaxScaler()
.setInputCol("overdue_days_imp")
.setOutputCol("overdue_days_scaled")
// 2. 定义模型
val lr = new LogisticRegression()
.setLabelCol("label")
.setFeaturesCol("features")
.setMaxIter(50)
// 3. 组装 Pipeline
val pipeline = new Pipeline()
.setStages(Array(indexer, encoder, imputer, scaler, lr))
// 4. 训练
val pipelineModel = pipeline.fit(trainingData)
// 5. 预测
val predictions = pipelineModel.transform(testData)
2.4 催收评分 Pipeline 架构图
2.5 催收评分特征工程关键对比
| 特征类型 | 常见字段 | 推荐处理方式 | 催收业务含义 |
|---|---|---|---|
| 逾期行为 | 逾期天数、逾期金额、逾期次数 | 分箱 + 缩放 | 反映客户还款意愿与能力 |
| 联系信息 | 联系次数、接通率、通话时长 | 缺失填充 + 缩放 | 评估催收触达效率 |
| 客户画像 | 年龄、收入、职业 | 分箱 + 编码 | 辅助判断还款能力 |
| 历史表现 | 历史还款率、历史延期次数 | 直接入模 + 缩放 | 强预测力特征 |
| 产品属性 | 产品类型、贷款期限、利率 | StringIndexer + OneHotEncoder | 区分不同产品风险差异 |
实战建议: 在构建催收评分 Pipeline 时,建议将特征工程分为两个子 Pipeline:
① 基础特征 Pipeline:缺失填充 + 类别编码 + 分箱(可复用至多个模型)。
② 模型特定 Pipeline:特征缩放 + 特征选择 + 模型 Estimator(不同算法可独立调整)。
① 基础特征 Pipeline:缺失填充 + 类别编码 + 分箱(可复用至多个模型)。
② 模型特定 Pipeline:特征缩放 + 特征选择 + 模型 Estimator(不同算法可独立调整)。