查看全课大纲(第 31 / 35 节)
- 1.特征工程简介
- 2.特征工程的处理流程
- 3.数据与特征概述
- 4.数据统计、相似度与数据探索
- 5.数据探索工具 Pandas_profiling
- 6.工具应用:《泰坦尼克》分析报告
- 7.构造一个微型链家租房数据集用于演示
- 8.数据预处理综述
- 9.缺失值处理实操
- 10.异常值处理实操
- 11.连续值特征构建
- 12.类别型数据特征构建
- 13.特征幅度缩放
- 14.特征离散化
- 15.特征编码:让类别数据参与建模
- 16.特征变换
- 17.时间特征
- 18.特征衍生
- 19.自动化特征工具
- 20.特征选择综述
- 21.特征选择方法
- 22.过滤式特征选择方法实操
- 23.包裹式特征选择方法
- 24.嵌入式特征选择
- 25.混序法与混合法特征选择
- 26.特征降维综述
- 27.案例实操:特征降维
- 28.特征监控概述与指标
- 29.Iris 数据集特征漂移检测案例
- 30.特征监控实战:用分布对比检测数据漂移
- 31.实时特征监控
- 32.电商销量预测项目背景介绍
- 33.数据预处理和特征工程(一)
- 34.数据预处理和特征工程(二)
- 35.数据建模
实时特征监控
约 6 分钟
小象实战讲义 · 特征工程精讲与实践
在上一节,我们学习了如何使用阶段性监控的方法,对比训练集与线上预测数据的特征分布,从而发现数据漂移。然而,在实际的工业场景中,许多业务(如金融风控、实时推荐)对特征的时效性要求极高,需要近乎实时的监控能力。本节我们将介绍实时特征监控的概念,并通过一个开源项目 Simple Model Monitor 来了解其技术架构与实现思路,为你构建自己的监控平台提供参考。
💡 核心导读
- 实时监控的意义:理解为何在某些业务场景下,需要从阶段性监控升级到实时监控。
- 开源项目剖析:通过
Simple Model Monitor项目,了解一个简易实时监控平台的技术栈(Python + MySQL + Flask + ECharts)。 - 实现流程概览:掌握从数据存储、后端服务到前端展示的完整监控链路是如何搭建的。
- 技术选型参考:了解构建此类监控平台所需的核心组件及其作用,为自研平台打下基础。
实时监控的必要性与架构
在特征监控概述中我们提到,监控可分为阶段性监控和实时监控。阶段性监控(如每小时、每天)适用于对时效性要求不高的场景,通过批量对比报告来发现问题。而实时监控则要求系统能够持续地、低延迟地采集线上样本,并进行统计分析与可视化展示。
实时监控平台常见于对决策时效性要求极高的领域,例如:
- 金融风控:需要实时监控用户信用评分模型的特征分布,以应对突发的欺诈模式变化。
- 内容推荐:需要实时监控用户兴趣特征的变化,以保证推荐结果的时效性和准确性。
- 广告投放:需要实时监控广告点击率预估模型的特征,以快速调整出价策略。
构建一个完整的实时特征监控平台,通常涉及后台开发、前端可视化、数据存储与计算等多个环节,开发工作量较大。因此,我们本节的目标并非从零实现一个平台,而是通过分析一个优秀的开源项目,理解其核心架构与实现原理。
Simple Model Monitor 项目解析
Simple Model Monitor 是一个基于 Python 的、用于金融风控场景下监控用户信用分及特征分布的开源 Web 应用。它完美地演示了一个简易实时监控平台的技术栈和交互逻辑。
项目背景与功能
该项目模拟了一个典型的金融风控场景:定期(如每月)根据用户的新数据更新其信用评分(A卡、B卡、C卡等)。监控平台需要能够:
- 展示评分分布:可视化不同信用评分模型(A分、B分等)下,用户得分的分布情况。
- 展示特征分布:可视化构成信用评分的关键特征(如年龄、收入区间)的分布情况。
- 多周期对比:支持选择不同的账期(时间周期),对比同一评分或特征在不同时期的分布变化,从而评估模型的稳定性(例如,计算 PSI 指标)。
- 交互式查询:用户可以通过网页前端选择不同的模型和账期,动态更新图表。
技术栈详解
该项目采用了经典且轻量级的技术组合,非常适合学习和作为自研项目的起点:
- 后端框架 - Flask:一个轻量级的 Python Web 框架,负责处理 HTTP 请求、业务逻辑和路由。代码中的
model_monitor.py和server.py是后端核心。 - 前端可视化 - ECharts:百度开源的一个强大的 JavaScript 图表库。前端通过 Ajax 请求从后端获取 JSON 格式的数据,然后使用 ECharts 渲染出动态、可交互的图表(如柱状图、折线图)。
- 数据存储 - MySQL:由于监控数据量通常不会特别巨大(存储的是聚合后的统计信息,而非原始海量数据),因此使用关系型数据库 MySQL 进行存储,简单可靠。项目中包含
save_fake_data.py用于生成模拟数据并存入数据库。 - 数据交互 - Ajax:用于实现前端与后端的异步通信。当用户在网页上选择不同的模型或账期时,前端通过 Ajax 发送请求到后端特定的接口(如
/selected),后端查询数据库并返回新的图表数据,前端再局部更新图表,无需刷新整个页面。 - 核心数据处理 - Python (pandas, numpy):用于从数据库查询数据、进行聚合计算、并格式化为前端 ECharts 所需的数据结构。
核心代码逻辑梳理
虽然我们不深入每一行代码,但理解其核心流程至关重要:
数据准备与存储:
- 运行
save_fake_data.py,生成模拟的信用评分和特征统计数据。 - 数据被存入 MySQL 的两张表:
model_statistic(存储不同账期、不同评分模型的得分分布)和feature_statistic(存储不同账期、不同评分模型下的特征值分布)。
- 运行
启动监控服务:
- 运行
python model_monitor.py启动 Flask 开发服务器(默认端口 9000)。 - 或者运行
python server.py启动一个更适用于生产环境的 Tornado 服务器(默认端口 8000,监听所有网络接口0.0.0.0)。
- 运行
页面加载与初始渲染:
- 用户访问
http://127.0.0.1:9000。 - Flask 路由
/对应的hello_world()函数被调用。 - 该函数执行以下操作: a. 查询数据库中有哪些账期 (
periods)。 b. 获取最新账期的默认评分模型(如‘A’分)的分布数据,通过model_data_for_front_begin等工具函数处理成 ECharts 可用的格式。 c. 获取相同条件下特征的分布数据。 d. 将所有数据打包成一个字典,传递给index.html模板进行渲染。
- 用户访问
交互与动态更新:
- 用户在页面切换模型或选择多个账期进行对比。
- 前端通过 Ajax 向
/selected路由发送 POST 请求,携带用户选择的参数。 response_form()函数处理请求,根据参数重新查询数据库。- 将查询结果处理成 JSON 格式,返回给前端。
- 前端 JavaScript 接收到新的 JSON 数据后,调用 ECharts 的 API 更新图表。
# 以下代码块用字典模拟了后端核心路由的数据流逻辑,帮助理解数据从查询到聚合的过程。
# 注意:这是一个简化的示意实现,可在本讲义环境中直接运行;真实项目中数据来自 MySQL 查询。
# 假设我们有一个微型的模拟数据库(用字典代替)
fake_db = {
'model_statistic': [
{'period': '2023-10', 'score_name': 'A', 'score': 650, 'counts': 100},
{'period': '2023-10', 'score_name': 'A', 'score': 700, 'counts': 150},
{'period': '2023-11', 'score_name': 'A', 'score': 650, 'counts': 90},
{'period': '2023-11', 'score_name': 'A', 'score': 700, 'counts': 160},
],
'feature_statistic': [
{'period': '2023-10', 'score_name': 'A', 'feature_name': 'age_group', 'feature_value': '20-30', 'counts': 80},
{'period': '2023-10', 'score_name': 'A', 'feature_name': 'age_group', 'feature_value': '30-40', 'counts': 170},
{'period': '2023-11', 'score_name': 'A', 'feature_name': 'age_group', 'feature_value': '20-30', 'counts': 85},
{'period': '2023-11', 'score_name': 'A', 'feature_name': 'age_group', 'feature_value': '30-40', 'counts': 165},
]
}
def get_model_data(period_selected, model_selected):
"""模拟从数据库查询模型分布数据并聚合"""
data = []
for record in fake_db['model_statistic']:
if record['period'] in period_selected and record['score_name'] == model_selected:
data.append({'score': record['score'], 'counts': record['counts'], 'period': record['period']})
# 简单按账期分组示意
result = {}
for d in data:
key = d['period']
if key not in result:
result[key] = {'scores': [], 'counts': []}
result[key]['scores'].append(d['score'])
result[key]['counts'].append(d['counts'])
return result
def get_feature_data(period_selected, model_selected):
"""模拟从数据库查询特征分布数据并聚合"""
# 逻辑类似,略
pass
# 假设收到一个前端请求:对比2023-10和2023-11月的A卡评分
selected_periods = ['2023-10', '2023-11']
selected_model = 'A'
model_distribution = get_model_data(selected_periods, selected_model)
print("模型分布查询结果(示意):")
for period, dist in model_distribution.items():
print(f" 账期 {period}: 得分 {dist['scores']}, 人数 {dist['counts']}")模型分布查询结果(示意):
账期 2023-10: 得分 [650, 700], 人数 [100, 150]
账期 2023-11: 得分 [650, 700], 人数 [90, 160](注:真实项目中,数据会经过更复杂的处理,转换成ECharts需要的series、xAxis等数据结构)
从开源项目到工业实践
Simple Model Monitor 项目为我们提供了一个清晰的蓝图。在实际的工业级特征监控平台开发中,你可能还需要考虑以下方面:
- 数据接入:如何从线上实时数据流(如 Kafka、Flink)或离线数仓中,实时/准实时地计算特征的统计分布(均值、分位数、唯一值等)并写入监控数据库。
- 监控指标计算:除了展示分布,还需集成 PSI、特征覆盖率、异常值比例等监控指标的计算与报警逻辑。
- 报警机制:当监控指标超过阈值时,如何通过邮件、钉钉、企业微信等渠道自动触发报警。
- 权限与多租户:大型公司可能有多个业务线或模型团队,平台需要支持权限管理和数据隔离。
- 性能与扩展性:随着监控特征和模型数量的增长,数据库查询、前端渲染的性能需要优化,架构可能需要引入缓存(如 Redis)或更强大的数据引擎。
尽管完整的平台构建涉及较多工程开发,但其核心思想不变:持续采集线上特征数据,计算关键指标,并通过友好的界面进行可视化与对比,从而让算法工程师和业务方能够快速感知数据变化,保障模型稳定运行。
📝 动手练一练
- 概念辨析:阶段性监控和实时监控最主要的区别是什么?请列举一个必须使用实时监控的业务场景,并说明理由。
👉 点击查看参考答案
主要区别在于数据处理的延迟和频率。阶段性监控是按固定时间间隔(如小时、天)进行批量数据对比,延迟高;实时监控是持续或近实时地进行数据采集与分析,延迟极低。
必须使用实时监控的场景示例:金融交易反欺诈系统。 理由:欺诈行为往往发生在瞬间,实时风控系统需要在用户发起交易的毫秒级时间内,基于最新的用户行为特征(如本次交易金额、地点、设备信息)做出风险判断——拦截单笔交易是模型实时推理链路的职责,特征监控本身并不参与拦截。特征监控的价值在于:若只做阶段性监控(例如每小时分析一次),发现特征分布漂移的延迟会很高,失效特征会“带病”持续支撑实时风控模型,让拦截决策建立在过时的特征分布上。因此,对特征输入分布做实时(或近实时)监控,才能尽快发现”模型判断依据已经失效”的信号,触发模型回滚或再训练。
- 技术思考:如果要将
Simple Model Monitor项目改造成监控一个电商推荐系统的特征(例如“用户近1小时点击率”、“商品当前库存”),你认为在技术栈或实现上需要做哪些主要的调整?(至少列出两点)
👉 点击查看参考答案
- 数据源与计算层调整:原项目使用静态的、预先计算好的统计表。电商推荐特征(如近1小时点击率)是动态变化的。需要引入实时计算框架(如 Apache Flink、Spark Streaming)来消费用户行为日志流,实时聚合出这些时间窗口特征的最新统计值,并写入监控数据库(或时序数据库如 InfluxDB),供前端查询。
- 监控指标与报警强化:原项目侧重分布可视化。电商场景下,除了分布,可能更关心特征的覆盖率(有多少用户有近1小时行为)、时效性(数据延迟)、异常值(点击率突然飙高可能是爬虫)。需要在后端增加这些指标的计算逻辑,并集成报警模块,当指标异常时自动触发告警。
- (可选)前端图表优化:电商特征可能变化非常快,可以考虑增加实时刷新的图表(如每秒自动请求新数据),或引入趋势图来展示特征指标随时间的变化曲线,而不仅仅是多周期的静态对比。
本章小结
至此,我们完成了《特征监控》章节的全部学习。我们从特征监控的必要性讲起,明确了监控的核心指标(分布、时效性、覆盖率、异常值),并深入探讨了两种监控方法:使用工具进行阶段性分布对比,以及了解如何构建一个实时监控平台的架构。
特征工程并非模型上线前的“一次性”工作,而是一个贯穿模型生命周期的持续过程。特征监控就是确保特征在线上环境中持续、稳定、有效发挥作用的“守夜人”。
📋 行动清单
学完本章,你可以立即着手:
- 回顾项目:运行
Simple Model Monitor开源项目,理解其前后端数据流。 - 分析现有模型:为你正在接触或学习的一个模型(如泰坦尼克生存预测),设计几个关键的特征监控指标(例如
Age的分布、Sex的类别占比)。 - 构思监控方案:思考如果要为你熟悉的某个业务场景(如房价预测、销量预测)设计特征监控,你会重点关注哪些指标?采用阶段性报告还是实时看板?为什么?
—— 小象教研组