XAI 十年回顾:可解释 AI 在碰撞严重度预测中的系统综述(Heliyon 2026 论文解读)

XAI 十年回顾:可解释 AI 在碰撞严重度预测中的系统综述

论文信息

项目 内容
标题 A systematic mapping review of explainable machine and deep learning approaches for road traffic crash severity prediction: A decade-long review (2014-2024)
期刊 Heliyon
年份 2026
DOI 10.1016/j.heliyon.2026.e45513
团队 Karim Asif Sattar 等,Universiti Putra Malaysia
综述范围 237 篇原始研究(2014-2024)
初始检索 3616 条记录,去重后 2768 条,PRISMA 筛选至 237 篇

1. 核心发现

1.1 精度 vs 可解释性的根本矛盾

模型类型 精度 可解释性 在碰撞预测中的使用
逻辑回归/决策树 ⚠️ 中等 ✅ 透明 2014前主流
随机森林/XGBoost ✅ 高 ⚠️ 半透明 2014后主流
深度神经网络 ✅ 最高 ❌ 黑箱 2020后增长
XAI 增强(SHAP/LIME) ✅ 高 ✅ 可解释 关键趋势

1.2 关键数据

指标 数值
综述论文数 237 篇
最常用算法 随机森林(109 次应用)
最常用 XAI 方法 SHAP(SHapley Additive exPlanations)
特征选择使用率 ~64% 的研究采用
PESA-II 降维案例 31 变量→13 变量,精度 94.7%

2. 算法分布分析

2.1 机器学习 vs 深度学习

类别 占比 代表算法
机器学习 ~60% 随机森林、决策树、SVM、XGBoost、LightGBM、CatBoost
深度学习 ~25% ANN、CNN、LSTM、GNN
混合方法 ~15% ML+DL 融合

2.2 XAI 方法排名

XAI 方法 原理 优势 使用频率
SHAP 博弈论 Shapley 值 唯一归因保证、局部精度、一致性 🔴 最高
LIME 局部线性近似 模型无关、计算高效 🟡 第二
特征重要性 树结构杂质减少 内置于树模型 🟡 常用
PDP/ICE 部分依赖图 直观可视化 🟢 中等
Attention 权重 注意力机制 内置于 Transformer 🟢 增长中

3. SHAP 原理与代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""
SHAP (SHapley Additive exPlanations) 在碰撞严重度预测中的实现
基于博弈论的模型解释框架
"""

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from dataclasses import dataclass
from typing import List, Dict
import warnings
warnings.filterwarnings('ignore')

# 尝试导入 SHAP
try:
import shap
HAS_SHAP = True
except ImportError:
HAS_SHAP = False
print("SHAP 未安装,使用自定义实现")

@dataclass
class CrashFeature:
"""碰撞特征定义"""
name: str
description: str
value_range: tuple
typical_impact: str # 对严重度的影响方向

# 碰撞严重度预测的关键特征
CRASH_FEATURES = [
CrashFeature("speed_limit", "道路限速 (km/h)", (20, 120), "正影响"),
CrashFeature("vehicle_type", "车辆类型", (0, 5), "大型车更严重"),
CrashFeature("collision_type", "碰撞类型", (0, 5), "正面>追尾>侧面"),
CrashFeature("weather", "天气条件", (0, 3), "恶劣天气加剧"),
CrashFeature("lighting", "光照条件", (0, 2), "夜间更严重"),
CrashFeature("road_geometry", "道路几何", (0, 3), "弯道更危险"),
CrashFeature("driver_age", "驾驶员年龄", (18, 80), "极端年龄更严重"),
CrashFeature("alcohol_involved", "酒精涉及", (0, 1), "正影响"),
CrashFeature("seatbelt_used", "安全带使用", (0, 1), "负影响"),
CrashFeature("airbag_deployed", "气囊展开", (0, 1), "负影响"),
]

def generate_crash_data(n_samples=2000):
"""生成模拟碰撞数据"""
np.random.seed(42)

data = np.zeros((n_samples, len(CRASH_FEATURES)))
for i, feat in enumerate(CRASH_FEATURES):
low, high = feat.value_range
if low == 0 and high == 1:
data[:, i] = np.random.choice([0, 1], n_samples, p=[0.7, 0.3])
else:
data[:, i] = np.random.uniform(low, high, n_samples)

# 生成标签(严重度:0=轻微, 1=中等, 2=严重)
severity = np.zeros(n_samples)
for i in range(n_samples):
score = 0
score += (data[i, 0] - 20) / 100 * 0.3 # 限速
score += data[i, 7] * 0.25 # 酒精
score += (1 - data[i, 8]) * 0.2 # 未系安全带
score += (data[i, 1] / 5) * 0.15 # 车辆类型
score += (data[i, 2] / 5) * 0.1 # 碰撞类型
score += np.random.normal(0, 0.05) # 噪声

if score > 0.5:
severity[i] = 2 # 严重
elif score > 0.25:
severity[i] = 1 # 中等
else:
severity[i] = 0 # 轻微

return data, severity

# 简化版 SHAP 值计算
def simplified_shap_values(model, X_background, X_explain):
"""
简化版 SHAP 值估算(实际应使用 shap 库)

基于 Kernel SHAP 的近似:
1. 从背景数据中采样
2. 逐个特征扰动,观察预测变化
"""
n_features = X_explain.shape[1]
n_background = len(X_background)
shap_values = np.zeros_like(X_explain)

base_value = np.mean([
np.mean(model.predict_proba(X_background)[0])
for _ in range(min(n_background, 100))
])

for i in range(len(X_explain)):
x = X_explain[i]
for j in range(n_features):
# 创建扰动版本
x_perturbed = x.copy()
x_perturbed[j] = np.random.choice(X_background[:, j])

# 原始预测
pred_orig = model.predict_proba([x])[0]
pred_pert = model.predict_proba([x_perturbed])[0]

# SHAP 值近似
shap_values[i, j] = np.mean(pred_orig - pred_pert)

return shap_values

# 使用示例
if __name__ == "__main__":
# 生成数据
X, y = generate_crash_data(2000)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

feature_names = [f.name for f in CRASH_FEATURES]

# 训练随机森林
rf = RandomForestClassifier(n_estimators=100, max_depth=8, random_state=42)
rf.fit(X_train, y_train)

accuracy = rf.score(X_test, y_test)
print(f"模型准确率: {accuracy:.3f}")

# 特征重要性
importances = rf.feature_importances_
print("\n=== 随机森林特征重要性 ===")
for name, imp in sorted(zip(feature_names, importances),
key=lambda x: -x[1]):
print(f" {name:25s}: {imp:.4f}")

# SHAP 值(使用 shap 库或简化版)
if HAS_SHAP:
explainer = shap.TreeExplainer(rf)
shap_values = explainer.shap_values(X_test[:50])
print(f"\nSHAP 值 shape: {np.array(shap_values).shape}")

if isinstance(shap_values, list):
# 多分类:每个类一组 SHAP 值
for cls in range(min(3, len(shap_values))):
mean_shap = np.mean(np.abs(shap_values[cls]), axis=0)
top_idx = np.argsort(-mean_shap)[:3]
print(f"\n类别 {cls} 前三大特征:")
for idx in top_idx:
print(f" {feature_names[idx]:25s}: {mean_shap[idx]:.4f}")
else:
print("\n使用简化版 SHAP 估算...")
shap_vals = simplified_shap_values(rf, X_train[:100], X_test[:10])
mean_abs = np.mean(np.abs(shap_vals), axis=0)
print("=== 简化 SHAP 平均绝对值 ===")
for name, val in sorted(zip(feature_names, mean_abs),
key=lambda x: -x[1]):
print(f" {name:25s}: {val:.4f}")

4. 对座舱安全 XAI 的启示

4.1 从碰撞预测到座舱 DMS 的 XAI 迁移

碰撞预测 XAI 座舱 DMS XAI 对应
SHAP 解释碰撞严重度因素 SHAP 解释疲劳/分心判断依据
特征重要性排序 DMS 各指标权重排序
LIME 局部解释 单次警告触发的局部归因
PDP 部分依赖图 PERCLOS 阈值对检测率的影响曲线

4.2 可落地的开发建议

优先级 建议 理由
🔴 P0 DMS 警告附带 SHAP 解释 每次触发警告时记录 SHAP 值,用于事后审计和模型调优
🟡 P1 特征重要性可视化 DMS 模型训练时使用 SHAP 进行特征重要性分析
🟡 P1 LIME 局部解释 对误报/漏报样本进行 LIME 分析,理解模型决策边界
🟢 P2 XAI 驾驶员反馈 警告时向驾驶员展示简化的解释(”检测到闭眼过长”)

4.3 XAI 在 DMS 中的架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
DMS XAI 架构:可解释的驾驶员状态监测系统
"""

class ExplainableDMS:
"""
可解释 DMS 框架

每次状态判断都附带 SHAP 解释
"""

def __init__(self, model, background_data):
self.model = model
self.background = background_data

def predict_with_explanation(self, features: dict) -> dict:
"""
带解释的预测

Returns:
{
'state': 'normal' | 'fatigue' | 'distraction',
'confidence': float,
'top_factors': [(feature, shap_value), ...],
'explanation_text': str
}
"""
# 模型预测
state = self.model.predict([list(features.values())])[0]
proba = self.model.predict_proba([list(features.values())])[0]

# SHAP 解释(简化版)
shap_values = self._compute_shap(features)

# 排序贡献最大的特征
feature_names = list(features.keys())
ranked = sorted(zip(feature_names, shap_values),
key=lambda x: abs(x[1]), reverse=True)

top_factors = [(f, v) for f, v in ranked[:3]]

# 生成自然语言解释
explanation = self._generate_explanation(state, top_factors)

return {
'state': state,
'confidence': float(max(proba)),
'top_factors': top_factors,
'explanation_text': explanation
}

def _compute_shap(self, features):
"""简化 SHAP 计算"""
# 实际应使用 shap.TreeExplainer 或 shap.KernelExplainer
return np.random.randn(len(features)) * 0.1

def _generate_explanation(self, state, factors):
"""生成自然语言解释"""
if state == 'fatigue':
top = factors[0]
return f"检测到疲劳状态。主要因素:{top[0]}(贡献度 {top[1]:.3f})"
elif state == 'distraction':
return f"检测到分心状态。主要因素:{factors[0][0]}"
return "驾驶状态正常"


# 测试
if __name__ == "__main__":
from sklearn.ensemble import RandomForestClassifier

# 模拟数据
np.random.seed(42)
X = np.random.randn(1000, 5)
y = (X[:, 0] + X[:, 1] > 0).astype(int)

model = RandomForestClassifier(n_estimators=50, random_state=42)
model.fit(X, y)

xdms = ExplainableDMS(model, X[:100])

result = xdms.predict_with_explanation({
'perclos': 0.25,
'blink_rate': 22,
'gaze_away': 0.4,
'head_pitch': 15,
'yaw_var': 8
})

print("=== 可解释 DMS 结果 ===")
print(f"状态: {result['state']}")
print(f"置信度: {result['confidence']:.2f}")
print(f"解释: {result['explanation_text']}")
print("主要因素:")
for f, v in result['top_factors']:
print(f" {f}: {v:.4f}")

5. 特征选择方法论

5.1 综述发现的特征选择方法

方法类别 代表算法 使用率 优势
包装法 Boruta, RFE 中 直接优化目标函数
正则化 LASSO, Elastic Net 高 嵌入式,高效
信息论 信息增益, 增益比 高 快速,可解释
统计检验 卡方, Pearson 中 通用
优化算法 遗传算法, NSGA-II 低但增长 全局最优

5.2 对 DMS 特征选择的启示

DMS 模型通常有 20-50 个输入特征,特征选择同样关键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""
DMS 特征选择示例
使用 Boruta + SHAP 组合方法
"""

def select_dms_features(X, y, feature_names):
"""
DMS 特征选择流程

1. Boruta 初筛(去除无关特征)
2. SHAP 排序(量化贡献)
3. 交叉验证确认(避免过拟合)
"""
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

rf = RandomForestClassifier(n_estimators=100, random_state=42)

# Step 1: 基于随机森林的重要性
rf.fit(X, y)
importances = rf.feature_importances_

# 排序
ranked = sorted(zip(feature_names, importances),
key=lambda x: -x[1])

# Step 2: 逐步消融验证
results = []
for n_features in range(3, len(feature_names) + 1):
selected = [f for f, _ in ranked[:n_features]]
idx = [feature_names.index(f) for f in selected]

score = cross_val_score(rf, X[:, idx], y, cv=5, scoring='f1').mean()
results.append((n_features, score, selected))

# 找最佳数量
best = max(results, key=lambda x: x[1])

return best

# 示例特征列表
DMS_FEATURES = [
'perclos', 'blink_rate', 'blink_duration', 'blink_interval_std',
'gaze_x', 'gaze_y', 'gaze_dispersion', 'saccade_freq',
'head_pitch', 'head_yaw', 'head_roll', 'nod_freq',
'mouth_open', 'facial_symmetry', 'muscle_tone',
'steering_reversals', 'lane_deviation', 'speed_variability'
]

print(f"DMS 特征总数: {len(DMS_FEATURES)}")
print("推荐选择方法: Boruta + SHAP + 交叉验证")
print("预期最优特征数: 8-12(减少冗余同时保持精度)")

6. 技术路线判断

6.1 核心洞察

  1. SHAP 已成为 XAI 事实标准——在碰撞预测领域如此,在 DMS 领域也将如此
  2. 精度和可解释性不必二选一——XAI 方法可以在保持高精度的同时提供解释
  3. 特征选择是模型效率的关键——DMS 模型应从 50+ 特征降至 10-15 个关键特征
  4. XAI 是法规合规的工具——Euro NCAP 要求 DMS 决策可审计,SHAP 提供了审计手段

6.2 对 Euro NCAP 合规的价值

Euro NCAP 未来可能要求 DMS 厂商提供模型决策可解释性报告:

  • 为什么触发警告?(SHAP 值 top-3 因素)
  • 模型的决策边界在哪里?(PDP 图)
  • 误报的主要原因是什么?(LIME 局部解释)

6.3 长期趋势

XAI 将从”可选”变为”必选”:

阶段 时间 XAI 要求
当前 2026 无明确要求
近期 2027-2028 OEM 内部审计要求
中期 2029-2030 Euro NCAP 建议提供
远期 2031+ 法规要求 XAI 报告

7. 参考


XAI 十年回顾:可解释 AI 在碰撞严重度预测中的系统综述(Heliyon 2026 论文解读)
https://dapalm.com/2026/10/05/2026-10-05-017-xai-crash-severity-prediction-systematic-review-heliyon2026/
作者
Mars
发布于
2026年10月5日
许可协议