ERP 统计与报告写作
数字有了,接下来回答终极问题:"两个条件的波形不一样,是真的不一样吗?" 这一课打通统计检验、多重比较校正与行为相关,最后把整条链路写成论文里的一段方法。
🎯 本节学习目标
- 会根据实验设计选择正确的条件间检验:配对 t 检验与重复测量 ANOVA,并能报告效应量
- 理解通道 × 时间点的大规模检验如何制造多重比较问题,会用 Bonferroni 与 FDR 校正
- 能说清点式检验的局限,知道 cluster 置换检验解决什么问题(模块 5 预告)
- 会做被试级 ERP-行为相关分析(皮尔逊/斯皮尔曼),明白试次级相关为何要谨慎
- 掌握结果图表呈现规范,能套用模板写出完整的方法部分段落
一、这一课在整条链路中的位置
3.2 结束时,你手里有一张表:每个被试 × 每个条件 × 每个指标,各一个数。 现在要回答的问题是:条件之间的差异,是真实差异,还是运气? 这就是推断统计的事。本课把"检验 → 校正 → 相关 → 呈现 → 写作"一次讲完。
① 测量:每个被试 x 条件 x ROI → 一个数(3.2 已完成) ② 检验:条件间差异是否超出偶然波动(配对 t / 重复测量 ANOVA) ③ 校正:通道 x 时间的多重比较(Bonferroni / FDR) ④ 关联:ERP 指标与行为指标的关系(相关分析) ⑤ 呈现与写作:图表规范 + 方法部分模板
二、条件间比较:检验跟着设计走
选检验的唯一依据是实验设计,不是"哪个显著用哪个": 同一批被试做两个条件 → 配对 t 检验;三个及以上条件、或有多因素被试内设计 → 重复测量 ANOVA;不同组被试 → 独立样本 t 检验 / 组间 ANOVA。 ERP 指标在每个被试身上只有一个数(3.2 测好的),所以统计和普通行为数据没有本质区别。
%% 配对 t 检验:同一批被试、两个条件
% ampA / ampB:每个被试一个数的平均幅值(如顶叶 ROI 250-350ms)
[h, p, ci, stats] = ttest(ampA, ampB);
fprintf('t(%d) = %.2f, p = %.4f\n', stats.df, stats.tstat, p);
fprintf('均值差 95%% CI: [%.2f, %.2f] uV\n', ci(1), ci(2));
% 效应量:配对版 Cohen d = 差值均值 / 差值标准差
d = mean(ampA - ampB) / std(ampA - ampB);
fprintf("Cohen's d = %.2f\n", d);
%% 重复测量 ANOVA:三个及以上条件(条件为被试内因素)
% ampA / ampB / ampC:每个条件一个 nSub x 1 的向量
nSub = numel(ampA);
y = [ampA; ampB; ampC]; % 所有观测摞成一列
cond = [repmat({'A'}, nSub, 1); repmat({'B'}, nSub, 1); repmat({'C'}, nSub, 1)];
sub = repmat((1:nSub)', 3, 1); % 每个被试出现三次
% 被试设为随机因素:条件 x 被试交互项自动成为正确的误差项
[pVal, anovaTbl] = anovan(y, {cond, sub}, 'model', 2, ...
'random', 2, 'varnames', {'Cond', 'Sub'});
% 看 anovaTbl 中 Cond 一行的 p 值;显著后做事后两两配对比较(记得再校正)
ANOVA 显著只说明"至少有一对条件不同"。事后两两比较(还是配对 t)会产生新的多重比较, 用 Bonferroni 简单除以比较次数即可:三个条件是 3 次两两比较,α 取 0.05/3。 另外,无论 t 检验还是 ANOVA,都请顺手报告效应量(Cohen d、偏 η²)与置信区间。
三、多重比较:一次 t 检验怎么变成三万次
上面的做法一次只检验一个指标。但 ERP 更诱人的问题是: "差异在哪些电极、哪些时间点上显著?"——于是你对每个通道、 每个时间点各做一次检验:64 通道 × 400 个时间点 = 25600 次检验。
在纯噪声数据上,α = 0.05 意味着每次检验有 5% 的概率"蒙对"。25600 次里, 预期会有约 1280 个"显著"点——它们看起来就像真实的效应,其实什么都不是。 一张布满散点的显著性图,如果不校正,等于没做统计。
一族检验中至少出现一个假阳性的概率。检验次数越多,家族错误率越高 (20 次独立检验就超过 64%)。Bonferroni 等校正方法控制的就是它。
四、Bonferroni 与 FDR:传统校正的两板斧
Bonferroni:把 α 除以检验次数 m(0.05/25600 ≈ 0.000002)。最简单、最保守, 适合少量事先计划好的比较(比如两个 ROI × 两个时间窗 = 4 次)。 FDR(错误发现率):不追求"零假阳性",而是控制显著结果中假阳性的比例, 检验力高得多,是大规模逐点检验的常规选择。
%% 通道 x 时间的大规模检验 + FDR 校正
% ERP_A / ERP_B:被试 x 通道 x 时间 的矩阵(每人每条件一条 ERP)
[nSub, nChan, nTime] = size(ERP_A);
pmap = ones(nChan, nTime); % 每个通道-时间点的 p 值
for ch = 1:nChan
for tt = 1:nTime
[~, pmap(ch, tt)] = ttest(squeeze(ERP_A(:, ch, tt)), ...
squeeze(ERP_B(:, ch, tt)));
end
end
%% Benjamini-Hochberg FDR:手工实现,一共几行
pv = sort(pmap(:)); m = numel(pv); q = 0.05; % 目标 FDR 水平
thresh = q * (1:m)' / m; % 第 i 小 p 值对应的阈值
ok = pv <= thresh;
if any(ok)
pCrit = pv(find(ok, 1, 'last')); % 能通过 FDR 的最大 p 值
sigMap = pmap <= pCrit; % 校正后仍显著的通道-时间点
else
pCrit = 0; sigMap = false(size(pmap)); % 一个显著点都没有
end
fprintf('FDR(q=0.05) 临界 p 值: %.4f,显著点占比: %.1f%%\n', ...
pCrit, 100 * mean(sigMap(:)));
| 方法 | 控制什么 | 优点 | 局限 |
|---|---|---|---|
| 不校正 | 什么都不控制 | "好看" | 假阳性泛滥,不可报告 |
| Bonferroni | 家族错误率 | 简单,适合少量计划比较 | 通道/时间高度相关时过度保守 |
| FDR | 错误发现率 | 检验力较高,适合大规模逐点检验 | 显著点仍是逐点的,不利用时空结构 |
| cluster 置换 | cluster 水平的家族错误率 | 利用时空相邻性,对延展效应敏感 | 计算量大;结论落在 cluster 水平(模块 5 详解) |
波形图上把每个显著点画成小圆点、不做任何校正——这是 ERP 论文里最经典的错误之一。 审稿人看到的第一反应不是"效应真强",而是"作者不懂多重比较"。 至少做 FDR;时空延展的效应,等模块 5 的 cluster 置换检验。
五、点式检验的局限与 cluster 置换检验(模块 5 预告)
相邻时间点、相邻电极的数据高度相关——它们不是彼此独立的证据。 这带来两个后果:Bonferroni 按"独立检验"来算,惩罚被放大(过度保守); 而逐点校正后的显著区常常碎成一地小点,回答不了"效应何时、何地发生"。
cluster 置换检验的思路:把相邻的显著点连成簇(cluster), 用置换数据的簇级统计量分布来判断整簇是否显著。它利用了时空结构, 对延展型效应(比如持续 200ms、覆盖半个头皮的差异)远比逐点检验敏感。 这是模块 5 的主角,这里先记住一句话:逐点校正看"点",cluster 检验看"片"。
六、ERP 与行为数据的相关分析
脑电指标和行为指标(反应时、正确率、量表分数)的相关,能回答"这个脑成分和行为有多大关系"。 两个层级要分清:
- 被试级(默认):每人一个 ERP 指标 × 每人一个行为指标,n = 被试数。简单、干净,但 n 小(20-30),一个离群点就能翻盘——所以散点图必画;
- 试次级:单试次幅值 × 单试次反应时。数据量大、理论上更敏感,但试次嵌套在被试里,观测彼此不独立,不能当普通相关直接算——需要混合效应模型,或"先分被试算相关、再对相关系数做组检验"。本课先掌握被试级。
%% ERP 指标与行为指标的相关(被试级)
% amp:每个被试的 P300 平均幅值;rt:每个被试的平均反应时 (ms)
[r, p] = corr(amp, rt); % 默认皮尔逊(线性关系)
[rho, p2] = corr(amp, rt, 'Type', 'Spearman'); % 秩相关:对离群值和非线性更稳健
fprintf('Pearson r = %.2f, p = %.3f\n', r, p);
fprintf('Spearman rho = %.2f, p = %.3f\n', rho, p2);
% 散点图必画:小样本里一个离群点就能"造出"一个显著相关
figure; scatter(rt, amp, 'filled'); hold on;
b = polyfit(rt, amp, 1); % 一元线性拟合
xv = linspace(min(rt), max(rt), 100);
plot(xv, polyval(b, xv), 'r-');
xlabel('平均反应时 (ms)'); ylabel('P300 平均幅值 (\muV)');
title(sprintf('被试级相关(n = %d)', numel(amp)));
一、皮尔逊抓线性关系,斯皮尔曼抗离群值——两个都报告最稳妥; 二、皮尔逊显著而斯皮尔曼不显著时,先检查是不是被一两个离群点撑起来的; 三、相关不等于因果,n 小的时候尤其要克制解释。
七、结果呈现规范:让图自己说话
- 波形图:条件配色全篇统一(正文、组图、答辩 PPT 一致);给波形加置信带(SEM 或 95% CI 的阴影),别只画两条裸线;
- 显著性标注:在时间轴下方用粗色条标出校正后的显著时段,不要用星号"满天飞";波形所用电极与时间窗在图注里写清;
- 地形图:同一行多张图必须统一色标(
caxis一致),标注时刻;红正蓝负的方向全篇一致; - 统计量:报告 t/df、精确 p 值、效应量与置信区间,不要只给星号;
- 诚实呈现:单被试图(灰色细线 + 红色组平均)是好习惯,让读者自己看到个体差异。
八、论文方法部分写作模板
方法部分的作用是让别人能照着复现。对照下表逐项检查,缺一项就补一项:
| 报告要素 | 模板句式(替换括号内容) |
|---|---|
| 预处理参数 | "连续数据经(0.1–45 Hz)带通滤波,以(平均参考)重参考,ICA 剔除眼电与心电成分,剔除幅值超过(±100 μV)的试次,平均每名被试保留(N ± SD)个试次。" |
| 分段与基线 | "以刺激呈现为 0 点,提取(−200 至 800 ms)片段,以刺激前(200 ms)为基线进行校正。" |
| 测量指标 | "(P300)平均幅值取(顶叶 ROI:Pz、P3、P4、CPz)在(250–350 ms)的均值;时间窗依据(参考文献 [x])及跨条件总平均波形确定,各条件一致。" |
| 潜伏期 | "潜伏期采用(50% 分数面积潜伏期),计算窗口为(250–450 ms)。"(如报告) |
| 统计方法 | "条件间差异采用(配对 t 检验 / 重复测量 ANOVA),效应量以(Cohen d / 偏 η²)报告。" |
| 多重比较 | "通道 × 时间点的大规模检验采用(FDR,q = 0.05 / cluster 置换检验)校正。" |
| 软件版本 | "数据分析在(EEGLAB 2022.1,Matlab R2022a)中完成。" |
最后一个建议:在开工之前把这张表填好,存成一份分析计划。 窗口、电极、指标全部先定后测,方法部分直接照抄计划—— 既避免"看结果挑窗口"的陷阱,投稿被质询时也理直气壮。 到这里,"从一条条试次到一段能发表的方法",整条 ERP 时域分析链路就闭环了; 模块 4 我们换一副眼镜,从时域走进频域。
📌 本节小结
- 检验跟着设计走:同被试两条件用配对 t,多条件用重复测量 ANOVA,组间用独立样本检验
- 通道 × 时间逐点检验等于上万次检验:不校正就报告,假阳性是必然结果
- Bonferroni 控家族错误率但保守;FDR 控错误发现比例、检验力更高;两者都不利用时空相关——延展效应看模块 5 的 cluster 置换检验
- 行为相关优先做被试级(皮尔逊 + 斯皮尔曼 + 散点图);试次级相关受嵌套非独立性影响,不能当普通相关算
- 结果呈现四件套:置信带波形、统一配色、校正后的显著性标注、统一色标的地形图
- 方法部分六要素:滤波与参考、分段基线、测量窗及依据、电极/ROI、统计检验、多重比较校正
✏️ 课后练习
- 用模拟数据(20 个"被试"、两个条件)跑配对 t 检验,完整报告 t、df、p、Cohen d 与 95% CI。
- 把 BH-FDR 代码跑在纯随机噪声数据上(如 64 通道 x 400 时间点),数一数未校正时有多少"显著"点、校正后还剩几个。
- 按方法模板写出你自己研究的方法段落(约 150-200 字),对照六要素检查表逐项打勾。