4. 聚类分析基础概念归纳总结
说到批次效应检测,我个人最常用的先手招就是聚类分析。你想想看,如果数据里藏着批次效应,那不同批次的样本在降维空间里往往会自然抱团——这不就是个天然的聚类问题吗?
不过很多人一上来就调包跑K-Means,结果可视化出来一堆乱糟糟的点,完全看不出批次在哪儿。为什么?因为连聚类的基本假设都没搞明白。今天我们就把这些基础概念捋一遍。
4.1 什么是聚类?它跟分类有什么区别?
用一句话说:分类是有标签的,聚类是没标签的。分类像考试——老师给了标准答案,你只需把新样本对号入座。聚类像拼图——你只有一堆散件,得靠形状、颜色把它们分成几堆,至于每堆代表什么,得分析完才知道。
| 维度 | 分类 (Classification) | 聚类 (Clustering) |
|---|---|---|
| 训练数据 | 有标签 | 无标签 |
| 学习方式 | 监督学习 | 无监督学习 |
| 目标 | 预测类别 | 发现结构 |
| 批次效应检测 | 不适用(哪有批次标签让你训练) | 天然匹配:自动暴露样本间的隐藏分组 |
所以在我们这个场景里,聚类是识别批次效应的主力。我记得刚入行时有个项目,样本按收集年份自然分成了三群,PCA一看全错开。当时我还以为是生物学差异,后来才发现是实验试剂批次不同——这就是聚类暴露的问题。
4.2 核心概念:距离、簇与内聚
所有聚类算法都绕不开三件事:距离怎么算?簇长什么样?多紧才算一簇?
4.2.1 距离度量
说白了,距离越近越可能是一家人。最常用的有这几种:
- 欧氏距离:最直观,高维空间里容易“维度灾难”,但在PCA降维后的低维空间里挺好用。
- 曼哈顿距离:对异常值更鲁棒,我在处理基因表达数据时偶尔会用它。
- 余弦相似度:只看方向不看长度,适合比较表达谱的形状而非强度。嗯,批次效应常体现在整体偏移上,用余弦有时反而能绕过这个坑。
# 在Python里计算欧氏距离和余弦距离
from scipy.spatial.distance import euclidean, cosine
vec1 = [2.1, 3.5, 1.2]
vec2 = [2.3, 3.7, 1.5]
print("欧氏距离:", euclidean(vec1, vec2))
print("余弦距离:", cosine(vec1, vec2)) # 0表示完全相同
4.2.2 簇与簇内相似度
一簇样本在特征空间里应该紧密抱团。衡量簇的“紧密程度”有两个常用指标:
- 簇内平方和 (WCSS):所有样本到簇中心的距离平方和,越小越紧凑。
- 轮廓系数 (Silhouette Score):既考虑簇内紧密度,又考虑簇间分离度,值在[-1,1]之间,越接近1越好。
from sklearn.metrics import silhouette_score
import numpy as np
# 假设我们已经用KMeans得到了labels
X = np.random.rand(100, 3)
labels = np.random.randint(0, 3, 100)
score = silhouette_score(X, labels)
print("轮廓系数:", score)
4.3 常见聚类算法概览
不同算法适合不同形状和规模的数据。处理批次效应时,我根据数据特点来选:
| 算法 | 核心思想 | 适合批次效应的场景 |
|---|---|---|
| K-Means | 基于中心点的硬聚类 | 批次效应导致椭球形簇,快速初筛 |
| 层次聚类 | 自底向上合并或自顶向下分裂 | 想看出批次之间的层次关系(如批次内还有亚批次) |
| DBSCAN | 基于密度的聚类,可识别噪声 | 批次效应让数据形成任意形状的簇,且含有离群样本 |
| GMM(高斯混合模型) | 软聚类,每个样本属于某簇的概率 | 批次边界模糊,样本可能“半在A批半在B批” |
我个人习惯先跑K-Means快速看个大概,如果簇的形状奇怪(比如长条、环状),就换成DBSCAN。有一次在单细胞RNA-seq数据里,批次效应让细胞聚成一条弧线,K-Means完全分不开,换成DBSCAN一下就识别出三个密度中心——每个中心对应一个实验批次。
4.4 如何评价聚类结果?
聚类没有标准答案,但有几个经验法则:
- 肘部法则:K-Means里,画WCSS随K变化的曲线,找到拐点。不过批次效应检测时K往往不大(2~5个批次),所以先猜K等于已知批次数的试试。
- 轮廓分析:计算所有样本的轮廓系数,如果多数样本在0.5以上,说明簇分得还可以。
- 稳定性检验:对数据加一点随机噪声或重采样,看聚类结果是否稳定。如果换个种子就全变了,那说明聚类结构不可靠。
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 肘部法则示意代码
wcss = []
for k in range(2, 10):
km = KMeans(n_clusters=k, random_state=42)
km.fit(X)
wcss.append(km.inertia_)
# 然后绘制wcss随k的变化(此处省略绘图代码)
关键点:在批次效应检测中,我们不是要追求“完美的簇”,而是要看聚类结果是否能对应到批次标签。如果聚类出来的簇与已知批次完全吻合,那批次效应就很明显了。反过来,如果簇内混合了不同批次,说明数据整合得不错。
4.5 聚类与批次效应检测的关系:一张图说清楚
下面这张图是我经验里最常用的流程:从原始数据到最终判断批次效应是否显著。
我的习惯做法:每次做完聚类我都会标上真实批次颜色看一眼,如果两个簇界限分明且颜色基本不混,那批次效应基本实锤了。如果簇内五颜六色,那可以放心往下做差异分析。
4.6 小结:你该记住的
- 聚类是无监督方法,天然适合发现未知的批次分组。
- 距离度量要跟数据特点匹配:PCA降维后欧氏距离最省心。
- 算法不要死磕一个:先K-Means试探,不行再DBSCAN或层次聚类。
- 评估时别忘了可视化,光看指标容易漏掉“形状奇怪”的批次簇。
- 最终判断是看聚类结果能否对应到批次标签,而不是追求聚类指标完美。
嗯,基础概念就说到这儿。下一轮我们会实际动手,用真实数据跑一遍K-Means聚类检测批次效应——到时候这些概念全能用上。