3. AI风险预测的数据底座

AI风险预测模型的效果,往往不取决于算法有多复杂,而取决于喂给它的数据是否真实、完整、时序一致。工程项目的数据天然分散:进度在计划软件里,成本在财务系统里,资源在物资台账里,天气在外部接口里,传感器在物联网平台里,文本记录散落在日志、会议纪要和巡检单里。把这些数据整合成一张可供模型训练和推理的“宽表”,就是本节要解决的核心问题。

一、六类数据源及其采集方式

工程项目的风险预测通常需要六类数据,它们的采集频率、数据形态和接入方式差异很大,必须分别设计采集策略。

  • 进度数据:来自P6、Project或自研进度系统,核心字段包括任务编号、计划开始/结束时间、实际开始/结束时间、完成百分比、前置任务关系。采集方式为按日或按周批量导出,或通过数据库视图增量拉取。
  • 成本数据:来自ERP或成本管理系统,核心字段包括科目编码、预算金额、已发生成本、承诺成本、支付时间。通常按日增量同步,注意与进度数据的WBS编码对齐。
  • 资源数据:来自物资系统和人力系统,包括设备台班、材料到场量、劳动力工时。采集频率可为日或班次级。
  • 天气数据:来自气象API或现场气象站,包括温度、降水、风速、能见度。按小时或按日采集,需记录站点经纬度以便与工区匹配。
  • 传感器数据:来自基坑监测、塔吊监控、混凝土测温等IoT设备,包括测点编号、时间戳、测值、单位。通常以秒级或分钟级高频上报,需做降采样或聚合。
  • 文本记录:包括施工日志、监理通知、安全巡检记录、会议纪要。这类数据以非结构化文本存在,需通过NLP抽取事件类型、涉及工区、严重程度等结构化标签。

采集阶段的关键原则是“先落地、再加工”:原始数据应原样存入数据湖或ODS层,保留采集时间和来源标识,避免后续无法追溯。

二、数据清洗:从脏数据到可用记录

工程数据常见的质量问题包括:缺失值、异常值、重复记录、单位不统一、时间戳格式混乱。清洗不是简单删除,而是有判断地修复或标记。

以传感器数据为例,某基坑测斜仪在2024年3月15日02:00至05:00连续上报位移值为0,而前后时段正常值在2.1~2.8mm之间。这种“零值段”通常是设备断电或通信中断,应标记为缺失而非真实位移。处理方式为:将0值替换为NaN,再用前后各30分钟的中位数做线性插值,同时生成一个“插值标记”字段供模型区分。

对于成本数据,常见问题是同一笔付款被重复导入。清洗规则可设为:以“合同编号+付款批次+金额+付款日期”为唯一键去重,保留最新导入时间的一条。

对于文本记录,清洗包括去除HTML标签、统一简繁体、纠正明显错别字,然后进入实体抽取。例如“3号塔吊基础积水严重”应被抽取为{对象:3号塔吊, 问题:基础积水, 严重度:高}。

清洗阶段应保留“清洗日志”,记录每条规则影响了多少条记录、替换了什么值。这既是数据质量审计的依据,也是模型可解释性的一部分。

三、时间对齐:让不同频率的数据说同一种“时间语言”

六类数据的时间粒度不同:传感器是分钟级,天气是小时级,进度和成本是日级,文本记录是事件级。要让它们进入同一个特征向量,必须统一到同一时间基准。

推荐做法是选择“日”作为基础时间粒度,因为工程风险预测通常以天为决策周期。对齐规则如下:

  • 传感器数据:按日聚合,取每日均值、最大值、最小值、标准差、变化率五个统计量。
  • 天气数据:按日聚合,取日降水量、日最高/最低温度、日最大风速、是否出现恶劣天气的布尔标记。
  • 进度数据:取每日快照,记录当日完成百分比、是否发生任务延期。
  • 成本数据:取每日累计已发生成本、当日新增成本。
  • 文本记录:按日汇总,统计当日各类事件数量、最高严重度。

对齐后的每一行代表“某工区某一天”的完整状态。如果某天某类数据缺失,应明确标记为缺失,而不是填0——因为0在成本或位移中可能是真实值,会造成语义混淆。

多源数据采集 → 清洗 → 时间对齐 → 特征化 全链路 ① 采集层(六类数据源) 进度数据 P6/Project 日快照 成本数据 ERP 日增量 资源数据 物资/人力 班次级 天气数据 气象API 小时级 传感器数据 IoT 分钟级 文本记录 日志/纪要 事件级 ② 清洗层(规则+标记) 缺失值处理 零值段→NaN→插值+标记 重复记录去重 合同+批次+金额+日期 单位/格式统一 mm/m、时间戳ISO8601 文本实体抽取 对象/问题/严重度 ③ 时间对齐层(统一到“日”粒度) 传感器→日聚合 均值/最大/最小/标准差 天气→日聚合 降水/温度/风速/恶劣标记 进度/成本→日快照 完成率/累计成本/延期 文本→日汇总 事件数/最高严重度 缺失标记 不填0 ④ 特征化层(输出模型可用宽表) 数值特征:位移变化率、成本偏差率、资源到位率 类别特征:工区、任务类型、天气等级 时序特征:近7日滑动均值、趋势斜率、事件累积

四、特征化:把对齐后的宽表变成模型输入

对齐后的宽表每一行是“工区-日期”,但模型不能直接吃原始字段,需要构造有风险判别力的特征。特征化通常分三类:

数值特征:对连续量做变换和衍生。例如,传感器位移的“日变化率”比绝对值更能反映突变风险;成本偏差率 = (已发生成本 - 预算成本) / 预算成本,比单纯看成本金额更有意义;资源到位率 = 实际到场量 / 计划到场量,低于0.8时往往预示进度风险。

类别特征:工区编号、任务类型、天气等级等需要编码。对于树模型,可直接用标签编码;对于神经网络,建议用嵌入或独热编码。天气等级可按降水量和风速划分为“正常、注意、警告、严重”四级。

时序特征:风险往往有累积和趋势。常用构造包括:近7日滑动均值、近7日标准差、趋势斜率(用线性回归拟合近7日值)、事件累积计数(如近7日“严重”文本事件数)。这些特征能捕捉“逐渐恶化”或“突然爆发”两种模式。

以下是一个特征化配置的示例片段,展示如何用Python对对齐后的宽表生成时序特征:

import pandas as pd
import numpy as np

# df 为对齐后的宽表,索引为 (工区, 日期)
df = df.sort_values(['工区', '日期'])

# 近7日位移均值与标准差
df['位移_7日均值'] = df.groupby('工区')['位移_日最大'].transform(
    lambda s: s.rolling(7, min_periods=3).mean())
df['位移_7日标准差'] = df.groupby('工区')['位移_日最大'].transform(
    lambda s: s.rolling(7, min_periods=3).std())

# 近7日成本偏差率趋势斜率
def slope(series):
    if series.isna().sum() > 3:
        return np.nan
    x = np.arange(len(series))
    mask = ~series.isna()
    return np.polyfit(x[mask], series[mask], 1)[0]

df['成本偏差率_7日斜率'] = df.groupby('工区')['成本偏差率'].transform(
    lambda s: s.rolling(7, min_periods=4).apply(slope, raw=False))

# 近7日严重文本事件累积
df['严重事件_7日累积'] = df.groupby('工区')['严重事件数'].transform(
    lambda s: s.rolling(7, min_periods=1).sum())

运行后,宽表会新增若干列。判断特征是否有效,可以观察:在历史风险事件发生前7天,这些特征是否出现明显异动。例如,某工区在发生“基坑位移超限”前5天,“位移_7日斜率”由0.02mm/天升至0.15mm/天,“严重事件_7日累积”从0升至3。如果多个风险事件前都有类似模式,说明特征具有判别力。

五、数据底座的质量检查清单

在把数据交给模型之前,建议逐项核对以下内容,避免“垃圾进、垃圾出”:

检查项判断标准不通过时的处理
时间戳一致性所有数据源时间戳可对齐到同一时区统一转为UTC+8,记录转换日志
缺失率关键字段缺失率低于5%超过则回溯采集环节,补充数据源
唯一键冲突工区+日期组合无重复按规则去重,保留最新记录
数值范围位移、成本等无负值或极端离群标记异常,人工复核后决定是否剔除
特征覆盖率训练集与推理集特征分布一致检查特征计算逻辑是否随时间变化
特别注意:不要用未来数据填充过去。例如,用“最终实际成本”去填充“某日累计成本”,会造成数据泄漏,模型在训练集上表现极好,上线后完全失效。所有特征必须只使用该日期及之前可获得的数据。

完成以上四步后,你得到的就是一张按“工区-日期”组织的宽表,每一行包含进度、成本、资源、天气、传感器、文本六类特征。这张表既是模型训练的数据底座,也是后续预警规则和可解释性分析的共同基础。数据底座的质量,直接决定了风险预测能走多远。