2026 上海开源软件应用创新大赛正在报名,中国商飞为其中的「AI+工业软件赛道」设置了两道赛题。对开发者而言,这类比赛的价值不只在于训练模型,还在于理解 AI 如何进入真实工业流程:数据从哪里来、结果如何解释、异常怎样追溯、系统能否稳定部署。
中国商飞是大型客机项目的实施主体,C919 已于 2023 年 5 月完成首次商业飞行。把赛题放在这样的产业背景下看,参赛作品就不能只追求一张漂亮的精度表,还需要展示工程完整性。参赛者还可关注中国商飞校招绿色通道,但具体资格、流程和适用对象应以大赛及招聘方发布的正式规则为准,不能把“绿色通道”简单理解为录用承诺。
目前摘要没有披露两道赛题的具体任务、数据格式和评分细则。下面的代码以“工业设备多传感器异常检测”为演示假设,不代表官方赛题内容;拿到赛题材料后,需要替换字段、阈值和评估方式。
工业赛题真正考察的是一条链路
普通机器学习练习往往从一份整理好的 CSV 开始,以准确率结束。工业软件则需要覆盖更长的链路:
- 数据接入:识别时间戳、设备编号、工况和传感器单位,避免把数据质量问题误判成设备异常。
- 建模与验证:划分训练集时保留时间顺序或设备边界,防止同一设备相邻时刻的数据同时进入训练集和验证集。
- 结果解释:除了输出异常分数,还要指出是哪个变量、在哪个时间段偏离基线。
- 工程交付:固定依赖、参数和随机种子,提供一条命令完成运行,并保存机器可读结果。
- 业务闭环:说明告警之后由谁复核、如何抑制重复告警,以及误报和漏报分别会带来什么成本。
这意味着,参赛展示最好不要停在 Notebook。一个能从命令行运行、输出 CSV、记录配置的最小项目,通常比只能现场点击执行的原型更容易复现和评审。
可复制的异常检测基线
下面可以这样实践:使用 Python 标准库生成三路模拟传感器数据,根据前一段正常窗口计算均值和标准差,再通过最大绝对 Z-score 标记异常。它不是面向航空系统的生产算法,但适合作为数据管道、输出格式和可解释结果的起点。
将以下内容保存为 baseline.py:
#!/usr/bin/env python3
import argparse
import csv
import math
import random
from statistics import mean, pstdev
def build_data(rows: int, seed: int):
random.seed(seed)
data = []
for i in range(rows):
temperature = 70.0 + random.gauss(0, 0.8)
vibration = 0.20 + random.gauss(0, 0.015)
pressure = 101.0 + random.gauss(0, 0.5)
# 注入一段可验证的模拟异常。
if rows * 3 // 4 <= i < rows * 3 // 4 + 5:
temperature += 7.0
vibration += 0.12
data.append({
"timestamp": f"T{i:04d}",
"temperature": temperature,
"vibration": vibration,
"pressure": pressure,
})
return data
def fit_baseline(data, train_rows, features):
model = {}
for feature in features:
values = [row[feature] for row in data[:train_rows]]
sigma = pstdev(values)
model[feature] = {
"mean": mean(values),
"std": sigma if sigma > 1e-12 else 1.0,
}
return model
def score(row, model):
z_scores = {
feature: abs((row[feature] - stats["mean"]) / stats["std"])
for feature, stats in model.items()
}
reason = max(z_scores, key=z_scores.get)
return z_scores[reason], reason
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--rows", type=int, default=200)
parser.add_argument("--train-rows", type=int, default=100)
parser.add_argument("--threshold", type=float, default=4.0)
parser.add_argument("--seed", type=int, default=42)
parser.add_argument("--output", default="anomalies.csv")
args = parser.parse_args()
if not 10 <= args.train_rows < args.rows:
raise SystemExit("train-rows 必须不少于 10 且小于 rows")
features = ["temperature", "vibration", "pressure"]
data = build_data(args.rows, args.seed)
model = fit_baseline(data, args.train_rows, features)
results = []
for row in data:
anomaly_score, reason = score(row, model)
results.append({
**row,
"anomaly_score": round(anomaly_score, 4),
"is_anomaly": int(anomaly_score >= args.threshold),
"reason": reason,
})
fields = ["timestamp", *features, "anomaly_score", "is_anomaly", "reason"]
with open(args.output, "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=fields)
writer.writeheader()
writer.writerows(results)
count = sum(row["is_anomaly"] for row in results)
print(f"wrote {len(results)} rows to {args.output}; anomalies={count}")
print("baseline model:", model)
if __name__ == "__main__":
main()
直接运行:
python3 baseline.py --rows 200 --train-rows 100 --threshold 4.0
head -n 8 anomalies.csv
接入真实赛题数据时,至少需要改动三处:
- 用 CSV、数据库或官方数据接口替换
build_data(); - 将
features改成允许参与训练的字段,并统一单位、缺失值和采样频率; - 按官方指标选择阈值,不能根据测试集结果反复调参。
如果训练数据混入异常,均值和标准差会被污染。后续可以尝试中位数与 MAD、Isolation Forest、时序自编码器等方法,但复杂模型必须与同一数据划分下的简单基线比较。否则,模型规模增加并不等于有效提升。
让作品像软件,而不只是一次实验
评审者需要知道结果是怎样产生的。可以把关键参数放进独立配置文件,例如 config.yaml:
project: industrial-anomaly-baseline
seed: 42
data:
timestamp_column: timestamp
entity_column: equipment_id
features:
- temperature
- vibration
- pressure
validation:
strategy: time_split
train_ratio: 0.7
model:
name: zscore_baseline
threshold: 4.0
output:
prediction_file: artifacts/predictions.csv
metrics_file: artifacts/metrics.json
这份配置只是建议格式;如果要直接读取 YAML,需要引入相应解析库。项目提交时还可以附上:
README.md:环境、数据目录和复现命令;requirements.txt或锁定文件:明确依赖版本;src/:训练、推理和评估代码分离;artifacts/:指标、预测结果和模型元数据;- 测试用例:覆盖空文件、缺失字段、重复时间戳和单位异常。
演示界面可以展示趋势图、异常区间和原因变量,但不要让可视化掩盖数据泄漏、不可复现或评价指标选择错误等基础问题。
提交前检查:准确率之外还要回答什么
围绕工业场景准备答辩时,可以逐项确认:
- 数据划分是否遵循时间、设备或批次边界?
- 是否记录数据版本、代码提交、模型参数和运行环境?
- 告警能否给出时间、对象、分数与主要影响变量?
- 阈值变化后,误报率和漏报率会怎样变化?
- 模型遇到字段缺失、分布漂移或输入越界时如何降级?
- 方案是否避免上传敏感数据,并遵守赛题的数据使用与开源许可要求?
- 是否明确声明原型不能直接用于真实航空器运行或安全决策?
中国商飞设置赛题,使参赛者有机会把开源技术放到大型工业场景中检验。更稳妥的参赛策略,是先建立可复现基线,再针对正式题目逐步增加模型复杂度,并把每次改进映射到明确指标。模型分数决定方案能否进入视野,工程边界、解释能力和交付质量则决定它是否像一个真正可用的工业软件原型。