ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Seurat聚类核心:FindNeighbors与FindClusters的图聚类原理与调参实践

Seurat聚类核心:FindNeighbors与FindClusters的图聚类原理与调参实践 做单细胞分析尤其是用Seurat跑标准流程的时候最容易被问倒的一个问题就是“FindNeighbors和FindClusters到底在干什么”多数人会把它们当成两行固定代码跑完看UMAP图出结果就完事。可一旦结果不理想比如细胞群分得太碎、分不出来、或者某个群明显是两种细胞被硬拼在一起很多人就不知道从哪儿下手了。问题恰恰出在没搞懂这两个函数的底层逻辑。FindNeighbors不是简单算个距离FindClusters也不是随便把点聚成几堆。它们背后是一整套“关系图构建”和“社区发现”的数学思路。理解了这套东西你才能在参数选择、结果判读、问题排查这几个环节里真正有底而不是拿0.5、0.8挨个试resolution碰运气。这篇文章我就把这两个函数从输入到输出的完整原理拆开讲一遍从距离计算、K近邻、SNN图的构建到模块度优化、Louvain和Leiden聚类算法都会尽量说得明白。过程中也会穿插我在实际项目中调参和排查问题的一些经验希望能让正在学单细胞分析的朋友少走点弯路。1. 从降维到聚类两个函数到底在流水线里干什么1.1 Seurat标准流程中的位置先把流程捋一遍。Seurat分析单细胞转录组数据的标准路径大概是读入数据、质控过滤、归一化、找高变基因、ScaleData、PCA线性降维、然后就是FindNeighbors接FindClusters最后用UMAP/tSNE做可视化再结合marker基因注释细胞类型。这里有个很关键的认知FindNeighbors和FindClusters并不是在“降维可视化”之后的步骤而是在“降维”和“可视化”之间。UMAP是最后画图用的它本身不负责聚类。真正决定细胞分群结果的是FindNeighbors和FindClusters这两个函数。可以打个比方。PCA跑完后每个细胞在低维空间里是一个点但这些点还没有“关系”。FindNeighbors干的事情就是给每个细胞找到它周围的邻居并且在邻居之间连上线形成一张“细胞关系网”。FindClusters干的事情就是在这张网里找出联系紧密的社区——也就是我们说的细胞类群。UMAP更像是一个“展示工具”它把复杂的网络关系压到二维平面方便我们用眼睛看。所以严格来说聚类的“决策”发生在图里不是发生在UMAP图里。你看UMAP图上两个细胞群分开了本质是它们在FindNeighbors构建的图里联系比较稀疏被FindClusters切开了。1.2 为什么不能直接用原始表达矩阵聚类很多刚接触的人会问既然要分群为什么不直接拿表达矩阵做k-means或者层次聚类这涉及几个层面的问题。第一维数灾难。一个细胞经过质控后通常会检测到几千个基因的表达。如果把这几千个维度直接用来算距离绝大多数细胞之间的距离都会非常接近聚类算法很难区分出有意义的结构。打个比方你在一条街上辨别邻居靠的是门牌号但如果把全中国所有街道的门牌号放在一起比较你就很难说谁跟谁是邻居。PCA的作用就是把这几千维压缩成几十维把主要的结构性差异提取出来。第二表达矩阵稀疏且噪声大。单细胞数据有大量的dropout基因没有检测到表达但可能只是技术原因直接拿原始矩阵算距离噪声会淹没信号。经过高变基因筛选和PCA降维后我们保留的是细胞间差异最稳定、最有生物学意义的信息。第三细胞类群的边界是模糊的。真实的细胞状态往往是连续变化的过程比如从干细胞到分化终末状态中间过渡态细胞无处不在。传统聚类算法比如k-means需要预先指定类别数量K而且倾向于把细胞硬性划分成球形簇。这显然不符合单细胞数据的真实特点。所以Seurat的思路不是直接“聚”而是先把细胞的局部关系变成图然后在图上做社区发现。这种方法不需要预先指定K值虽然resolution也会影响群数量而且能捕捉复杂的非线性结构——比如同一个细胞类型内部有多个亚群或者两个不同细胞类型之间有一条分化轨迹相连。2. FindNeighbors原理把细胞拓扑关系变成一张图2.1 距离计算与主成分选择FindNeighbors的输入一般是降维后的矩阵。默认情况下Seurat会用PCA的结果也就是embedding为“pca”的降维矩阵。函数内部做的事第一步是计算细胞两两之间的距离。这里要强调一下FindNeighbors默认使用欧几里得距离。欧氏距离的公式很简单两个细胞在PCA空间里的坐标差平方和再开方。但这里有一个极易被忽视的参数dims。你选择用哪些PC来计算距离直接决定了细胞之间的“远近距离”怎么定义。选太少PC会丢失真实的细胞差异信息选太多PC会把噪声也当作信号。比如你在第50个PC之后开始进入“噪声平缓区”这里的维度几乎只是技术噪声如果它们参与距离计算就会把原本相似的细胞“推远”把不相似的细胞“拉近”。在实际分析中确定dims的常用方法有两种。一种是ElbowPlot画主成分的方差贡献率看曲线在哪个位置变平选取拐点之前的PC。另一种是JackStraw的置换检验统计每个PC的显著性。我个人的经验是ElbowPlot看拐点配合后续聚类结果的稳定性来定往往是更实用的方式。死记硬背“用前20个PC”并不保险因为不同数据的复杂度差别很大。2.2 K近邻与SNN单看距离还不够距离算完之后最朴素的想法是离得近的就是邻居。但单细胞数据里简单的K近邻k-nearest neighborskNN直接建图会有一个大问题——在PCA空间里坐标的绝对值受测序深度、批次效应、dropout模式影响很大单纯用距离会引入大量假阳性连接。Seurat的做法是用共享最近邻Shared Nearest NeighborSNN来权衡细胞之间的关系。思路是这样的两个细胞如果它们各自有大量共同的邻居那即使它们在PCA空间里距离远一点我们也可以认为它们是“真正的邻居”反过来如果两个细胞距离近但几乎没有共享邻居那它们可能只是在高维空间偶然靠近不是真正的结构关系。具体实现分两步。第一步对每个细胞按照欧氏距离找最近的k个细胞作为它的K近邻。k由参数k.param控制默认值是20。第二步计算所有细胞之间的SNN关系——如果细胞A和细胞B共享了m个邻居在这两者的k近邻集合中同时出现的细胞数量那么它们之间的边的权重就用这个共享邻居数来衡量。在Seurat里边的权重用的是Jaccard相似度公式是两个细胞的共享邻居数除以它们的邻居集合的并集大小再乘以一个调整系数。Jaccard系数的取值范围在0到1之间值越高说明两个细胞在网络中的“朋友圈”重叠度越高关系越紧密。这比单纯看距离更抗噪——它关注的是两个细胞共享的“社交圈子”而不是它们在空间里的绝对位置。这里有个细节值得注意不是所有细胞对之间都会存在边。在kNN图里每个细胞只有k条边连向它的邻居。所以K的选择很关键。k太小比如5每个细胞的邻居太少网络会分裂成很多小块聚类结果会很碎k太大比如50图中会充满弱连接不同类群之间的边界会被模糊掉聚类的分辨率就下降了。默认k20在大多数数据集上表现不错但如果你发现聚类群体形状怪异或者群很碎k值是需要考虑调整的调参项。2.3 图的构建表达矩阵变成了邻接矩阵距离和邻居计算完成后FindNeighbors的结果本质上是一个“图”graph对象。这个图是稀疏加权图顶点是细胞边是细胞之间的邻居关系边的权重是SNN/Jaccard相似度。Seurat里这个图会存储为一个稀疏邻接矩阵矩阵的行和列都是细胞矩阵中某个位置的值就是对应两个细胞之间边的权重。由于每个细胞只连向少数邻居大部分位置是0稀疏矩阵在内存上非常节省。你可以在分析结果里用graphs(obj)查看现在存了哪些图对象默认会有两个一个是RNA_nn基于K近邻的二值图边的权重为1另一个是RNA_snn带权重SNN图。这里顺带说明一下为什么需要两个图。nn图是纯粹的二值邻接关系用于某些算法需要用到邻接关系的场景snn图则带有权重体现细胞之间关系的强弱FindClusters默认会使用snn这个加权图。还有一个比较隐蔽的点当使用FindNeighbors时reduction参数决定用哪套降维结果。如果只是默认的PCA没问题但如果你的数据经过了整合比如Harmony或者Seurat的CCA整合你可能会选用整合后的降维空间来构建邻接图。这在处理多批次数据时非常重要——如果直接用原始PCA构建图批次效应会把同类型细胞拆散到不同的群里。3. FindClusters原理社区检测与模块度优化3.1 聚类问题是怎么变成图分区问题的FindNeighbors把细胞之间的“关系网”搭好了接下来FindClusters要做的事就是在这张网上“切几刀”把联系紧密的区域分成一个个社区。为什么把聚类转化为“图分区”问题因为图结构能很好地表达细胞的局部结构。在之前的SNN图里同一个细胞类群内部的细胞之间边很多、权重高不同细胞类群之间边少、权重低。我们要找的“类群”正是图上那些内部稠密、外部稀疏的区域——这在社会网络里叫“社区”community。Seurat的FindClusters默认用的就是社区发现算法不是传统聚类算法。它会从图里找出一组“分区”使得同一分区内部的连接尽量紧密而不同分区之间的连接尽量稀疏。3.2 模块度的直观理解社区发现算法里有几个经典的目标函数比如模块度modularity就是最常用的之一。模块度的核心思想是一个好的社区划分社区内部的边数量应该显著大于随机网络的期望值。所谓随机网络是指在保持每个节点度数不变的情况下随机重新连接这些边。如果某个划分结果中社区内部的边数远超随机期望说明这个社区不是偶然凑到一起的而是真的有结构。模块度Q的公式虽然是数学形式但直觉可以这样理解你把整张网络切成几个小区块然后数一数每个小区块内部的边比随机情况下多出来多少。多出来的越多Q值越高分区质量越好。Q的取值范围通常在-1到1之间一般大于0.3就算有一定社区结构了。你可能会问那直接穷举所有可能的划分取最大Q值不就行了实际上不行——对所有划分方式做全量搜索是指数级的计算量细胞数量一多根本算不过来。所以Seurat用的是一些启发式优化方法其中最经典的就是Louvain算法。3.3 Louvain与Leiden迭代优化Louvain算法是一种贪心优化算法主要分两步反复迭代。第一步是“模块度优化”一开始每个节点各自成一个社区然后依次尝试把每个节点迁移到邻居社区里如果迁移后模块度的增加大于0就执行这个迁移。反复循环直到模块度不再增加。第二步是“社区聚合”把第一步形成的每个社区合并成新的超节点类似“缩点”更新节点之间的边权重然后回到第一步重新跑。这样一轮一轮下来社区数量逐渐减少直到模块度不再显著变化。实际跑Seurat的时候你会在FindClusters里看到algorithm 1默认就是Louvain算法的完整实现。你还会在Seurat 4之后的版本里看到algorithm 4对应Leiden算法。Leiden算法是Louvain的一个改进版本它在第一步之后增加了一个“细化”阶段确保划分出的每个社区内部是连通的。这里有必要解释一下为什么Leiden比Louvain好。Louvain有个著名的问题它会把一些本来应该属于同一个社区的节点因为局部模块度增益的差异拆成两个不连通的碎片区域更糟糕的是这些碎片还会被单独当作社区保留下来。Leiden算法修正了这个问题保证最终社区内部是连通的这在分析连续分化的细胞状态时特别重要——中间状态的细胞不会被随意分割成互不相连的孤立小块。Seurat从4.0版本开始逐渐推荐Leiden算法。你可以在FindClusters里设置algorithm 4来启用Leiden它会调用igraph包里的cluster_leiden函数。我在实际项目里对比过对同一份数据用Louvain和LeidenLeiden得到的分群稳定性通常更好尤其在数据量比较大、细胞类型多、有过渡状态的时候。还有一个隐藏的细节FindClusters默认不是直接把每个细胞分到群而是会先从邻接矩阵里移除那些孤立节点没有边连向其他细胞的细胞然后跑社区发现算法最后把孤点单独作为一个群。所以你在结果里偶尔看到-1或者单独的群可能不是因为聚类算法出错而是一些“离群”细胞根本没有进入图的计算。3.4 resolution参数到底控制的是什么这是很多人最关心的参数。很多教程会说“resolution调大群变多”但没解释为什么。在有数学背景的社区发现算法里模块度的定义里有一个分辨率参数resolution通常记作γ。这个γ代表的是“对跨社区连接的惩罚强度”。当γ较小时算法倾向于合并小区块成大社区群数量少当γ较大时算法对社区之间的连接更敏感倾向于把大社区切分成更细的亚群。在Seurat的FindClusters里resolution参数其实就是这个γ。区别在于Louvain算法的标准实现可以直接把resolution因子乘到模块度更新公式里。所以你在Seurat里调resolution本质上就是调模块度优化函数对社区粒度的敏感度。经验范围一般是0.1到1.2。0.1到0.3适合合并成比较粗的大类群比如区分免疫细胞、上皮细胞、基质细胞这些大类0.4到0.8适合进一步细分比如区分T细胞里的CD4和CD8亚群0.8以上适合寻找稀有亚群或疾病状态特异的细胞群体。但要注意resolution并不是唯一决定聚类粒度的因素。你输入的图结构也就是k.param和dims的选择已经决定了哪些连接是存在的resolution只是在已有图上做切割。如果图本身建得不好比如PC选太少导致同类细胞之间没有建立连接那不管怎么调resolution也切不出有意义的结果。4. 从原理到实战参数怎么调才算靠谱4.1 dims与k.param的选择策略先讲dims。PCA跑了多少个主成分不等于你要全用到。我见过不少人在做单细胞分析时直接抄作业默认dims 1:20。但不同数据集的复杂度差距很大比如一个只有5000个细胞、细胞类型比较简单的样本可能前15个PC就够了一个10万个细胞、包含多种稀有亚群和连续分化状态的数据集可能需要前30个甚至更多PC。判断dims选择是否合理的办法不是只看ElbowPlot还要看聚类结果的稳定性。你可以先用一个比较宽的dims范围比如1:30跑一遍聚类再看ElbowPlot的拐点如果PC20之后的方差贡献率已经趋于平缓那就可以用1:20然后看聚类结果和marker基因是否对应。如果marker基因出现了混杂可以试着把dims范围调大或调小看聚类结果是否稳定。再说k.param。前面提到k.param默认值是20但这个默认值是通过大量数据集调优出来的经验值不是万能值。数据量很大的时候比如超过5万个细胞k20容易导致每个细胞的邻居太少局部信息不够造成群与群之间出现大量“碎片”。我一般会随着细胞数增加适当调大k值比如5万细胞用25到30。反过来如果细胞数很少几千个k20又可能让群之间过度连接此时可以试着减小k到10到15让边界更清晰。这里提供一个我常用的判断思路跑完聚类后看每个群的细胞数和生物学意义。如果出现太多细胞数只有两三个的小群而且这些群在UMAP上也不成独立岛屿往往说明图的局部连接不够稳定k需要调大一点。如果出现两个原本明显不同的大细胞群被连成一条“有桥”的结构可能说明k值太大边界连接过强。4.2 resolution调试的正确姿势很多新手会死磕resolution把0.1到1.2全部试一遍最后挑一个“看起来好看”的。这种做法不是完全不行但你会陷入一个误区只看群的形状不看群的生物学意义。我推荐的做法是这样的先跑几个基准resolution比如0.2、0.5、0.8、1.0看看群的层级关系。比如0.2时得到免疫细胞、上皮细胞、基质细胞这三大类0.5时免疫细胞拆成髓系和淋巴系0.8时髓系再拆成巨噬细胞亚群、树突状细胞亚群淋巴系再拆成T细胞、B细胞、NK细胞群。这样一层层看下来你就会明白哪些分群层级是稳定的哪些是受resolution影响的。然后结合marker基因验证每个群是否表达了已知的细胞类型标志基因一个群内部是否还混有两个不同谱系的基因表达模式如果某个分辨率下marker基因清晰、互不混杂那这个resolution就是合理的如果marker基因在跨群之间弥漫表达或者一个群里同时出现两套互斥的标记那就说明分辨率或参数并不合适。在实际操作中我还有一个小技巧先在一个适中分辨率比如0.5下跑出基础分群然后对感兴趣的大类群单独提取出来做一次子聚类subset后重新FindNeighbors和FindClusters。这样比直接调高整体resolution要可控得多——因为整体分辨率调高时可能把那些本来很稳定的大类群也给切碎了。4.3 聚类后如何验证结果可不可信聚类结果不是跑完就算完至少要经过三步验证。第一步是看UMAP分布。虽然UMAP不是聚类依据但它能直观反映细胞群的分离度。如果聚类的群在UMAP上有明显的重叠或者一个群内部有明显的一分为二的结构这往往提示聚类尺度太粗或太细。第二步是看marker基因。对每个群做FindAllMarkers提取高表达且特异性高的marker基因看是否符合已知生物学知识。比如T细胞群应该表达CD3D、CD3E等T细胞标志基因B细胞群应该表达MS4A1、CD79A等巨噬细胞群应该表达LYZ、CD68等。如果marker基因和群注释对不上优先怀疑参数设置而不是强行注释。第三步是看差异表达基因的效应量。FindAllMarkers默认输出avg_log2FC、p_val_adj等统计量。一个好看的群内部细胞的差异between群应该远大于within群。如果很多marker基因的avg_log2FC只有0.25以下即使P值显著区分度也很弱可能是分辨率调太高导致的过度切分。另外还有一点容易被忽略聚类的稳定性和可重复性。你可以把同一数据随机抽取80%的细胞重新跑一遍流程看看几个主要群是否还能稳定复现。如果某个群只能在50%的抽样子集里出现那它可能是靠少量离群细胞撑起来的不够可靠。5. 常见问题与排查技巧实录5.1 聚类结果“糊成一团”分不出边界这是我被问得最多的问题之一。你跑了FindClustersresolution调到0.8UMAP图还是糊的整个图上的细胞均匀分布没有明显的分离岛屿。优先检查这几个方向。第一检查PC选择。如果dims范围太小细胞之间的关键差异没有被纳入距离计算图里就不会有强连接分割线。试着扩大dims范围比如从1:15改成1:30看聚类是否有改善。第二检查是否做了ScaleData。Seurat的流程要求在PCA之前必须先ScaleData如果不做标准差的权重不对PCA结果会失真距离计算也就不靠谱。我见过新手把ScaleData漏掉然后跑出糊图的情况加了之后群立刻分开。第三检查数据是否包含大量低质量细胞或双重细胞。双细胞会把两个类型的不同表达谱拉进同一个细胞导致图中有大量“桥”连接分割困难。可以用DoubletFinder或Scrublet去预测双细胞过滤后再聚类。第四考虑批次效应。如果你的数据是多个样本合并跑出来的批次效应会把同类型细胞分隔在不同区域。必须先用整合方法如Harmony或FindIntegrationAnchors消除批次效应后再重新构建邻接图。5.2 聚类分得过碎出现大量小群有时候resolution不高但聚类结果还是有很多细胞数只有十几个的小群或者同一个细胞类型被拆成好几块。这时先检查k.param。图连接太多会让一些噪声区域变成独立小社区。把k减少到10到15通常能减少碎群。反过来如果小群是因为图连接太少增加k到30让同一类型的细胞更充分连接也有帮助。还要检查一下dims里是否包含太多噪声PC。如果你选到第50个PC后面这一段基本是噪声它们会让许多细胞产生“假的相似性”把本不相关的细胞连到一起导致一些奇怪的小群。重新用ElbowPlot确定合理的dims范围。此外小群也可能是真实存在的稀有细胞亚群。比如肿瘤微环境里的某些罕见免疫细胞亚群、循环肿瘤细胞等它们细胞数本来就少。判断标准还是看marker基因如果小群能明确表达对应已知的marker那它就是真实亚群不需要强行合并。5.3 一个群明显混有两种细胞类型最典型的情况是某个群在UMAP上看起来是“融合”的状态提取marker基因后发现有两种互斥的标志基因都在这个群里高表达。比如既有T细胞markerCD3D又有髓系markerLYZ这说明这个群里混了两种细胞。大概率是以下原因之一。一是这个群其实是双细胞污染一个T细胞和一个髓系细胞被液滴包在一起在聚类中被当作了一个细胞。可以在分析前跑一遍双细胞检测工具来减小这个风险。二是分辨率不够两种细胞之间的图连接太强还没被切开。试着提高resolution把这个群拆成两个。三是这两个细胞类型之间存在真实的连续分化状态比如单核细胞向巨噬细胞分化或者T细胞向效应记忆阶段发育中间状态的细胞表达两种类型的基因程序聚类时会被合在同一个群。这种情况需要更细致的亚聚类和轨迹分析来解析而不是简单地把群拆开。5.4 Seurat 5里代码跑不通或者结果和以前不一样Seurat 5.0发布后FindClusters和FindNeighbors的默认行为有一些变化最直接的一点是图对象的默认存储名称、assay的对接方式都有调整。如果你的代码是跟着4.x的教程写的升级到5.0后FindClusters(graph.name RNA_snn)这类参数可能会报错或者找不到对象。解决办法很简单升级后先看当前Seurat对象的graphs槽位里到底存了哪些图用DefaultAssay()确认当前active assay是哪套再用精确的图名传入FindClusters。如果你用的是RNA assay通常传入graph.name RNA_snn如果用整合后的assay就要注意名称对应。另一个常见坑是Seurat 5引入了layers的概念来管理多份数据切片。如果你的对象是从10x的多个样本生成的直接跑FindNeighbors可能会发现邻接矩阵的维度对不上因为某些基因在部分样本中没有表达。这时候需要先用JoinLayers把assay的数据层合并起来再进入聚类流程。这个细节在新手教程里很少讲到但实际项目中经常遇到。5.5 不同分辨率跑出来的结果很“跳跃”有些数据在一个resolution下分群稳定稍微调高0.1某个方向的分群结果就发生“重组”产生完全不同的群组合。这通常说明你的图结构不够稳定也就是FindNeighbors阶段的信息不够强。怎么应对呢我的习惯是先确定一个主分析用的resolution用这个分辨率跑出大群然后用marker基因注释。接着对这个分辨率下的每个大群再做一次子聚类subcluster子聚类时可以用更高的resolution和更合适的dims。这样既能保证大类群方向的稳定又能挖掘细粒度异质性。另外Leiden算法的稳定性通常比Louvain好。如果Louvain下每次跑出来的结果在局部有跳动可以切换到algorithm 4试试它会更稳定一些。6. 工具选型与其他聚类算法的补充对比讲到这儿可能有人会问Seurat内部这些图聚类算法跟其他单细胞聚类方法比如scanpy的Leiden或者直接上k-means到底有什么区别先说k-means。它在低维空间把细胞硬分成K个球形簇边界是线性分割对复杂的高维流形适应能力差单细胞数据基本不适合直接用。再说层次聚类。它虽然不需要K值但计算复杂度高在几万个细胞的规模上非常慢而且它把每个细胞都归到一个叶子节点不适合连续分化数据的分析。社区发现算法Louvain/Leiden更适合单细胞数据的原因有三个。第一它不要求K值而是通过图结构天然决定社区数量第二它识别的是“群体”结构对连续分化状态相对宽容第三它的计算效率很高能扩展到几十万甚至百万级别的细胞数据。那如果非要用Seurat以外的工具scanpy的Leiden实现和Seurat的Leiden实现本质上是同一套图聚类思路但leidenalg库的参数面稍不同最常用的resolution参数定义基本一致。跨工具对比结果时不要惊讶于小差异因为PCA处理、标准化流程、邻居数选择的差异都会影响最终结果。工具选择上我个人的看法是在单细胞质量管理、整合流程都做得规范的前提下Seurat和scanpy的聚类结果通常在大方向上高度一致。真正影响结果的是上游的QC、去批次、PC选择和聚类参数工具本身反而不是最大的变量。这里也顺带提一个容易被忽略的点如果数据整合用的是Harmony那么FindNeighbors建议用整合后的Harmony降维空间也就是reduction harmony而不是PCA。因为Harmony已经做了批次效应的校正用它的嵌入维度来计算细胞间的距离可以避免批次效应主导图的构建。这个问题在包含多个样本的实验设计中尤其重要很多人就是因为这里没注意导致同类型细胞跨样本被拆到不同群。结尾一点个人体会说回最初那个问题——不理解FindNeighbors和FindClusters的原理能不能跑完流程能。但能不能把结果解释好、能不能在结果不对的时候定位问题就看你对这两个函数有没有真正的理解。我自己的体会是做单细胞分析最忌讳把工具当黑盒。哪怕只是知道了“FindNeighbors是建图FindClusters是切图”这一层你面对一堆聚类结果时会更有底气。比如看到两个群之间有奇怪的连接你不会只是想着把resolution调大而是会回头看看是不是这个群之间的SNN权重太高是不是PCA维度选得不够是不是数据里有双细胞——每一个排查方向都对应着明确的生物学问题。如果你现在正在学单细胞分析我建议你跑完流程之后专门花点时间把你自己的数据在FindNeighbors后打印出来的graphs对象看一下感受一下图的节点和边再尝试换一组dims换一个k.param看看聚类结果怎么变化。这个“动手感受参数”的过程比背十遍教程都有用。还有一个小建议在最终结果汇报的时候不要只给出一张UMAP图最好在方法部分写明FindNeighbors用的dims范围、k.param还有FindClusters的resolution和algorithm。别人拿你的结果做比较或复现时这些细节比UMAP的配色重要得多。单细胞数据分析这条路很多情况都是在“模糊中求真”。理解了原理你起码能知道模糊来自哪里。
返回列表