统计方法交互速查

生信面试常考统计方法一网打尽 | 覆盖宏基因组 + 微生物组 + 机器学习

为什么统计方法是面试必考?

做生信分析,本质上就是在回答"两组之间有没有差异?差异有多大?哪些物种/基因导致了差异?能不能预测?"——这些全靠统计方法。面试官通过统计题考察你是不是"真做过分析"还是"只会跑脚本"。

两组比较 多组比较 群落整体差异 差异物种/基因 多重检验校正 机器学习预测
01 统计方法决策树 — 拿到数据先问什么? 决策指南

面试官问"你怎么选统计方法?"——不要背方法名,而是说出你的决策逻辑。下面是一个清晰的决策路径:

第一步:你的研究问题是什么?
问题A:两组之间某个指标有没有差?(如 Alpha 多样性、某个物种丰度)
先检查正态性(Shapiro-Wilk 检验)
正态 + 方差齐 ➔
独立样本 t-test(生信中很少用,因为微生物数据几乎不正态)
非正态 / 样本小 ➔
Wilcoxon 秩和检验(= Mann-Whitney U 检验)(最常用!)
问题B:三组及以上某个指标有没有差?
Kruskal-Wallis 检验(非参数的 ANOVA 替代)
如果整体显著 ➔
Dunn's post-hoc 检验 + BH 校正,找出哪两组之间有差
问题C:两组群落整体组成有没有差?(Beta 多样性)
PERMANOVA (adonis2) — 配合 PCoA/NMDS 可视化
问题D:哪些物种/基因在两组之间有差异?
DESeq2(基于负二项分布,适合 count 数据)
LEfSe(LDA 效应量,适合找 biomarker)
MaAsLin2(多变量关联,可矫正协变量)
ANCOM-BC(专门处理组成数据偏差)
问题E:能不能用微生物特征预测疾病?
随机森林 + 嵌套交叉验证 — 输出 AUC/ROC + 特征重要性
面试回答模板:"我会先看研究问题类型——比较单个指标用 Wilcoxon,比较整体群落用 PERMANOVA,找差异物种用 DESeq2 或 LEfSe,做预测建模用随机森林。所有涉及多重比较的结果都要做 FDR 校正。"
02 Wilcoxon 秩和检验 — 生信最常用的比较方法 非参数检验

白话原理:不比较数值大小,而是比较排名。把两组数据混在一起从小到大排序,给每个值编号(秩),然后看一组的编号之和是不是偏大或偏小。如果一组的排名普遍靠前(数值小),另一组普遍靠后(数值大),就说明有差异。

Wilcoxon 秩和检验(Wilcoxon rank-sum test)和 Mann-Whitney U 检验是同一个检验的不同名字!Frank Wilcoxon 1945 年发明,Mann 和 Whitney 1947 年独立推导了等价公式。面试千万别说它们是不同检验。

真正不同的是 Wilcoxon signed-rank test(符号秩检验)——它用于配对样本(如同一个人治疗前后),而秩和检验用于独立样本

R 代码

# 比较健康组和T2D组的Shannon多样性指数 wilcox.test(shannon ~ group, data = alpha_div, exact = FALSE, # 样本量大时用正态近似 correct = TRUE) # Yates连续性校正
📖 参数逐行讲解
wilcox.test(shannon ~ group, data = alpha_div) 用公式写法做 Wilcoxon 秩和检验:shannon ~ group 意思是"按 group 列分组,比较 shannon 列的值";data 指定数据框
exact = FALSE 不计算精确 p 值,改用正态近似。样本量大于 50 或有并列值(tie)时建议 FALSE,否则计算会很慢甚至报错
correct = TRUE 启用 Yates 连续性校正——因为秩和是离散值,但正态近似是连续的,校正会让 p 值略微保守(更不容易显著),一般保持默认 TRUE 即可
💡 如果是配对样本(如同一个人治疗前后),加 paired = TRUE,此时变成 Wilcoxon signed-rank test(符号秩检验),这是完全不同的检验

真实输出

Wilcoxon rank sum test with continuity correction data: shannon by group W = 2847, p-value = 0.003142 alternative hypothesis: true location shift is not equal to 0
输出字段含义白话解释
WWilcoxon 统计量(秩和)一组排名之和,越偏离期望值越说明有差异
p-value显著性概率<0.05 说明两组确实不一样

适用场景:

场景具体例子
Alpha 多样性比较T2D 组 vs 健康组的 Shannon 指数
单个物种丰度比较两组之间 Bacteroides 的相对丰度
某个功能通路的丰度两组之间某 KEGG pathway 的 abundance
面试追问:为什么不用 t-test?
回答:"微生物丰度数据几乎都是偏态分布(右偏、大量零值),不满足 t-test 的正态性假设。Wilcoxon 不需要正态假设,对离群值也不敏感,所以在微生物组分析中几乎默认用 Wilcoxon。"
03 PERMANOVA (adonis2) — 群落整体差异检验 Beta多样性

白话原理:把每个样本想象成地图上的一个点,同组样本靠得近,不同组样本靠得远。PERMANOVA 就是比较"组间距离是否显著大于组内距离"——如果是,说明分组因素(如疾病/健康)确实影响了菌群组成。

技术上:PERMANOVA 对距离矩阵做方差分析的思想(类似 ANOVA),但不要求正态性,通过置换(permutation)获得 p 值。

R 代码

# 加载 vegan 包 library(vegan) # 计算 Bray-Curtis 距离矩阵 bc_dist <- vegdist(otu_table, method = "bray") # PERMANOVA 检验 result <- adonis2(bc_dist ~ Group, data = meta, permutations = 999) # 置换次数;bc_dist已是距离矩阵,无需method参数 print(result)
📖 参数逐行讲解
vegdist(otu_table, method = "bray") 计算样本间的 Bray-Curtis 距离矩阵。otu_table 是物种丰度表(行=样本,列=物种);method 指定距离度量——"bray" 是微生物组分析的首选(考虑丰度差异),其他选项有 "jaccard"(只看有无)、"euclidean"(欧氏距离,一般不用于丰度数据)
adonis2(bc_dist ~ Group, data = meta) 做 PERMANOVA 检验。公式 bc_dist ~ Group 意思是"用 Group 变量解释距离矩阵的变异";data = meta 是包含分组信息的元数据表
permutations = 999 做 999 次随机置换来计算 p 值——把样本标签随机打乱 999 次,看真实的 F 值在随机分布中排第几。999 次是常用默认值,发文章一般用 9999 次更稳定
💡 如果有多个因素要检验,可以写 bc_dist ~ Group + Age + BMI,同时评估多个变量的贡献。注意变量顺序会影响结果(sequential test),所以通常把最关心的变量放第一个

真实输出(vegan adonis2)

Permutation test for adonis under reduced model Terms added sequentially (first to last) Permutation: free Number of permutations: 999 Df SumOfSqs R2 F Pr(>F) Group 1 0.8234 0.0712 3.4521 0.001 *** Residual 85 20.2876 0.9288 Total 86 21.1110 1.0000 --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
输出字段含义白话解释
Df自由度Group 有 2 组所以 Df=1
SumOfSqs平方和该因素解释的"距离变异量"
解释度(0~1)这里 7.12% 的群落差异由分组解释
F伪F统计量组间变异 / 组内变异,越大差异越明显
Pr(>F)p值(基于置换)0.001 表示非常显著
面试追问:PERMANOVA vs ANOSIM?
回答:"两者都检验组间差异,但 PERMANOVA 基于距离矩阵的方差分析(类似 F 检验),能给出 R²(解释度),并且可以加入多个协变量。ANOSIM 基于秩,只给 R 统计量(-1到1),不能加协变量。现在主流推荐 PERMANOVA。"

补充:R² 小不等于不显著!微生物组数据个体差异极大,R²=5%~10% 在这个领域很常见且有生物学意义。
PERMANOVA 假设组内离散度相似(类似方差齐性),如果不满足,需先用 betadisper() 检验离散度差异,再做 PERMANOVA。如果 betadisper 显著,PERMANOVA 的结果可能被离散度差异"污染"。
04 DESeq2 差异分析 — 找差异物种/基因的金标准 差异分析

白话原理:微生物 count 数据不是正态分布,而是"负二项分布"(一种适合 count 数据的分布,允许方差大于均值)。DESeq2 用这个分布建模,通过"缩减估计"(shrinkage)稳定低丰度物种的 fold change,最后做 Wald 检验判断每个物种在两组之间的差异是否显著。

R 代码

# 1. 创建 DESeq 数据对象(count矩阵 + 分组信息) library(DESeq2) dds <- DESeqDataSetFromMatrix( countData = count_matrix, # 行=物种, 列=样本 colData = sample_info, # 样本元数据(含 Group 列) design = ~ Group # 按 Group 列比较 ) # 2. 运行 DESeq2 流程(自动完成标准化+离散度估计+统计检验) dds <- DESeq(dds) # 3. 提取结果 res <- results(dds, contrast = c("Group", "T2D", "Healthy"), # T2D vs Healthy alpha = 0.05 # FDR 阈值 ) # 4. 按 padj 排序,查看 top 差异物种 res_ordered <- res[order(res$padj), ] head(res_ordered)
📖 参数逐行讲解
DESeqDataSetFromMatrix(countData, colData, design) 创建 DESeq2 专用数据对象,把三样东西打包在一起:
countData = count_matrix 原始 count 矩阵(行=物种/基因,列=样本)。必须是未标准化的整数,不能用相对丰度或 RPKM
colData = sample_info 样本元数据表,行名=样本名(要和 count_matrix 列名一致),至少包含分组列(如 Group)
design = ~ Group 告诉 DESeq2 按哪个变量比较。~ 是 R 公式写法;如果要矫正协变量:~ Age + BMI + Group(最关心的变量放最后)
DESeq(dds) 一键运行三步流程:① 估计 size factors(标准化)→ ② 估计基因/物种的离散度(dispersion)→ ③ 对每个物种做 Wald 检验。一行代码搞定所有统计
results(dds, contrast, alpha) 提取差异分析结果:
contrast = c("Group", "T2D", "Healthy") 指定比较方向:第一个是列名,第二个是分子(实验组),第三个是分母(对照组)。这里 log2FC = log2(T2D / Healthy),正值=T2D升高
alpha = 0.05 FDR 显著性阈值,影响 independent filtering 的阈值选择和 summary() 的报告,但不影响 padj 的计算本身
💡 res[order(res$padj), ] 按校正后 p 值排序,最显著的排最前面。看结果永远看 padj 列,不要看 pvalue

真实输出(DESeq2 results)

log2 fold change (MLE): Group T2D vs Healthy Wald test p-value: Group T2D vs Healthy DataFrame with 6 rows and 6 columns baseMean log2FoldChange lfcSE stat pvalue padj Bacteroides 5832.41 -1.2453 0.1887 -6.6009 4.06e-11 1.22e-08 Faecalibacterium 3214.76 -0.9871 0.2104 -4.6914 2.72e-06 4.08e-04 Prevotella 2456.33 1.5632 0.3241 4.8229 1.42e-06 2.84e-04 Roseburia 1843.92 -0.7234 0.2456 -2.9454 3.23e-03 2.15e-01 Blautia 1567.44 0.4521 0.3102 1.4575 1.45e-01 6.83e-01 Akkermansia 876.21 -0.3812 0.4561 -0.8358 4.03e-01 NA
字段含义白话解释
baseMean所有样本的标准化 count 均值这个物种总体丰度有多高
log2FoldChangelog2(T2D / Healthy)正值=T2D中升高,负值=T2D中降低。-1.24 意味着 T2D 组约为健康组的 1/2.4
lfcSElog2FC 的标准误估计的不确定性
statWald 统计量 = log2FC / lfcSE类似 z-score,绝对值越大越显著
pvalue原始 p 值单个检验的显著性(未校正)
padjBH 校正后 p 值这个才是最终看的!<0.05 才认为显著

火山图解读:

X轴 = log2FoldChange(越左越在T2D中减少,越右越增加);Y轴 = -log10(padj)(越高越显著)。右上角 = T2D显著升高的物种;左上角 = T2D显著降低的物种;中间/下方 = 无显著差异。

面试追问:DESeq2 vs LEfSe vs ANCOM-BC?
工具统计模型优势适用场景
DESeq2负二项分布 + Wald检验统计功效高,给出 log2FCcount 数据差异分析(宏基因组)
LEfSeKruskal-Wallis + LDA可视化效果好,给出 LDA score找 biomarker,文章图好看
ANCOM-BC线性回归 + 偏差校正专门解决组成数据偏差问题16S 相对丰度数据
MaAsLin2广义线性混合模型可加协变量(年龄、BMI等)需矫正混杂因素时
05 多重检验校正 — 别被假阳性骗了 FDR/BH

白话原理:假如你检测了 1000 个物种,即使它们全都没有真正的差异,按 p<0.05 的标准,也会有大约 50 个"碰巧显著"的(50 = 1000 × 0.05)。多重检验校正就是把这些"碰巧显著"的假阳性压下来。

Benjamini-Hochberg (BH) 校正步骤图解:

步骤操作白话解释
1把所有 p 值从小到大排序,编号 i=1,2,...,mm 是总检验数(如 1000 个物种)
2计算每个 p 值的 BH 临界值 = (i/m) × QQ 是你设定的 FDR 阈值(通常 0.05)
3从大到小找到第一个 p ≤ 临界值的位置这个位置及之前的所有 p 值都被认为显著

调整后 p 值的计算公式:

# padj 的计算(从后往前) padj[m] = p[m] # 最大 p 值不变 padj[i] = min(padj[i+1], m * p[i] / i) # 保证单调递增 padj[i] = min(padj[i], 1) # 不超过 1
📖 公式逐行讲解
padj[m] = p[m] 最大的那个 p 值不需要调整,保持原样(m = 总检验数,比如检测了 1000 个物种,m=1000)
padj[i] = min(padj[i+1], m * p[i] / i) 从后往前算:m * p[i] / i 就是 BH 校正公式的核心——p 值乘以"总检验数/当前排名"。取 min 是为了保证 padj 从小到大递增(单调性),否则可能出现排名靠前的 padj 反而比排名靠后的大的怪现象
padj[i] = min(padj[i], 1) p 值不能超过 1,这是概率的上限
💡 白话理解:排名越靠前(p 值越小)的检验,除以的 i 越小,所以惩罚越轻——BH 的核心思想是"越显著的结果惩罚越少",比 Bonferroni 的一刀切(全部乘以 m)温和得多

Bonferroni vs BH 对比

特性BonferroniBenjamini-Hochberg (BH)
控制指标FWER(Family-Wise Error Rate)FDR(False Discovery Rate)
白话"保证不犯任何一个假阳性错误""允许少量假阳性,但控制比例"
公式padj = p × mpadj = p × m / rank
严格程度非常严格,容易漏掉真信号适中,保留更多真信号
适用场景检验数少(<20)、不容错检验数多(宏基因组/转录组常用)
生信中很少用几乎默认用 BH

R 代码

# 假设你有一组原始 p 值 p_values <- c(0.001, 0.008, 0.039, 0.041, 0.042, 0.15, 0.31, 0.56, 0.78, 0.92) # BH 校正(FDR 校正,最常用) p_adj_bh <- p.adjust(p_values, method = "BH") # Bonferroni 校正(太严格,一般不用) p_adj_bonf <- p.adjust(p_values, method = "bonferroni") # 比较结果 data.frame(raw_p = p_values, BH = p_adj_bh, Bonferroni = p_adj_bonf)
📖 参数逐行讲解
p.adjust(p_values, method = "BH") R 内置的多重检验校正函数,一行搞定:
p_values 一个数值向量,包含所有原始 p 值(比如 1000 个物种的 Wilcoxon 检验 p 值)
method = "BH" 校正方法。常用选项:"BH""fdr"(两个完全一样,都是 Benjamini-Hochberg)、"bonferroni"(太严格,慎用)、"holm"(比 Bonferroni 稍温和)、"BY"(允许 p 值之间有相关性时用,更保守)
p_adj_bonf <- p.adjust(p_values, method = "bonferroni") Bonferroni 校正就是每个 p 值直接乘以检验总数 m,简单粗暴但太严格
💡 实际使用中,DESeq2 内部已经自动做了 BH 校正(padj 列),不需要手动调用 p.adjust。手动调用的场景:你自己跑了一批 Wilcoxon 检验或相关性检验,得到一组原始 p 值,需要统一校正
面试追问:什么时候用 FDR?什么时候用 Bonferroni?
回答:"宏基因组和转录组分析中,通常检测成百上千个物种/基因,用 BH-FDR 是标准做法(如 DESeq2 默认用 BH)。Bonferroni 太严格,检验数多了几乎什么都检不出来。只有在检验数很少(比如只比较 3~5 个预设的 candidate gene)且不容许任何假阳性的情况下才用 Bonferroni。"
06 随机森林与交叉验证 — 疾病预测模型 机器学习

白话原理:"让 100 棵决策树投票。" 每棵树只看部分数据和部分特征,做出自己的判断,最终少数服从多数。就像请 100 个医生各看部分化验单来诊断,然后投票决定——比一个医生看全部更可靠。

sklearn 代码 + 参数说明

# 导入必要的库 from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold, cross_val_predict from sklearn.metrics import roc_auc_score, roc_curve import numpy as np # 创建随机森林分类器 rf = RandomForestClassifier( n_estimators=500, # 500棵树(越多越稳定,但更慢) max_depth=None, # 不限制深度(让树充分生长) min_samples_split=5, # 至少5个样本才能继续分裂 min_samples_leaf=2, # 叶节点至少2个样本 max_features='sqrt', # 每次分裂只看 sqrt(总特征数) 个特征 class_weight='balanced', # 自动平衡不均衡的样本数 random_state=42, # 固定随机种子,结果可复现 n_jobs=-1 # 用所有CPU核心加速 ) # 5折交叉验证 cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) y_pred_proba = cross_val_predict(rf, X, y, cv=cv, method='predict_proba')[:, 1] # 计算 AUC auc = roc_auc_score(y, y_pred_proba) print(f"AUC = {auc:.3f}") # 训练完整模型以获取特征重要性 rf.fit(X, y) importances = rf.feature_importances_
📖 参数逐行讲解
RandomForestClassifier(...) 创建随机森林分类器对象,关键参数:
n_estimators=500 森林里种 500 棵决策树。树越多结果越稳定,但训练越慢;一般 100~1000 都可以,超过 1000 收益递减
max_depth=None 不限制树的深度,让每棵树充分生长到底。如果担心过拟合可以设成 10~20
min_samples_split=5 一个节点里至少有 5 个样本才允许继续往下分。调大这个值=更保守,树更矮,不容易过拟合
min_samples_leaf=2 叶子节点(最终预测节点)至少要有 2 个样本。防止出现只有 1 个样本的叶子(那就是死记硬背了)
max_features='sqrt' 每次节点分裂时,只从 sqrt(总特征数) 个随机选中的特征中挑最好的。这是随机森林"随机"的核心来源之一,降低树之间的相关性
class_weight='balanced' 自动给少数类更高的权重。如果 T2D 组 30 人、健康组 70 人,设 balanced 后模型不会偏向多数类
random_state=42 固定随机种子,保证每次运行结果一样(可复现)。42 是机器学习社区的惯例数字,用别的也行
n_jobs=-1 用所有 CPU 核心并行训练,加速计算。-1 表示"有几个核就用几个"
StratifiedKFold(n_splits=5, shuffle=True, random_state=42) 分层 5 折交叉验证:把数据分成 5 份,每次用 4 份训练、1 份测试,轮 5 次。Stratified 保证每折中 T2D 和健康的比例和原始数据一致;shuffle=True 先打乱数据再分折
cross_val_predict(rf, X, y, cv=cv, method='predict_proba')[:, 1] 对每个样本获取交叉验证的预测概率。method='predict_proba' 输出概率而非类别;[:, 1] 取第二列(即属于正类/T2D 的概率)
roc_auc_score(y, y_pred_proba) 计算 AUC(ROC 曲线下面积),衡量模型区分两类的能力。1.0=完美,0.5=瞎猜
rf.feature_importances_ 训练后自动生成的特征重要性数组,基于 Gini impurity 的下降量。值越大=该物种对分类贡献越大。常用来画 Top 20 重要物种柱状图
参数默认值白话解释调参建议
n_estimators100森林里有多少棵树一般 100~1000,越多越好但越慢
max_depthNone每棵树最多分多少层None=不限制;设 10~20 可防过拟合
max_features'sqrt'每次分裂只随机看几个特征sqrt 是分类任务的标准选择
min_samples_split2一个节点至少多少样本才能分裂调大=更保守,不容易过拟合
min_samples_leaf1叶节点最少多少样本调大=叶子不会太小
class_weightNone类别权重'balanced' 用于不均衡数据

嵌套交叉验证图解:

嵌套交叉验证(Nested CV)
外层循环(5折)
目的:评估模型泛化能力
每折留出 20% 作为测试集
内层循环(5折)
目的:调参(GridSearchCV)
在剩余 80% 数据上调参,选最优参数
外层 ➔ 防止"用测试数据选参数"的信息泄漏
内层 ➔ 在训练数据内部找最佳超参数

AUC / ROC 解读标准:

AUC 范围解释白话说法
0.5随机猜测模型和抛硬币一样没用
0.5 ~ 0.6很差(Failed)几乎没有区分能力
0.6 ~ 0.7差(Poor)有一点区分能力但不可靠
0.7 ~ 0.8可接受(Fair/Acceptable)有一定预测能力,可以发文章
0.8 ~ 0.9好(Good)模型很不错,临床有参考价值
0.9 ~ 1.0优秀(Excellent)非常强的分类能力(但注意过拟合)
面试追问1:为什么用嵌套 CV?
回答:"普通交叉验证中,如果在全部数据上调参再评估,调参过程已经'偷看'了测试数据,会导致 AUC 虚高(过于乐观)。嵌套 CV 用外层专门评估、内层专门调参,彻底隔离了信息泄漏。"

面试追问2:过拟合怎么判断?
回答:"训练集 AUC 很高(比如 0.99)但测试集 AUC 明显低(比如 0.65),差距大说明过拟合。或者用学习曲线(learning curve)看训练集和验证集的分数随样本量增加的趋势。"
面试追问3:随机森林为什么不容易过拟合?
回答:"两个随机化机制——Bagging(每棵树只用约 63% 的样本训练)和 Feature Subsampling(每次分裂只看 sqrt(p) 个特征),让每棵树都不一样。单棵树可能过拟合,但几百棵不同的树投票取平均,过拟合的部分被抵消了。但注意:样本量太小、特征太多时仍然可能过拟合。"
07 面试高频统计 Q&A — 直接背答案 面试必背
参数检验和非参数检验的区别?
参数检验(t-test, ANOVA)假设数据服从特定分布(通常是正态分布),利用分布参数(均值、方差)做推断。
非参数检验(Wilcoxon, Kruskal-Wallis)不假设特定分布,基于数据的排名(秩)做推断。

白话版:参数检验像是"我知道考试成绩是正态分布的,所以用平均分比较";非参数检验像是"我不知道分布是什么形状,但我可以比较排名"。

微生物组数据几乎默认用非参数,因为 OTU/ASV 丰度数据是零膨胀(很多物种在很多样本中丰度为 0)、右偏(少数物种丰度极高)、非正态的。
什么是 FDR?为什么不直接用 p 值?
FDR(False Discovery Rate)= 在你报告的"显著"结果中,有多少比例是假阳性。

为什么不能直接用 p 值?举个例子:你检测了 1000 个物种,p<0.05 意味着每个物种有 5% 的概率"假显著"。检测 1000 个,期望假阳性 = 1000 × 0.05 = 50 个!如果你不做校正,会有约 50 个物种被你错误地报告为"有差异"。

BH 校正控制 FDR ≤ 5%,意味着你报告的显著结果中最多 5% 是假的——这在发现型研究中是可接受的。

记住:生信文章中,几乎所有差异分析都要报 padj(校正后 p 值),不报 padj 审稿人一定会质疑。
PERMANOVA 的 R² 是什么意思?
R² 表示分组因素解释了群落总变异的百分比。比如 R²=0.07 意味着 7% 的群落组成差异可以用"T2D vs 健康"来解释。

常见困惑:"R² 才 7%,是不是很小?" —— 在微生物组研究中,个体差异极大,R²=5%~15% 是很常见的。人类肠道菌群的个体间差异远大于疾病组间差异,所以不要因为 R² 小就否定结果。关键看 p 值是否显著。

类比:就像"南方人和北方人的身高差异只解释了身高总变异的 3%,但这 3% 确实是显著存在的"。
随机森林为什么不容易过拟合?
随机森林有两重随机化:
1. Bagging(Bootstrap Aggregating):每棵树只用约 63% 的样本训练(有放回抽样),剩余 37% 自动作为 OOB(Out-of-Bag)验证。
2. Feature Subsampling:每次节点分裂只随机选 sqrt(p) 个特征(p=总特征数),降低树之间的相关性。

这两重随机让每棵树都"视角不同",最终投票取平均可以抵消个别树的过拟合。

但注意:当样本量很小(如 n<50)但特征很多(如 p>1000)时,随机森林仍然可能过拟合。这时需要特征选择(如 Boruta、递归特征消除 RFE)来降维。
AUC 0.679 算好还是差?你怎么解释?
AUC 0.679 属于 "差到可接受之间"(Poor to Fair),模型有一定的区分能力但不够理想。

面试中怎么回答:
"我的模型 AUC 为 0.679,虽然还达不到 0.7 的'可接受'门槛,但考虑到 T2D 是多因素疾病,仅靠肠道菌群特征做预测有其局限性。同时,我们的样本量只有 XX 例,可能存在统计功效不足的问题。后续可以通过以下方式改进:
1)增加样本量;
2)结合临床指标(BMI、血糖、年龄等)作为特征;
3)使用嵌套交叉验证 + 特征选择优化模型;
4)尝试其他算法(如 XGBoost、LightGBM)做对比。"

关键:面试中不要回避 AUC 不高的事实,而是展示你知道原因和改进方向——这比一个好看的数字更重要。
组成数据(compositional data)问题是什么?为什么测序数据需要特殊处理?
16S/宏基因组数据得到的是相对丰度(加起来 = 100%),不是绝对数量。这导致:
1. 负相关伪象:一个物种丰度升高,其他物种的比例会被"挤压"下降,即使它们的绝对数量没变。
2. 传统统计方法失效:标准统计假设数据在实数空间,但比例数据被限制在 0~100% 之间(单形空间)。

解决方案:
- CLR 变换(centered log-ratio):把组成数据变换到实数空间
- ANCOM-BC:直接在模型中估计和校正组成偏差
- DESeq2:使用原始 count 数据 + 内部标准化,避免相对丰度问题
你的毕设项目中用了哪些统计方法?为什么这样选?
(参考回答,根据你的真实项目调整)

"我的毕设是 T2D 肠道菌群分析 + 随机森林建模,用到了以下统计方法:
1. Wilcoxon 秩和检验:比较 T2D 组和健康组的 Alpha 多样性(Shannon、Chao1)—— 因为丰度数据非正态。
2. PERMANOVA:检验两组的 Beta 多样性是否有显著差异 —— 配合 PCoA 可视化。
3. DESeq2:找出两组之间的差异物种 —— 用 padj<0.05 和 |log2FC|>1 作为筛选标准。
4. 随机森林:用差异物种的丰度作为特征,建立 T2D 预测模型 —— 用 5 折交叉验证评估,AUC 作为评价指标。
5. 所有多重比较都做了 BH-FDR 校正。

选择逻辑:非参数检验适合微生物数据 ➔ PERMANOVA 看整体差异 ➔ DESeq2 找具体差异物种 ➔ 随机森林做预测验证。"

统计方法速查对照表

方法用途输入数据输出关键值R / Python 函数
Wilcoxon 秩和检验 两组单指标比较 连续型数值(非正态) W 统计量, p-value wilcox.test()
Kruskal-Wallis 多组单指标比较 连续型数值(非正态) H 统计量, p-value kruskal.test()
PERMANOVA 群落整体差异 距离矩阵 + 分组 R², F, Pr(>F) vegan::adonis2()
DESeq2 差异物种/基因 Count 矩阵 log2FC, padj DESeq() + results()
BH-FDR 校正 多重检验校正 一组 p 值 调整后 p 值 p.adjust(method="BH")
随机森林 分类预测 特征矩阵 + 标签 AUC, feature_importances_ RandomForestClassifier()

统计方法交互速查 | 面试常考统计方法 | 2026 年 5 月生成