脑网络研究这几年越来越火,不管你是做fMRI、DTI还是EEG/MEG,最后基本都会落到一个问题上:怎么把庞大的连接矩阵压缩成几个能讲故事的指标。图论就是干这个的。而说到工具,Matlab下的BCT(Brain Connectivity Toolbox)几乎是绕不开的标准件——免费、开源、被上千篇论文引用,你导师八成也让你用它跑过。
这篇文章我想把脑网络分析里最常用的5个图论指标一次讲透,从它们算的是什么、为什么有意义,到怎么用BCT一步步算出来,再到那些论文里不会写的坑。适合刚接触脑网络的新手,也适合给已入门但想系统梳理的人做一次查漏补缺。
1. 脑网络图论分析的整体思路
1.1 从连接矩阵到图论指标:你到底在算什么
先说清楚一件事:脑网络分析本质上做的是“建模”的活儿。你手里是一堆时间序列(fMRI的BOLD信号)或者纤维追踪数据(DTI),第一步永远是先把这些原始数据整理成一个N×N的连接矩阵,N是脑区节点数量。每个元素表示两个节点之间连接的强度。
有了连接矩阵,图论才有用武之地。图论不关心你扫描了几分钟、用了什么型号的机器,它只关心一件事:给定这些节点和边,网络的拓扑结构长什么样。是散布的、聚团的、还是介乎两者之间?有没有某些节点特别重要?信息在这张网上流动是快还是慢?这就是图论指标的意义——用几个数值描述整个网络的全局和局部属性。
这也是为什么图论指标能在不同研究之间做比较的原因。它把个体差异、设备差异、生理噪声都“折叠”成了拓扑特征,让你能拿一组病人的网络性质和正常对照组做统计检验。
1.2 BCT工具包是什么,为什么大家都在用
BCT全称Brain Connectivity Toolbox,是Olaf Sporns实验室维护的一套Matlab函数集合,下载解压之后把路径加进去就能用。它收录了几乎所有主流图论指标的计算函数,从最基础的节点度、聚类系数,到复杂一点的motif分析、生成模型拟合。
选择BCT而不是自己写代码,理由很简单:图论指标的实现细节远比看起来复杂。比如聚类系数在加权网络里有多种定义(Onnela定义、Barrat定义、Zhang定义),不同定义结果差异很大。BCT把这些实现细节固定了下来,而且用的是领域内被验证过的主流传法,这样你算出来的结果可以和其他文献直接对照。你要是自己实现一遍,很容易在某个边界条件上出错,而且审稿人问你用的哪个定义,解释起来也会很麻烦。
1.3 核心分析流程概览
用BCT做脑网络分析的标准流程大概是:
- 从原始数据构建节点×节点连接矩阵
- 对连接矩阵做预处理:阈值化、二值化或者保留权重
- 调用BCT函数计算各项图论指标
- 通常会重复步骤2-3多次(比如不同的稀疏度阈值)
- 用非参数检验(置换检验等)比较组间差异
- 结果去多重比较校正,再可视化
这篇文章聚焦前4步,特别是第2、3步里大量容易踩的细节。
2. 5个核心图论指标逐一拆解
2.1 节点度与度分布:最基础的连接画像
先看最底层的指标。
节点度(Degree)的定义极其简单:对于一个二值网络,节点i的度就是与它直接相连的边数。在加权网络里则一般用强度(Strength)表示,即所有连接权重的总和。BCT里对应的是degrees_und(无向网络)和strengths_und(加权无向网络)。
度这个指标回答的问题是:某个脑区在整个网络里“接触面”有多广?类比一下,一个社交圈子里认识人最多的那个人,自然在信息传播中有更重要的位置。如果一个脑区的度显著高于其他节点,我们通常称之为hub节点,它承担着全局信息汇聚和分发的角色。
实际操作中要注意一个细节:度对网络构建参数非常敏感。扫描仪噪声、头动校正的不彻底、以及阈值选择都会造成度的波动。所以单独看单个被试的度意义有限,通常的做法是做组水平比较,或者在每个被试内把度做了标准化(比如除以网络平均度)再比较。
另外一个跟度紧密相关的概念是度分布。真实脑网络的度分布通常呈截断幂律或者偏态分布——少数节点有很高的度,多数节点度很低。这种“无标度”特征说明脑网络不是均匀的随机网络,它有中心化的组织机制。如果你想在论文里展示这一点,可以用BCT的degrees_und先算出所有节点的度,再用直方图或者双对数坐标图展示分布形状。
2.2 聚类系数:衡量网络局域信息处理能力
聚类系数(Clustering Coefficient)衡量的是:某个节点的邻居之间,彼此也是邻居的比例。通俗地说,就是一个人的朋友们之间互相认识的程度。如果你的三个朋友彼此也是朋友,那你的聚类系数就高;如果他们互相不认识,那就低。
BCT里计算聚类系数,二值无向网络用clustering_coef_bu,加权无向网络用clustering_coef_wu。返回的是一个N×1的向量,每个元素是节点的聚类系数,整个网络的平均聚类系数就是所有节点的平均值。
聚类系数的生理意义一般和“功能分化”与“局域信息处理”联系起来。高聚类意味着局部形成稠密的连接簇,有利于信息的局部整合,也意味着冗余度较高——某条连接断开时,替代路径还在。
在实操中,加权网络的聚类系数计算特别容易出问题。目前常见的几种加权聚类系数定义不完全等价。BCT默认的是Onnela定义:分子是三角形三条边权重的几何均值,分母是节点度的某种归一化。不同定义的差异主要体现在权重分布不均匀时,所以如果你看到文献里聚类系数数值特别大或者特别小,先别急着怀疑自己的代码,先确认对方用的哪种定义。
2.3 特征路径长度:信息传递的效率标尺
特征路径长度(Characteristic Path Length)的定义:网络中所有节点对之间最短路径长度的平均值。
计算方式上,BCT先用distance_bin或distance_wei算出距离矩阵——注意这个矩阵和连接矩阵长一个样子,但元素含义完全不同。连接矩阵存的是权重(连接强度大数值大),距离矩阵存的是“代价”(权重越大距离越短,通常是取倒数)。然后对非对角线元素求平均,得到的就是特征路径长度。
这个指标的生物学含义很好理解:路径长度短,意味着任意两个脑区之间的信息要通过的中间站少,或者说信号传递快。所以特征路径长度越短,网络的全局整合效率越高。
但这里有个特别重要的实操细节:如果一个网络不是全连通的(在脑网络中由于阈值化经常发生),存在孤岛节点,那么这些节点对之间的最短路径是无穷大,直接平均会得到无穷大。BCT的charpath函数返回的lambda值在计算时会设一个上限值(默认 NumNodes),但你最好在调用之前先检查网络的连通分量数量。一个常见做法是只对最大连通分量内的节点做路径长度计算,或者用全局效率指标来替代——效率指标对不连通网络更鲁棒,因为∞的倒数就是0,可以直接处理。
2.4 全局效率与局部效率:从路径到信息流
全局效率(Global Efficiency)可以理解为特征路径长度的“倒数版”变体——但不是简单取个倒数完事,而是先对每对节点的最短路径长度取倒数,再平均。它的优势在于不需要网络全连通,因为不连通节点对的效率贡献为0,不会让整体变成无穷大。BCT里用efficiency_wei或efficiency_bin计算,返回E(全局效率)和E_local(局部效率)两个输出。
局部效率(Local Efficiency)衡量的是:移除某个节点后,它的邻居之间的通信效率还能保持多少。这跟聚类系数有点像,但更贴近“容错性”的概念。高局部效率的节点,即使它自己罢工了,它周围的小团体依然能高效运作。BCT中局部效率可以通过efficiency_wei的第二个输出得到。
我想特别强调一下全局效率为什么在近些年的论文里逐渐取代特征路径长度成为主打指标。最重要的原因是它的鲁棒性更好,不连通网络也能算,不需要额外的处理。对于fMRI这种噪声较大的数据,阈值化后不连通是常态,用特征路径长度就得做很多额外的判断和处理。而全局效率版本处理起来更平滑、更稳健。
2.5 小世界特性:寻找“既高效又经济”的网络拓扑
小世界特性,也是这篇文章标题中最核心的概念。它说的是:一个网络同时具备“高聚类系数”和“短特征路径长度”这两种看起来矛盾的特征。高聚类意味着局部信息处理强,短路径意味着全局整合快。这种组合在自然界很常见——我们的人际社交网络是典型的例子,你的朋友们之间大概率互相认识(高聚类),但你认识的人中总有那么几个“联络员”能很快链接到完全陌生圈子(短路径)。
定量衡量小世界特性的标准做法是把网络和随机网络做比较。随机网络的特征是聚类系数很低,但路径长度很短。而真实脑网络的聚类系数远高于随机网络,同时路径长度和随机网络差不多甚至更短。所以定义两个比值:
- Gamma = C_网络 / C_随机
- Lambda = L_网络 / L_随机
如果Gamma > 1且Lambda ≈ 1,那么网络就具有小世界特性。
一个更常见的综合指标是小世界指数 Sigma = Gamma / Lambda,要求>1。严格来说,更稳的做法是看Gamma和Lambda各自的值域,而不是只看Sigma。
BCT提供了smallworldness_bu和smallworldness_wu函数,输入连接矩阵和随机网络个数,自动生成随机网络并计算。函数默认用的是null_model_und_sign生成随机网络,它保持了原网络的度序列不变,这一点很重要——因为如果不保持度序列,随机网络本身就和真实网络没有可比性。
在实际操作中,随机网络的生成次数一般设个100-1000次,太少结果不稳定,太多计算量太大。另外要特别注意科学报道中一个反复被提到的问题:小世界特性在脑网络研究中几乎总是显著的。换句话说,如果一篇论文最核心的发现只是“脑网络有小世界属性”,那基本是没多大信息量的结论。更值得关注的,是小世界指数在疾病组和健康组之间有没有显著差异,以及它的变化和认知行为指标有没有相关。
3. BCT工具包实操指南:从安装到算出一个指标
3.1 环境准备与安装要点
第一步,下载BCT。你可以在Brain Connectivity Toolbox官网找到最新版本(现在提供Matlab和Python两个版本),下载后解压到一个本地目录。
第二步,在Matlab里把BCT路径加入工作路径。有两个方法:
% 方法一:一次性添加当前会话路径 addpath /你的路径/BCT/2019_03_03 % 方法二:保存为默认路径,下次启动不需要重新添加 pathtool % 或者在命令行直接输入: savepath我强烈建议用方法二,不然每次重启Matlab都重新添加路径,烦得很。
第三步,验证安装是否成功。随便运行一个BCT函数,比如:
A = [0 1 1; 1 0 1; 1 1 0]; clustering_coef_bu(A)如果返回[1; 1; 1](一个完全图的聚类系数全为1),说明装好了。
关于版本:如果你用的是较新的Matlab(R2020之后的),旧的BCT版本可能有兼容性问题,建议直接下载官网上最新版。Python用户也可以走pip install bctpy,但有细小的API差异,而且如果你要复现别人论文里的结果,还是用Matlab版最稳妥。
3.2 预处理:从原始连接矩阵到可计算矩阵
BCT只能算矩阵,不会帮你造矩阵。所以你的第一步工作是准备好一个N×N的连接矩阵W。
如果你做的是静息态fMRI分析,通常流程是:
- 用标准模板(AAL、Desikan-Killiany、Schaefer等)将大脑划分为N个感兴趣区(ROI)
- 提取每个ROI的平均时间序列
- 计算ROI之间的Pearson相关系数,得到N×N相关矩阵
- 经过Fisher z变换,把相关系数分布从[-1,1]拉伸到(-∞,∞),更利于后续统计
如果你做的是DTI纤维追踪,流程稍微不同:
- 同样划分ROI
- 重建纤维束
- 统计每对ROI之间的纤维数量或者平均FA值,得到结构连接矩阵
无论哪种方式,你得到的矩阵都是加权矩阵,权重越大表示连接越强。但这里面有个重要概念需要理解:fMRI的功能连接矩阵包含负值和正值(正相关和负相关),而BCT的大部分指标函数要求非负权重矩阵。遇到这种情况,一个常见的做法是先对矩阵做一次阈值化,只保留正连接或者取绝对值。
我在自己的分析流程中,一般倾向于Fisher z之后取绝对值再进BCT,或者如果关心的是正负连接的方向性差异,可以同时跑两套分析,一套看正连接网络,一套看负连接网络。取绝对值虽然会损失方向信息,但对于大多数拓扑指标(度、聚类、路径长度)来说,操作上最省事,也是很多文献的常用做法。
3.3 稀疏化与阈值化选择:同一个矩阵能算出完全不同的结果
这是BCT实操里最核心、也最容易出事的一步。
你的连接矩阵通常是全连接的(每个节点之间都有相关值,只是大小不同)。如果把全部连接都算进去,那所有节点的度都一样,区分度极低,聚类系数也会被很多弱连接“稀释”。所以实际操作中必须先做稀疏化——保留一部分较强的连接,去掉弱的连接。
两种常见稀疏化方式:
第一,绝对阈值法。设定一个相关阈值,比如只保留r > 0.25的连接。优点是简单直观;缺点是不同被试的整体连接强度分布不同,同样的阈值在一个被试那里可能保留了500条边,另一个被试只保留200条,这样两组的连接数目都不一样,拓扑指标的组间差异可能完全是被试的连接强度差异驱动的,而不是拓扑差异。
第二,固定稀疏度法(比例阈值法)。先对所有权重排序,保留前K%的强连接,其余的置零。比如设置稀疏度S = 0.2,就保留20%的最强连接。这样每个被试的网络连接数目完全一样,组间比较更公平。这也是目前主流做法。
在Matlab里实现固定稀疏度的代码大致这样:
% 假设W是N×N的加权连接矩阵(非负) % prop表示保留的比例,比如0.15表示保留15%的连接 function W_thr = threshold_proportional(W, prop) N = size(W, 1); W_thr = W; % 确认对角线置零 W_thr(1:N+1:end) = 0; % 取上三角元素的绝对值的排序 up = triu(W_thr, 1); v = up(up > 0); if isempty(v) return; end k = round(prop * numel(v)); if k < 1, k = 1; end thr = max(prctile(v, 100 * (1 - prop)), min(v)); % 也可以直接用sort取阈值 sv = sort(v, 'descend'); if k > length(sv), k = length(sv); end threshold = sv(k); W_thr(W_thr < threshold) = 0; end这个函数是我按常见实现补全的,实际BCT里没有现成的固定稀疏度函数,需要自己写。写的时候有几个坑要注意:一是只取上三角排序,避免重复计算;二是对角线必须置零,否则自连接会污染结果;三是当网络比较稀疏时,看看保留的连接是否足以构成一个连通的网络,太稀疏(比如低于5%)会得到碎片化的网络,指标不再稳定。
关于稀疏度的取值范围,我见过的大多数论文用的是0.1到0.4之间,步长0.01或0.02,做多次阈值扫描然后取曲线下面积(AUC)作为最终指标。这个方法比单阈值好得多,因为单阈值选择本身带有一定主观性,换一个阈值结果可能就变了。AUC方法把阈值影响整合起来,结果更稳健。我在自己的项目中基本都用扫描+曲线下面积的做法。
阶跃式地回到那5个指标——BCT对每个指标都有二值版和加权版,我一般建议如果KEEP了权重,就直接用加权版。二值化会把权重信息全部丢掉,只留下0/1的“有/无连接”信息,这在研究连接强度本身就有意义时,是很可惜的。但要注意,很多研究为了尽可能消除权重分布差异的影响,也会特意用二值网络。没有哪种做法绝对正确,但要在一篇文章里保持一致。
3.4 完整指标计算代码演示
我以一个典型的加权脑网络分析为例,展示从阈值化到五类指标计算的完整代码。假设你已经准备好了连接矩阵W(N×N,非负,对角线为0)。
% 假设 W 是已经做预处理的加权连接矩阵 % 设置稀疏度比例 prop = 0.15; % 保留15%的连接 % 阈值化 W_thr = threshold_proportional(W, prop); % 保证对称(有些情况下相关矩阵可能有极小的数值误差) W_thr = (W_thr + W_thr') / 2; % 计算各项指标 % 1. 节点度与强度(加权网络用的是强度) D = degrees_und(W_thr > 0); % 二值度:连边数 S = strengths_und(W_thr); % 加权强度:权重和 % 2. 聚类系数(加权版) C = clustering_coef_wu(W_thr); % 节点聚类系数 C_mean = mean(C); % 网络平均聚类系数 % 3. 特征路径长度 % 注意:distance_wei返回的是距离矩阵,基于权重倒数 [~, hop_single] = distance_bin(double(W_thr > 0)); % 二值网络跳数 [~, D_dist] = distance_wei(W_thr); % 加权网络距离 L = charpath(D_dist, 0, N); % 特征路径长度(第2个参数表示不忽略孤立点时容错) % 实际更推荐用效率: [Eglob, Eloc] = efficiency_wei(W_thr); % 全局效率 和 局部效率 % 4. 小世界特性(与随机网络比较) % 注意:BCT 提供的函数有两种 % 方法A:直接用现成函数(需要网络是二值的或者使用加权版) [sigma, omega] = smallworldness_bu(W_thr > 0, 1000); % 或者加权版: % [sigma_w, omega_w] = smallworldness_wu(W_thr, 1000);上面代码中smallworldness_bu输出中的sigma就是小世界指数,omega是另一个度量小世界的指标(介于0和1之间,越接近1小世界性越强)。
一个值得提醒的点是:smallworldness_bu在处理加权网络时会自动把权重信息忽略(内部做二值化),如果你用的是加权小世界函数smallworldness_wu,它对权重的分布比较敏感,某些情况下可能报错或者结果异常。我先用W_thr > 0做二值化再用二值版函数,这样最稳。
也有一个偏强硬的经验:不要在你从未看过的连接矩阵上直接跑全流程。我一般先画一个连接矩阵的热力图,用imagesc(W_thr)看看保留的连接分布是否合理,再往下算指标。这种“一眼检查”能省掉大量后面的排查时间。
3.5 多阈值扫描与AUC计算
刚才提到单阈值容易受到阈值选择的主观影响,更稳的是多阈值扫描。下面是一段标准的扫描代码:
% 多阈值扫描 + AUC proportions = 0.10:0.02:0.40; % 稀疏度从10%到40%,步长2% n_prop = length(proportions); metrics_names = {'C_mean', 'L', 'Eglob', 'Eloc', 'S_mean'}; metrics = zeros(n_prop, length(metrics_names)); for p = 1:n_prop W_thr = threshold_proportional(W, proportions(p)); W_thr = (W_thr + W_thr') / 2; C = clustering_coef_wu(W_thr); metrics(p, 1) = mean(C); [~, D_dist] = distance_wei(W_thr); metrics(p, 2) = charpath(D_dist, 0, 0); % 忽略无穷大路径? 这里填第3个参数 [Eglob, Eloc] = efficiency_wei(W_thr); metrics(p, 3) = Eglob; metrics(p, 4) = mean(Eloc); S = strengths_und(W_thr); metrics(p, 5) = mean(S); end % 计算每个指标的AUC AUC_metrics = trapz(proportions, metrics, 1); % AUC_metrics 中每个元素就是对应指标的AUC值关于charpath的第三个参数,不同版本可能要求提供节点数,我的习惯是直接传size(W_thr, 1),或者干脆在只有一条路径的地方就只用效率指标,不做特征路径长度。
AUC结果在很多文献里被称为“网络拓扑指标的整合表征”,虽然它只是把不同阈值下的计算结果做了一次面积积分,但它确实能减少单阈值判断带来的运气成分,也让组间比较时不需要对每个阈值都做一次多重比较校正。
3.6 组间比较与统计检验注意点
指标算出来后,一般就是要做疾病组和对照组的比较了。
强烈建议不要直接用两组数据做t检验就完事。图论指标在不同被试之间通常不符合正态分布,更重要的是,它们高度依赖个体的整体连接强度水平。所以一个常见做法是先对被试做协变量回归,把年龄、性别、头动等作为协变量剔除掉,然后对残差做统计检验。
为了保证结果不是由某一个极端个体驱动的,最好同时做非参数置换检验。置换检验的写法并不复杂,大致是先合并两组数据,然后循环多次随机打乱组标签,比较真实组间差异在置换分布中的位置,得到经验p值。这个做法不但不依赖正态性假设,还可以自然地处理多重比较问题。
BCT本身不提供统计函数,所以这部分要自己写代码或者结合GAT、NBS等网络统计分析工具使用。
4. 常见问题与排查技巧实录
4.1 “为什么我的聚类系数全是NaN或者无穷大”
这个问题十个新手八个会遇到。
原因通常是连接矩阵里包含NaN值(某些被试的ROI时间序列存在异常值导致相关矩阵出现NaN),或者网络过于稀疏导致某个节点没有邻居,聚类系数分母为零,结果为NaN。
排查方法:
% 检查矩阵里是否含有 NaN any(isnan(W(:))) % 检查是否含有 Inf any(isinf(W(:))) % 检查对角线是否都为0 any(diag(W) ~= 0)修复方式:第一个问题回到数据源头,去看哪些ROI的时间序列有坏帧或者插值问题;第二个问题,把过于稀疏的阈值排除掉,保证每个节点至少保留1条连接;第三个问题,手动将W(1:N+1:end) = 0。
4.2 功能连接里有负值,到底该不该保留
这是个经典争议问题。负功能连接(负相关)在某些研究者看来是真实神经活动模式(如默认模式网络和任务正激活网络之间的负耦合),另一些研究者认为很大程度上是全局信号回归带来的伪相关。
实操层面,BCT的大多数函数只接受非负权重。如果你硬塞给它负值矩阵,聚类系数、路径长度这些指标都会出现异常。我的处理办法:
- 如果关心大脑的“分离/整合”拓扑架构,保留正连接即可
- 如果关心负连接在疾病中的作用,单独建一个负连接网络,权重取绝对值,然后跑一套平行分析
- 不推荐直接对整个矩阵取绝对值再进BCT,因为这会人为地把负连接和正连接混在一起
4.3 稀疏度设置多少比较合适
这个问题没有标准答案。我见过一些论文用5%,也有用30%的。关键是两点:一是保证网络连通性,二是保证指标在相邻阈值下是稳定的。
一个实用的方法是先对每个被试画一个“指标-稀疏度曲线”。如果曲线在某个区间内剧烈震荡,说明这个阈值区间不适合做分析。要是从10%到40%都保持相对平滑(以及组间差异方向一致),那就大胆使用。
还有一个好习惯是报告你在若干阈值下的结果而不只是AUC。审稿人喜欢看到结论在多个阈值下都成立,这说明你的发现不是阈值选择出来的偶然结果。
4.4 小世界指数算出来小于1,是不是说明我的网络不是小世界
有可能是,但也可能是技术原因。
一个常见技术原因是你的网络太稀疏,破坏了连通性,导致路径长度异常大,Lambda远大于1,Sigma被拉低。另一个原因是你用了加权网络但没有对权重分布做标准化,而某些节点权重大得离谱,压缩了其他节点的影响。
所以当Sigma小于1时,先做两件事:检查连通分量数量,检查随机网络的生成是否正常。如果这些都没问题,那把Gamma和Lambda拆开看:如果Gamma大于1但Lambda远大于1,说明你的网络太“局部化”,全局整合不足。这种结果本身不一定坏,它可能在告诉你这个被试群体的全局信息整合能力受损——这在一些精神疾病研究里反而是有意义的发现。
4.5 随机网络生成结果的稳定性问题
在计算小世界特性时,随机网络的参数直接决定Gamma和Lambda的基准值。
BCT默认生成1000个随机网络。但是当网络节点数比较多(比如用Schaefer 400模板就有400个节点)时,1000次随机网络生成会花很长时间。我一般先跑100次的版本看看结果稳定性,如果两次运行得到的Sigma变化小于1%,直接用100次就行。
另外一个容易被忽视的细节:随机网络是保持度序列的,所以生成结果的变异性会比较大,需要设置随机种子(rng),否则你报告的结果每次运行都不一样,审稿人要是复现不了会抓狂。在计算小世界报告里写明你用的随机数种子是个好习惯。
4.6 BCT版本更新导致函数名变化
BCT从2017版到现在的版本有些函数做了较大的调整,比如charpath的输入参数变了,smallworldness的称呼也有变化。最好把下载的BCT版本号和Matlab版本号记录下来,在方法学部分写清楚。对于可复现性来说,这条细节比你想的重要得多。
5. 实际分析中的几条经验与心得
到这里,脑中这些指标的来龙去脉和BCT的操作流程基本讲完了。最后说说几条我自己的切身体会,属于不写在正式教程里的那种经验。
第一,别被指标数量带跑。5个核心指标能讲清楚大部分故事:节点度告诉你哪个区域是枢纽,聚类系数告诉你局域处理强弱,路径长度和全局效率告诉你全局整合能力,小世界指数给你一个整体判断。如果这5个指标没有差异,加了模块度和介数中心性往往也不会有差异。
第二,纵使AUC是个好方法,也要先看单阈值的结果稳定不稳定。我踩过几次这样的坑:AUC在两组间有显著差异,但回头看单阈值下只有0.15和0.18两个阈值显著,其他阈值都不显著。这时候我心里就会打鼓,即使AUC是显著的。后来我学会了先看单阈值热图(横轴阈值,纵轴被试,颜色代表指标值),直观判断差异的稳定性,然后再做AUC比较。这个习惯帮我避开了至少两三次可能被审稿人质疑的处理方式。
第三,连接矩阵的质量压倒一切。你可以把图论指标算得非常精确,但如果矩阵本身是从头动严重的fMRI数据里提取出来的,指标再好看也是垃圾进垃圾出。话难听但道理是真的。粗运动评估、帧间位移(FD)检查、时间序列质量控制这些步骤,虽然不在这篇文章范围内,但请一定在分析管线中做好,它们最终会反映在指标质量上。
第四,如果条件允许,找个已经跑通过的师傅请教一下比看几天文档都管用。BCT虽然免费,但上手门槛不低,尤其是对一个新手来说,一个小坑能卡好几天。如果身边没有相关背景的人,那就用公开数据集(比如HCP的预处理结果)先跑通一遍流程,再上自己的数据。这个策略屡试不爽,比我刚入行时对着报错信息发呆高效太多。
脑网络图论分析是一个“看起来简单、做起来讲究”的领域。指标计算本身只要几行代码,难的是理解每个指标在什么样的情况下是可靠的、在什么样的情况下会被误导。希望你读完这篇文章之后,拿到一批连接矩阵,至少能判断哪几步是必须小心的、哪几步可以放心跑。祝你的数据都能算出你想要的结果。