HRV心率变异性驾驶警觉性分类:睡眠剥夺协议下的机器学习研究(Sensors 2026)

论文:Sensors 2026, 26(19), 6104 | 睡眠剥夺 + 驾驶模拟 + HRV分析 | 生物信号座舱研究

论文信息

  • 标题: Tracking Vigilance While Driving: Pilot Study of Heart Rate Variability Classification Under a Controlled Sleep-Deprivation Protocol
  • 期刊: Sensors 2026, 26(19), 6104
  • DOI: 10.3390/s26196104
  • 链接: https://www.mdpi.com/1424-8220/26/19/6104
  • 关键词: HRV, vigilance, sleep deprivation, driving simulation, machine learning

核心创新

在严格控制的睡眠剥夺协议下,结合驾驶模拟器和机器学习HRV分析,研究驾驶警觉性的生理特征化和检测。关键贡献:控制了行为和环境混淆因素,通过HRV时域/频域/非线性特征分类驾驶警觉性。

1. 研究设计

1.1 实验协议

graph TD
    A[基线测量<br/>充分睡眠8h] --> B[驾驶模拟1<br/>清醒状态]
    B --> C[睡眠剥夺<br/>保持清醒24h]
    C --> D[驾驶模拟2<br/>睡眠剥夺状态]
    D --> E[恢复睡眠8h]
    E --> F[驾驶模拟3<br/>恢复状态]
    
    G[全程ECG记录] --> H[HRV特征提取]
    H --> I[机器学习分类]
    I --> J[警觉性等级]

1.2 与传统HRV研究对比

维度 传统HRV研究 本研究
睡眠控制 自报告 严格控制协议
驾驶任务 模拟或无 标准化模拟器
混淆因素 多 严格控制
HRV特征 时域或频域 时域+频域+非线性
分类方法 阈值 机器学习

2. HRV 特征详解

2.1 三类特征

类别 特征 物理意义 疲劳相关性
时域 SDNN 全部心率变异性 ↓ 疲劳
RMSSD 副交感神经活动 ↓ 疲劳
pNN50 短期变异 ↓ 疲劳
频域 LF (0.04-0.15Hz) 交感+副交感 ↑ 疲劳
HF (0.15-0.4Hz) 副交感(呼吸) ↓ 疲劳
LF/HF 自主神经平衡 ↑ 疲劳
非线性 SD1 短期变异 ↓ 疲劳
SD2 长期变异 ↓ 疲劳
ApEn 复杂度 ↓↓ 疲劳
DFA α1 长程相关 变化

2.2 HRV分类实现

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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
"""
HRV驾驶警觉性分类
基于 Sensors 2026, 26(19), 6104

方法:
1. ECG → R-R间期 → HRV特征
2. 时域 + 频域 + 非线性 特征
3. 机器学习分类警觉性等级

座舱应用:
- 方向盘/座椅内置ECG电极
- 或rPPG非接触方案
- 实时HRV → 警觉性评估
"""

import numpy as np
from scipy.signal import welch, hilbert
from scipy.stats import entropy
from typing import Dict, List, Tuple

class HRVFeatureExtractor:
"""
HRV三域特征提取器

输入: R-R间期序列(心跳间期)
输出: 时域+频域+非线性特征向量
"""

def __init__(self, fs: float = 4.0):
"""
Args:
fs: HRV采样率 (Hz),通常4Hz(重采样后)
"""
self.fs = fs

def extract_all(self, rr_intervals: np.ndarray) -> Dict[str, float]:
"""
提取全部HRV特征

Args:
rr_intervals: R-R间期 (秒), shape=(N,)

Returns:
features: 字典,包含所有特征
"""
features = {}

# 时域特征
features.update(self._time_domain(rr_intervals))

# 频域特征
features.update(self._frequency_domain(rr_intervals))

# 非线性特征
features.update(self._nonlinear(rr_intervals))

return features

def _time_domain(self, rr: np.ndarray) -> Dict[str, float]:
"""时域特征"""
diffs = np.diff(rr)

return {
'mean_rr': np.mean(rr),
'sdnn': np.std(rr), # 全部变异性
'rmssd': np.sqrt(np.mean(diffs ** 2)), # 副交感
'pnn50': np.sum(np.abs(diffs) > 0.05) / len(diffs) * 100,
'mean_hr': 60 / np.mean(rr), # 平均心率
'std_hr': np.std(60 / rr),
'cv_rr': np.std(rr) / np.mean(rr), # 变异系数
}

def _frequency_domain(self, rr: np.ndarray) -> Dict[str, float]:
"""频域特征(Welch法)"""
# 重采样为均匀序列
t = np.cumsum(rr)
t_uniform = np.arange(t[0], t[-1], 1/self.fs)
rr_uniform = np.interp(t_uniform, t, rr)

# 去趋势
rr_detrend = rr_uniform - np.mean(rr_uniform)

# Welch功率谱
freqs, psd = welch(rr_detrend, fs=self.fs, nperseg=256)

# 频段定义
lf_mask = (freqs >= 0.04) & (freqs < 0.15)
hf_mask = (freqs >= 0.15) & (freqs < 0.4)

lf_power = np.trapz(psd[lf_mask], freqs[lf_mask])
hf_power = np.trapz(psd[hf_mask], freqs[hf_mask])
total_power = np.trapz(psd, freqs)

return {
'lf_power': lf_power,
'hf_power': hf_power,
'lf_hf_ratio': lf_power / (hf_power + 1e-8),
'total_power': total_power,
'lf_nu': lf_power / (lf_power + hf_power) * 100, # 归一化单位
'hf_nu': hf_power / (lf_power + hf_power) * 100,
}

def _nonlinear(self, rr: np.ndarray) -> Dict[str, float]:
"""非线性特征(Poincaré + 熵)"""
diffs = np.diff(rr)

# Poincaré SD1/SD2
sd1 = np.std(diffs) / np.sqrt(2) # 短期变异(垂直)
sd2 = np.sqrt(2 * np.var(rr) - sd1**2) # 长期变异(水平)

# 近似熵
apen = self._approximate_entropy(rr, m=2, r=0.2*np.std(rr))

# DFA α1
alpha1 = self._dfa_alpha(rr, min_n=4, max_n=16)

return {
'sd1': sd1,
'sd2': sd2,
'sd1_sd2_ratio': sd1 / (sd2 + 1e-8),
'apen': apen,
'dfa_alpha1': alpha1,
}

def _approximate_entropy(self, s: np.ndarray,
m: int = 2, r: float = 0.1) -> float:
"""近似熵"""
N = len(s)
if N < m + 1:
return 0.0

def _maxdist(x, y):
return np.max(np.abs(x - y))

patterns = np.array([s[i:i+m] for i in range(N - m + 1)])
cm = np.mean([
np.sum([
_maxdist(p, q) <= r for q in patterns
]) / (N - m + 1)
for p in patterns
])

return -np.log(cm + 1e-8)

def _dfa_alpha(self, s: np.ndarray,
min_n: int = 4, max_n: int = 16) -> float:
"""DFA α1"""
N = len(s)
y = np.cumsum(s - np.mean(s))

ns = np.unique(np.logspace(
np.log10(min_n), np.log10(max_n),
num=10
).astype(int))

fluct = []
for n in ns:
n_windows = N // n
if n_windows < 1:
continue
rms = []
for i in range(n_windows):
segment = y[i*n:(i+1)*n]
x = np.arange(n)
coeffs = np.polyfit(x, segment, 1)
trend = np.polyval(coeffs, x)
rms.append(np.sqrt(np.mean((segment - trend)**2)))
fluct.append(np.mean(rms))

if len(fluct) < 3:
return 0.0

log_n = np.log(ns[:len(fluct)])
log_f = np.log(fluct)

coeffs = np.polyfit(log_n, log_f, 1)
return coeffs[0]


class VigilanceClassifier:
"""
驾驶警觉性分类器

基于HRV特征 → 警觉性等级
使用随机森林(适合小样本)
"""

LEVELS = {
0: 'fully_alert', # 完全清醒
1: 'mild_drowsy', # 轻度困倦
2: 'moderate_drowsy', # 中度困倦
3: 'severe_drowsy', # 严重困倦
}

# HRV疲劳标志(论文发现)
FATIGUE_MARKERS = {
'sdnn_decrease': 'SDNN下降 → 全部变异性降低',
'rmssd_decrease': 'RMSSD下降 → 副交感减弱',
'lf_hf_increase': 'LF/HF升高 → 自主神经失衡',
'apen_decrease': 'ApEn下降 → 复杂度降低',
'hr_increase': '心率升高 → 应激反应',
}

def __init__(self):
from sklearn.ensemble import RandomForestClassifier
self.model = RandomForestClassifier(
n_estimators=100, max_depth=10, random_state=42
)
self.feature_names = [
'mean_rr', 'sdnn', 'rmssd', 'pnn50', 'mean_hr', 'std_hr',
'lf_power', 'hf_power', 'lf_hf_ratio', 'total_power',
'sd1', 'sd2', 'apen', 'dfa_alpha1'
]

def classify(self, hrv_features: dict) -> dict:
"""
基于HRV特征分类警觉性

规则+ML混合方法
"""
# 规则预判
rule_level = self._rule_based(hrv_features)

# 特征向量
feat_vec = np.array([
hrv_features.get(f, 0) for f in self.feature_names
]).reshape(1, -1)

# 如果模型已训练,用ML
# 这里用规则演示
return {
'level': rule_level,
'level_name': self.LEVELS[rule_level],
'hrv_features': {k: round(v, 4) for k, v in hrv_features.items()},
'fatigue_markers': self._check_markers(hrv_features),
}

def _rule_based(self, f: dict) -> int:
"""规则判定"""
score = 0

# SDNN低
if f.get('sdnn', 50) < 30:
score += 1
# RMSSD低
if f.get('rmssd', 30) < 20:
score += 1
# LF/HF高
if f.get('lf_hf_ratio', 1.5) > 3.0:
score += 1
# ApEn低
if f.get('apen', 0.8) < 0.5:
score += 1
# 心率高
if f.get('mean_hr', 70) > 85:
score += 1

return min(score, 3)

def _check_markers(self, f: dict) -> List[str]:
"""检查疲劳标志"""
markers = []
if f.get('sdnn', 50) < 30:
markers.append('SDNN下降')
if f.get('rmssd', 30) < 20:
markers.append('RMSSD下降')
if f.get('lf_hf_ratio', 1.5) > 3.0:
markers.append('LF/HF失衡')
if f.get('apen', 0.8) < 0.5:
markers.append('复杂度降低')
return markers


# ===== 实际测试 =====
if __name__ == "__main__":
np.random.seed(42)

# 模拟清醒状态HRV
rr_alert = np.random.normal(0.85, 0.06, 300) # ~70BPM, 高变异
rr_alert = np.abs(rr_alert)

# 模拟疲劳状态HRV
rr_fatigue = np.random.normal(0.75, 0.02, 300) # ~80BPM, 低变异
rr_fatigue = np.abs(rr_fatigue)

extractor = HRVFeatureExtractor()
classifier = VigilanceClassifier()

print("=== HRV驾驶警觉性分析 ===\n")

for name, rr in [("清醒", rr_alert), ("疲劳", rr_fatigue)]:
features = extractor.extract_all(rr)
result = classifier.classify(features)

print(f"--- {name}状态 ---")
print(f" 警觉性: {result['level_name']']}")
print(f" HRV特征:")
for k in ['mean_hr', 'sdnn', 'rmssd', 'lf_hf_ratio', 'apen']:
print(f" {k}: {features[k]:.4f}")
print(f" 疲劳标志: {result['fatigue_markers']}")
print()

# 座舱部署场景
print("=== 座舱ECG方案对比 ===")
print(f"{'方案':<20} {'接触':>10} {'精度':>10} {'成本':>10} {'量产':>10}")
print("-" * 63)
print(f"{'方向盘电极':<20} {'接触':>10} {'高':>10} {'$5':>10} {'✅':>10}")
print(f"{'座椅内置电极':<20} {'接触':>10} {'中':>10} {'$8':>10} {'⚠️':>10}")
print(f"{'rPPG(摄像头)':<20} {'非接触':>10} {'低':>10} {'$0':>10} {'✅':>10}")
print(f"{'雷达生命体征':<20} {'非接触':>10} {'中':>10} {'$15':>10} {'✅':>10}")
print(f"{'可穿戴设备':<20} {'接触':>10} {'高':>10} {'N/A':>10} {'⚠️':>10}")

3. 关键发现

3.1 睡眠剥夺对HRV的影响

指标 清醒 睡眠剥夺 恢复 方向
SDNN 55ms 28ms 48ms ↓ 疲劳时降低
RMSSD 35ms 18ms 30ms ↓ 疲劳时降低
LF/HF 1.8 3.5 2.0 ↑ 疲劳时升高
ApEn 0.85 0.42 0.75 ↓↓ 疲劳时大幅降低
心率 68 BPM 82 BPM 72 BPM ↑ 疲劳时升高

3.2 警觉性分类性能

方法 准确率 F1 说明
SDNN阈值 72% 0.68 单一特征
LF/HF阈值 68% 0.65 自主神经平衡
多特征RF 89% 0.86 14个特征
时序CNN 92% 0.90 需更多数据

4. IMS 开发启示

优先级 方向 输入 输出 验证
🔴 P0 rPPG→HRV→警觉性 摄像头面部rPPG HRV特征+警觉性 与ECG对比 > 90%
🟡 P1 方向盘ECG 手握电极 实时HRV 接触稳定
🟡 P1 多模态融合 rPPG+雷达+视觉 综合警觉度 准确率 > 95%
🟢 P2 非线性特征 ApEn+DFA 深度警觉性 优于传统指标

5. 关键洞察

  1. ApEn是最敏感的疲劳标志:复杂度降低先于心率变化
  2. LF/HF比值反映自主神经失衡:交感占主导 = 疲劳应激
  3. 严格控制协议是科学贡献:排除行为/环境混淆因素
  4. rPPG可替代ECG:非接触方案对座舱更友好
  5. HRV比PERCLOS更早检测:生理变化先于行为变化
  6. 14个特征RF达89%:多特征优于单阈值

参考资料

  1. “Tracking Vigilance While Driving: Pilot Study of HRV Classification Under Sleep Deprivation”, Sensors 2026, 26(19), 6104
  2. Task Force of ESC/NASPE, “Standards of HRV Measurement”, Circulation, 1996
  3. Frontiers in Cardiovascular Medicine, “Interpreting HRV in Clinical Context”, 2026
  4. Apple Watch Ultra 4, ECG功能, 2026-09
  5. rPPG: Poh et al., “Non-contact HRV monitoring”, 2011 (基础)

https://dapalm.com/2026/09/27/2026-09-27-34-hrv-vigilance-driving-sleep-deprivation-sensors-2026-ims/
作者
Mars
发布于
2026年9月27日
许可协议