4. 数据准备与特征工程
成本估算模型的预测精度,高度依赖输入数据的质量与特征工程的合理性。本章聚焦于将原始成本历史数据转化为机器学习模型可用的高质量特征矩阵,涵盖数据收集、清洗、特征选择与标准化四个核心环节。
4.1 成本历史数据的收集范围与来源
数据收集是联动机制的基础。需系统性地采集与软件项目成本相关的多维度数据,确保覆盖项目全生命周期。
| 数据类别 | 典型字段 | 数据来源 |
|---|---|---|
| 项目基本信息 | 项目ID、开始/结束日期、团队规模、开发方法论 | 项目管理工具(Jira、MS Project) |
| 规模度量 | 代码行数(LOC)、功能点(FP)、故事点(SP) | 代码仓库、需求管理工具 |
| 成本与工作量 | 实际人月、人力费率、硬件/软件采购成本 | 财务系统、工时记录系统 |
| 过程度量 | 需求变更次数、缺陷密度、测试覆盖率 | 测试管理工具、CI/CD 流水线 |
| 环境与上下文 | 技术栈、团队经验水平、项目复杂度评级 | 项目复盘报告、专家评估 |
收集策略提示: 优先收集已完成项目的完整数据,确保每个样本都包含“实际成本”标签。对于缺失严重的历史项目,可考虑将其作为验证集而非训练集。
4.2 数据清洗:处理缺失、异常与不一致
原始数据通常包含噪声,需通过清洗流程提升数据可靠性。清洗步骤应形成可复用的管道,以便在模型迭代时重复执行。
- 缺失值处理: 对于数值型字段(如实际人月),若缺失率 < 5%,采用中位数填充;若缺失率在 5%-20%,使用 KNN 插补;若缺失率 > 20%,考虑删除该特征或样本。
- 异常值检测: 使用 IQR(四分位距)或 Z-score 方法识别成本异常项目。例如,实际人月超出均值 ±3 倍标准差的项目需人工复核。
- 一致性校验: 检查逻辑矛盾,如“开始日期 > 结束日期”、“功能点数为负值”、“工作量记录为 0 但交付了代码”。
- 重复记录去重: 基于项目ID和日期去重,保留最新或最完整的记录。
清洗陷阱: 不要直接删除所有异常值。某些异常项目(如大型重构或技术债务偿还)可能包含重要的成本驱动信息,应标记而非简单剔除。
4.3 特征选择:识别关键成本驱动因子
特征选择旨在从原始字段中筛选出与成本强相关、且彼此间冗余度低的特征子集,以降低过拟合风险并提升模型可解释性。
常用的特征选择方法分为三类:
| 方法类别 | 代表算法 | 适用场景 |
|---|---|---|
| 过滤法 | 皮尔逊相关系数、互信息、方差阈值 | 快速初筛,适用于特征数量 > 100 的场景 |
| 包裹法 | 递归特征消除(RFE)、前向/后向搜索 | 特征数量较少(< 50),追求最优子集 |
| 嵌入法 | Lasso 回归、决策树特征重要性、XGBoost 重要性 | 模型训练与特征选择同步进行,效率较高 |
在成本估算场景中,建议优先使用 嵌入法(如 Lasso 或树模型重要性),因为它能同时考虑特征与目标变量的非线性关系,并自动处理多重共线性。
4.4 标准化处理:统一量纲与分布形态
不同成本驱动因子通常具有不同的量纲(如人月 vs. 代码行数),直接输入模型会导致梯度下降不稳定或距离度量失真。标准化处理是特征工程的关键步骤。
4.4.1 常用标准化方法对比
| 方法 | 公式 | 输出范围 | 适用模型 |
|---|---|---|---|
| Z-score 标准化 | \( z = \frac{x - \mu}{\sigma} \) | 均值 0,标准差 1 | 线性回归、SVM、神经网络 |
| Min-Max 归一化 | \( x' = \frac{x - x_{min}}{x_{max} - x_{min}} \) | [0, 1] | KNN、神经网络(输入层) |
| Robust 缩放 | \( x' = \frac{x - median}{IQR} \) | 受异常值影响小 | 含异常值的成本数据 |
成本估算推荐: 优先使用 Robust 缩放。成本数据常包含因项目规模差异导致的右偏分布和异常值,Robust 缩放基于中位数和四分位距,对异常值不敏感,能保留数据的相对排序信息。
4.4.2 标准化在联动机制中的位置
标准化应在数据划分(训练集/测试集)之后进行,且仅基于训练集计算缩放参数(均值、标准差、中位数等),再应用到测试集,避免数据泄露。
# Python 示例:使用 RobustScaler 进行标准化
from sklearn.preprocessing import RobustScaler
from sklearn.model_selection import train_test_split
# 假设 X 为特征矩阵,y 为成本标签
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 初始化 RobustScaler
scaler = RobustScaler()
# 仅在训练集上拟合
X_train_scaled = scaler.fit_transform(X_train)
# 使用训练集的参数转换测试集
X_test_scaled = scaler.transform(X_test)
4.5 数据准备与特征工程的完整管道
将上述环节整合为可重复执行的管道,是联动机制自动化的前提。以下 SVG 展示了从原始数据到模型输入的完整流程。
4.6 联动机制中的数据版本控制
成本历史数据会随项目积累而持续更新。为保障估算模型的可追溯性,建议对每次数据准备与特征工程的结果进行版本控制。
- 数据快照: 每次管道执行后,保存清洗后的特征矩阵与对应的特征选择配置。
- 特征元数据: 记录每个特征的来源、清洗规则、标准化参数(如中位数、IQR 值)。
- 模型-数据映射: 在模型注册时,关联其训练所用的数据版本 ID,便于回滚与审计。
工程实践: 使用 DVC(Data Version Control)或 MLflow 对特征工程管道进行版本管理,确保“数据-特征-模型”三者版本一致,这是成本估算联动机制可复现性的基石。