v1.11 — Edição de 2026. Um guia abrangente para a análise single-cell utilizando o Scanpy (v1.11 - 2026). Aprenda a pré-processar, visualizar, fazer clustering e inferir trajetórias para dados escaláveis de expressão génica single-cell.
Computação CientíficaAnálise de Célula ÚnicaBioinformática
Descubra as ideias fundamentais por trás do Scanpy e por que razão foi construído para análises single-cell escaláveis. Exploramos o objeto AnnData, a estrutura de dados central que mantém matrizes, anotações e embeddings perfeitamente alinhados. Irá aprender o modelo mental necessário para navegar no ecossistema do Scanpy.
4m 24s
2
Métricas de Controlo de Qualidade
Exploramos como realizar o controlo de qualidade inicial em dados single-cell utilizando o Scanpy. Ao isolar populações de genes específicas, como o RNA mitocondrial, podemos identificar células em stress ou a morrer. Irá aprender a calcular e interpretar estas métricas cruciais de controlo de qualidade.
3m 19s
3
Filtragem e Normalização
Este episódio aborda os passos críticos de filtragem e normalização de matrizes de expressão single-cell. Explicamos como descartar dados de baixa qualidade e aplicar o dimensionamento da profundidade de contagem com uma transformação log1p. Irá aprender a tornar células com diferentes profundidades de sequenciação diretamente comparáveis.
3m 37s
4
Deteção de Doublets com o Scrublet
Mergulhamos na deteção de doublets, um passo crucial para detetar artefactos técnicos na sequenciação single-cell microfluídica. Detalhamos como o Scrublet simula doublets artificiais para sinalizar células suspeitas. Irá aprender a identificar e remover estas combinações artificiais do seu dataset.
3m 27s
5
Seleção de Features e Genes Altamente Variáveis
Examinamos o conceito de seleção de features e por que razão é necessário identificar genes altamente variáveis. Ao descartar o ruído de genes de manutenção, focamos a análise nos impulsionadores biológicos. Irá aprender a utilizar o Scanpy para isolar os genes mais informativos para os passos seguintes.
3m 24s
6
Pontuação e Regressão do Ciclo Celular
Exploramos como lidar com fatores de confusão através da pontuação e regressão das fases do ciclo celular. Discutimos como calcular as pontuações S e G2M e utilizar a regressão para remover a sua influência. Irá aprender a evitar que a divisão celular ativa arruíne a topologia do seu clustering.
3m 29s
7
Redução de Dimensionalidade com PCA
Este episódio explica a Análise de Componentes Principais (PCA) no contexto de dados single-cell. Discutimos como o PCA reduz o ruído do dataset e por que razão a seleção do número certo de componentes é importante. Irá aprender a reduzir milhares de genes para uma base gerível destinada a algoritmos avançados.
3m 42s
8
O Grafo de Vizinhos Mais Próximos e o UMAP
Desconstruímos o núcleo absoluto da topologia single-cell moderna: o grafo de vizinhos mais próximos. De seguida, explicamos como o UMAP traduz esta teia complexa num gráfico 2D legível. Irá aprender por que razão o grafo de vizinhos é o pré-requisito para quase todas as ferramentas avançadas no Scanpy.
3m 30s
9
Clustering com o Leiden
Exploramos como encontrar populações discretas de células utilizando o algoritmo de clustering Leiden. Ao otimizar a modularidade no grafo de vizinhança, o Leiden isola comunidades altamente conectadas. Irá aprender a ajustar o parâmetro de resolução para encontrar grupos estáveis e biologicamente significativos.
4m 00s
10
Descoberta de Genes Marcadores
Mergulhamos na descoberta de genes marcadores e em testes de expressão diferencial. Explicamos como os testes estatísticos identificam as assinaturas transcriptómicas únicas dos seus clusters. Irá aprender a transitar de clusters numerados anónimos para tipos de células biológicas rotulados com confiança.
4m 20s
11
Integração de Dados com o Ingest
Este episódio aborda a integração de dados utilizando a ferramenta Ingest. Explicamos como projetar novos datasets no espaço PCA e UMAP de um atlas de referência pré-anotado. Irá aprender um método rápido e invariante para mapear rótulos entre diferentes experiências.
3m 53s
12
Visualização de Padrões de Expressão
Exploramos técnicas avançadas de visualização para avaliar a expressão génica entre clusters. Focamo-nos em dot plots e matrix plots, detalhando como estes codificam tanto a intensidade de expressão como a esparsidade. Irá aprender a validar visualmente as suas anotações de tipos de células num piscar de olhos.
3m 33s
13
Exploração de Manifolds com Diffusion Maps
Introduzimos os Diffusion Maps, uma poderosa técnica de embedding para dados biológicos contínuos. Contrastamo-la com o UMAP, explicando por que razão a difusão é mais adequada para analisar a diferenciação celular. Irá aprender a visualizar transições contínuas e processos de desenvolvimento.
3m 57s
14
Grafos Abstraídos com o PAGA
Este episódio aborda a Partition-based Graph Abstraction, ou PAGA. Discutimos como medir a conectividade real entre clusters para preservar a topologia global. Irá aprender a utilizar o PAGA para descobrir as verdadeiras relações de linhagem ocultas nos seus dados.
3m 32s
15
Inferência de Trajetórias com DPT
Exploramos a inferência de trajetórias utilizando o Diffusion Pseudotime (DPT). Explicamos como designar uma célula raiz e calcular distâncias geodésicas através do grafo celular. Irá aprender a organizar as células ao longo de uma linha temporal de desenvolvimento contínua.
3m 46s
16
Aumento de Escala Experimental com o Dask
No nosso último episódio, olhamos para a fronteira experimental do Scanpy: o aumento de escala com o Dask. Explicamos como lidar com datasets que excedem a RAM da sua máquina utilizando lazy evaluation e processamento out-of-core. Obrigado por se juntar a nós neste mergulho profundo no Scanpy!
3m 34s
Episódios
1
A Identidade do Scanpy e o AnnData
4m 24s
Descubra as ideias fundamentais por trás do Scanpy e por que razão foi construído para análises single-cell escaláveis. Exploramos o objeto AnnData, a estrutura de dados central que mantém matrizes, anotações e embeddings perfeitamente alinhados. Irá aprender o modelo mental necessário para navegar no ecossistema do Scanpy.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Análise Single-Cell com Scanpy, episódio 1 de 16. Os datasets de single-cell explodiram de milhares para milhões de células em apenas alguns anos. Tenta carregar essa escala em toolkits mais antigos e pesados na memória, e a tua máquina vai bloquear. É exatamente esse o problema que o Scanpy resolve.
O Scanpy é um toolkit escalável criado para analisar datasets massivos de expressão génica de single-cell em Python. Gere a memória de forma eficiente, recorrendo a uma estrutura de dados base altamente específica. Essa estrutura chama-se Annotated Data, ou AnnData.
Quem vem de dados tabulares normais assume muitas vezes que o AnnData é apenas um dataframe do pandas personalizado. Não é. Um único dataframe é demasiado plano para a biologia de single-cell. Numa experiência de single-cell, tens uma matriz enorme de contagens de expressão, mas também tens metadados complexos sobre as células e metadados completamente separados sobre os genes. O AnnData é um container multidimensional que une a matriz principal e todos os seus metadados associados num único objeto sincronizado.
Considera um cenário em que estás a carregar um dataset de um milhão de células. No centro do teu objeto AnnData está a matriz de dados principal, acedida através do atributo dot X. Esta é uma matriz bidimensional que contém os teus valores numéricos reais, tipicamente contagens de expressão génica. As linhas representam sempre observações, que são as tuas células individuais, e as colunas representam sempre variáveis, que são os teus genes. Para um dataset de um milhão de células, o dot X é quase sempre armazenado como uma matriz esparsa para conservar RAM.
Aqui está o ponto chave. A matriz no dot X não armazena os seus próprios nomes de linha ou coluna. Depende inteiramente de dois dataframes de metadados dedicados para fornecer esse contexto.
Os primeiros são os metadados de observação, acedidos através do atributo dot obs. Este é um dataframe standard do pandas mapeado diretamente para as linhas da tua matriz dot X. Contém tudo o que sabes sobre as células. Para o teu dataset de um milhão de células, o dot obs terá exatamente um milhão de linhas. É aqui que vivem os teus barcodes das células, batch labels, métricas de controlo de qualidade e atribuições de clustering.
Os segundos são os metadados das variáveis, acedidos através do atributo dot var. Este é outro dataframe mapeado diretamente para as colunas da tua matriz dot X. Contém tudo o que sabes sobre os genes ou features que mediste. É aqui que armazenas os símbolos dos genes, as localizações cromossómicas e métricas estatísticas, como flags de genes altamente variáveis.
Como o dot obs e o dot var estão estritamente alinhados com as dimensões do dot X, podes fazer slice do objeto AnnData com segurança. Se filtrares células mortas do dot obs, o objeto AnnData descarta automaticamente as linhas correspondentes da matriz dot X. O alinhamento dimensional nunca se quebra.
Existe mais uma camada crucial na estrutura AnnData. À medida que processas os teus dados de single-cell, geras representações multidimensionais das tuas células, como componentes principais ou coordenadas UMAP. Estes outputs não encaixam perfeitamente numa única coluna do dot obs. Em vez disso, vão para um dicionário separado chamado dot obsm, que significa observation matrices. A única regra é que qualquer matriz que coloques no dot obsm tem de ter exatamente o mesmo número de linhas que o dot X.
Ao manter a matriz principal, os metadados das células e os metadados dos genes trancados numa estrutura de atualização automática, o AnnData garante que os teus dados se mantêm perfeitamente sincronizados desde o primeiro passo de filtragem até à visualização final.
Se achas estes episódios úteis, podes apoiar o programa procurando por DevStoriesEU no Patreon. Como sempre, obrigado por ouvires. Vemo-nos no próximo episódio.
2
Métricas de Controlo de Qualidade
3m 19s
Exploramos como realizar o controlo de qualidade inicial em dados single-cell utilizando o Scanpy. Ao isolar populações de genes específicas, como o RNA mitocondrial, podemos identificar células em stress ou a morrer. Irá aprender a calcular e interpretar estas métricas cruciais de controlo de qualidade.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 2 de 16. A maneira mais rápida de arruinar uma análise single-cell é manteres, sem saberes, células a morrer ou vazias no dataset. Podes pensar que estás a descobrir uma nova subpopulação, mas na verdade estás apenas a fazer clustering de detritos celulares. Expor estas células comprometidas depende inteiramente de Quality Control Metrics.
Vamos esclarecer uma coisa logo desde o início. As pessoas muitas vezes confundem o cálculo de métricas de qualidade com a filtragem de bad data. Não são a mesma coisa. A função do Scanpy calculate qc metrics não remove uma única célula ou gene do teu dataset. É estritamente uma ferramenta de anotação. Calcula estatísticas e anexa-as como novas colunas ao teu dataframe de observações, que rastreia células, e ao teu dataframe de variáveis, que rastreia genes. A verdadeira remoção das células más acontece num passo separado.
Porque é que precisamos destas métricas específicas? Considera uma amostra de medula óssea. Durante a extração, o stress físico pode romper células frágeis. Quando a membrana celular rebenta, o RNA citoplasmático vaza e é lavado. No entanto, as mitocôndrias estão envolvidas pelas suas próprias membranas, por isso o RNA mitocondrial fica preso dentro da carapaça da célula rompida. Se sequenciares esta droplet, vais obter uma alta concentração de genes mitocondriais e muito pouco mais. Isto é uma célula morta.
Para identificares estas células rompidas, precisas de rastrear populações de genes específicas. Em datasets humanos, os genes mitocondriais começam tipicamente com o prefixo MT traço. Os genes ribossómicos podem começar por RPS ou RPL. Antes de poderes calcular métricas para estas populações, tens de as rotular no teu dataset. Fazes isto criando uma nova coluna boolean no teu dataframe var. Por exemplo, crias uma coluna chamada mt que avalia para True se o nome do gene começar por MT traço, e False caso contrário.
Assim que tiveres sinalizado estes genes, corres a função calculate qc metrics. Por default, esta função calcula estatísticas de baseline padrão, como o número total de counts de RNA por célula e o número de genes expressos por célula. Mas também lhe podes dizer para olhar para as populações de genes específicas que acabaste de definir. Passas o nome da tua coluna boolean, como mt, para o argumento qc vars.
A função depois calcula a proporção de counts com origem nesse grupo específico de genes. Adiciona novas colunas ao teu dataframe obs. Uma coluna vai mostrar os counts totais de genes mitocondriais para cada célula. Outra coluna, mais crítica, vai mostrar a percentagem dos counts totais que vêm de genes mitocondriais. Se uma célula mostrar que trinta por cento do seu RNA é mitocondrial, tu sabes que é provavelmente uma célula rompida e a morrer devido ao processo de extração.
Aqui está o insight principal. A função calculate qc metrics transforma matrizes de counts raw e não interpretáveis em sinais biológicos sobre a saúde da célula. Não toma decisões por ti, mas, ao fazer o tagging de populações de genes específicas, dá-te a evidência numérica exata de que precisas para separar a biologia real do ruído de extração.
Obrigado por passares uns minutos comigo. Até à próxima, fica bem.
3
Filtragem e Normalização
3m 37s
Este episódio aborda os passos críticos de filtragem e normalização de matrizes de expressão single-cell. Explicamos como descartar dados de baixa qualidade e aplicar o dimensionamento da profundidade de contagem com uma transformação log1p. Irá aprender a tornar células com diferentes profundidades de sequenciação diretamente comparáveis.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 3 de 16. Olhas para duas células no teu dataset. Uma parece expressar o dobro do RNA da outra. Mas não é uma diferença biológica — um droplet foi simplesmente sequenciado com o dobro da profundidade pela máquina. Se as comparares diretamente, toda a tua downstream analysis será distorcida por artefactos técnicos. A filtragem e a normalização são as ferramentas que resolvem esta disparidade.
Antes de poderes ajustar a profundidade de sequenciação, tens de remover o lixo. Os dados raw de single-cell estão cheios de células mortas, droplets vazios e ruído aleatório. Limpas isto ao longo de dois eixos distintos: as células e os genes. As pessoas às vezes confundem estes dois passos, mas eles fazem coisas completamente diferentes. Tratas das células primeiro usando a função filter cells. Dizes ao Scanpy para descartar qualquer célula que expresse menos do que um número mínimo de genes. Se um droplet contiver apenas duzentos genes detetados quando uma célula saudável deveria ter dois mil, esse droplet provavelmente está vazio ou contém uma célula danificada e a morrer. Descartas isso por completo.
A seguir, filtras os genes em todo o teu dataset. Usando a função filter genes, removes os genes que são expressos em muito poucas células. Se um gene específico for detetado em apenas uma ou duas células em dez mil, não fornece qualquer valor estatístico para agrupar ou classificar tipos de células mais tarde. É apenas ruído computacional. Descartas esse gene por completo.
Assim que as células de baixa qualidade e os genes não informativos forem removidos, ainda enfrentas o problema da profundidade de sequenciação. É aqui que normalizas os total counts. O objetivo é fazer o scale de cada célula para que todas pareçam ter o mesmo número total de read counts. Imagina um cenário em que a Célula A tem cinco mil total counts e a Célula B tem vinte mil. Escolhes um size factor comum, tipicamente dez mil. O Scanpy aplica um scaling factor a cada célula individualmente. Duplica os counts na Célula A e reduz para metade os counts na Célula B. Agora, ambas as células somam dez mil total counts. Quando olhas para um gene específico em ambas as células, estás a comparar a sua verdadeira expressão relativa, completamente independente da intensidade com que a máquina de sequenciação fez o sampling.
Igualar os totais é apenas metade da matemática. Os dados de expressão biológica são massivamente enviesados. Um punhado de genes terá números de counts enormes, enquanto a maioria terá muito poucos. Se passares estes dados enviesados para cálculos de variance ou algoritmos de dimensionality reduction mais tarde, esses poucos genes massivos vão dominar a matemática e abafar os sinais biológicos subtis. Corriges isto usando uma transformação log plus one. Chamas a função log one p no Scanpy, que aplica um logaritmo natural a todos os teus counts normalizados. A parte plus one da função é crítica porque a tua data matrix é maioritariamente zeros, representando genes que não são expressos numa determinada célula. O log de zero é indefinido, mas o log de zero plus one é zero. Este simples passo comprime os valores extremamente altos, mantendo os zeros exatamente onde estão, resultando numa distribuição muito mais equilibrada.
Aqui está o insight principal. A filtragem e a normalização não alteram a biologia subjacente da tua amostra. Elas eliminam os biases mecânicos do hardware de sequenciação para que a biologia real possa emergir. Obrigado por ouvirem, happy coding a todos!
4
Deteção de Doublets com o Scrublet
3m 27s
Mergulhamos na deteção de doublets, um passo crucial para detetar artefactos técnicos na sequenciação single-cell microfluídica. Detalhamos como o Scrublet simula doublets artificiais para sinalizar células suspeitas. Irá aprender a identificar e remover estas combinações artificiais do seu dataset.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 4 de 16. Às vezes, duas células completamente diferentes ficam presas na mesma gota microfluídica, criando uma assinatura transcriptómica Frankenstein que parece um estado biológico totalmente novo. Não é uma descoberta. É um erro, e se não o apanhares cedo, vai contaminar a tua análise. É exatamente esse o problema que a deteção de doublets com o Scrublet foi desenhada para resolver.
Quando corres uma experiência single-cell usando microfluídica de gotas, empurras uma suspensão celular através de um canal, com o objetivo de ter uma célula por gota. Estatisticamente, este processo não é perfeito. Ocasionalmente, duas células partilham uma única gota. Imagina um cenário onde um monócito e uma célula T ficam presos juntos. A máquina de sequenciação lê o RNA combinado deles como uma única entidade, gerando um perfil que mistura genes de ambos os tipos de células. Muitas vezes, as pessoas confundem estes perfis mistos com verdadeiros estados de transição biológica, como uma célula a meio da diferenciação. Temos de ser completamente claros. Os doublets são artefactos puramente técnicos. Eles não existem no tecido e têm de ser removidos.
No Scanpy, tratas disto usando a função scrublet no módulo de preprocessing. O Scrublet opera com uma premissa altamente eficaz para encontrar estas células falsas. Se queres detetar doublets, precisas de saber qual é o aspeto de um doublet no teu dataset específico. Como o algoritmo não sabe quais das tuas células observadas são erros, ele cria os seus próprios.
Primeiro, o Scrublet pega na expression matrix das tuas células observadas. A seguir, escolhe aleatoriamente pares destas células reais e soma computacionalmente os seus perfis de expressão génica. Estes perfis combinados são os teus doublets simulados. Agora, o Scrublet mapeia tanto as tuas células reais observadas como estes doublets recém-simulados no mesmo espaço de alta dimensionalidade. Ele constrói um classificador nearest-neighbor para analisar as relações entre eles.
Este é o ponto-chave. O Scrublet avalia a vizinhança imediata de cada célula real no teu dataset. Se uma célula observada estiver rodeada principalmente por doublets simulados, essa célula real parece matematicamente idêntica a uma mistura artificial. O Scrublet atribui-lhe um doublet score alto. Por outro lado, se uma célula observada estiver num cluster com outras células reais e muito poucos doublets simulados, recebe um score baixo. É altamente provável que seja uma single cell genuína.
A função não se limita a atribuir um score contínuo. Ela avalia a distribuição de todos os doublet scores no teu dataset para calcular automaticamente um cutoff threshold. Ela procura uma separação entre o grande pico de células normais e a cauda menor de doublets suspeitos. Com base neste threshold, o Scrublet marca cada célula no teu dataset com um valor boolean, marcando-a como true se for um doublet previsto, e false se for um singlet. Estes resultados são guardados diretamente no teu data object, permitindo-te filtrar as células falsas antes de passares para a downstream analysis.
A grande força do Scrublet é que ele não depende de bases de dados de referência externas para encontrar erros técnicos. Ele aprende os failure modes exatos da tua experiência específica combinando as próprias células que sequenciaste.
Por este episódio é tudo. Obrigado por ouvires, e continua a criar!
5
Seleção de Features e Genes Altamente Variáveis
3m 24s
Examinamos o conceito de seleção de features e por que razão é necessário identificar genes altamente variáveis. Ao descartar o ruído de genes de manutenção, focamos a análise nos impulsionadores biológicos. Irá aprender a utilizar o Scanpy para isolar os genes mais informativos para os passos seguintes.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 5 de 16. Dos cerca de 30.000 genes no genoma humano, a maioria está apenas a fazer a manutenção celular básica. Se tentares analisá-los todos de uma vez, o enorme volume de atividade basal vai abafar a biologia real que estás a procurar. Para encontrares o verdadeiro sinal, precisas de Feature Selection e Highly Variable Genes.
Primeiro, uma distinção rápida. Tu já usaste uma função básica de filtragem para descartar genes que mal são detetados em todo o teu dataset. Esse passo limpa o ruído técnico e as empty droplets. A seleção de highly variable genes faz algo completamente diferente. Assume que os genes restantes são reais, mas pergunta quais deles são realmente informativos.
Pensa nisto da seguinte forma. Vasculhar dezenas de milhares de genes para encontrar os que impulsionam as diferenças entre os tipos de células significa descartar os aborrecidos housekeeping genes basais. Um housekeeping gene está ativo em quase todas as células, mais ou menos ao mesmo nível. A sua expressão é estável, o que o torna inútil para distinguir uma célula T de uma célula B. Nós queremos genes que sejam muito expressos numas células e totalmente silenciosos noutras. Estes são os highly variable genes. Normalmente, tu queres reduzir o teu dataset para cerca de dois mil destes key drivers.
No Scanpy, tu tratas disto com a função highly variable genes. Mas não podes simplesmente classificar os genes pela raw variance. Em dados de sequenciação, a variance escala com a mean expression. Se um gene for muito expresso em todo o lado, a sua raw variance vai ser naturalmente alta, mesmo que não seja biologicamente interessante. O algoritmo tem de separar a variance da mean expression.
Faz isto dividindo os genes em bins com base nos seus níveis médios de expressão. Depois, calcula uma normalized dispersion dentro de cada bin. Isto diz-te o quanto um gene varia em comparação apenas com outros genes que são expressos a níveis basais semelhantes. O Scanpy oferece diferentes métodos estatísticos para fazer estas contas, chamados flavors.
O flavor tradicional do Seurat espera que os teus dados sejam log-normalized primeiro. Calcula a dispersion, divide os dados em bins e padroniza os valores. Existe também um flavor mais recente, o Seurat v3, que exige explicitamente raw count data, sem logaritmos, para modelar adequadamente a variance. Em alternativa, o flavor CellRanger usa uma abordagem ligeiramente diferente para calcular a normalized dispersion com base nas counts. O flavor que escolheres dita simplesmente a distribuição estatística específica usada para modelar essa relação entre a mean e a variance.
Quando corres esta função, ela não apaga o resto dos teus dados. Em vez disso, adiciona algumas colunas novas ao teu array de variable annotations. A mais importante é uma coluna boolean chamada simplesmente highly variable, que marca true para os dois mil genes de topo e false para os restantes. Passos futuros no teu pipeline vão procurar automaticamente por esta flag e usar apenas esses genes selecionados para downstream analysis.
Aqui está a ideia principal. Feature selection não é apenas um truque computacional para fazer o teu código correr mais rápido; é o processo deliberado de remover o white noise biológico para que as verdadeiras identidades celulares tenham espaço para emergir.
Obrigado por estares aí. Espero que tenhas aprendido algo novo.
6
Pontuação e Regressão do Ciclo Celular
3m 29s
Exploramos como lidar com fatores de confusão através da pontuação e regressão das fases do ciclo celular. Discutimos como calcular as pontuações S e G2M e utilizar a regressão para remover a sua influência. Irá aprender a evitar que a divisão celular ativa arruíne a topologia do seu clustering.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 6 de 16. O teu algoritmo de clustering acabou de dividir células T idênticas em dois grupos distintos. Elas são exatamente do mesmo cell type, mas o algoritmo separou-as simplesmente porque um grupo está a dividir-se ativamente enquanto o outro está em repouso. Para corrigir isto, usamos Cell-Cycle Scoring e Regression.
A heterogeneidade do ciclo celular é uma enorme fonte de variância em dados single-cell. Se não for controlada, os genes altamente expressos que impulsionam a mitose vão sobrepor-se às subtis assinaturas genéticas que definem os verdadeiros cell types. Acabas com clusters definidos por um estado temporário em vez de uma verdadeira identidade biológica. Para resolver isto, o Scanpy fornece uma função dedicada para fazer o score de genes com base no ciclo celular.
Passas a esta função o teu dataset single-cell juntamente com duas listas específicas de marker genes conhecidos. Uma lista contém genes que estão ativos durante a S-phase, a fase de síntese do ciclo celular. A outra lista contém genes ativos durante a G2M-phase, a fase da mitose. A função de scoring avalia cada célula individualmente e calcula duas métricas contínuas: um S-score e um G2M-score. Faz isto analisando a intensidade da expressão desses genes de fase específicos em comparação com o nível de background expression da célula. Com base nestes dois scores, a função também atribui uma label de fase categórica a cada célula na tua metadata, classificando-a como S, G2M ou G1 se nenhum dos scores for particularmente alto.
Agora que quantificaste este efeito, precisas de remover a sua influência do dataset. É aqui que usas a função regress out. Instruis o regress out a analisar as colunas de S-score e G2M-score que acabaram de ser adicionadas à tua metadata. O algoritmo constrói então um modelo linear para a expressão de cada gene em todas as células, usando esses dois cell cycle scores como variáveis preditoras. Calcula o residual, que é a quantidade exata de expressão genética que não pode ser explicada pela posição da célula no ciclo celular. Este valor residual torna-se o novo nível de expressão corrigido no teu dataset.
Aqui está o ponto-chave. As pessoas muitas vezes confundem regression com batch correction. São conceitos relacionados, mas são ferramentas fundamentalmente diferentes. Os métodos de batch correction são desenhados para alinhar grupos discretos e categóricos, como amostras recolhidas em dias diferentes ou sequenciadas em máquinas diferentes. O regress out é especificamente desenhado para variáveis de confusão contínuas. Usas isto para gradientes numéricos contínuos, como estes cell cycle scores, total counts por célula, ou a percentagem de genes mitocondriais. Modela uma inclinação matemática e achata-a.
Assim que corres este passo de regression, o forte viés biológico da divisão celular é matematicamente removido da expression matrix. Quando voltares a correr o teu algoritmo de clustering nestes dados corrigidos, essas células T em divisão e células T em repouso vão juntar-se novamente num único cluster coeso. O algoritmo já não é distraído pelo ruído da replicação de DNA. Fazer o regress out dos cell cycle scores garante que a tua downstream analysis agrupa as células estritamente pelo que elas são, em vez do que elas por acaso estavam a fazer no momento em que foram sequenciadas.
É tudo por este episódio. Obrigado por ouvirem, e continuem a construir!
7
Redução de Dimensionalidade com PCA
3m 42s
Este episódio explica a Análise de Componentes Principais (PCA) no contexto de dados single-cell. Discutimos como o PCA reduz o ruído do dataset e por que razão a seleção do número certo de componentes é importante. Irá aprender a reduzir milhares de genes para uma base gerível destinada a algoritmos avançados.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 7 de 16. A mente humana não consegue visualizar duas mil dimensões. Pior ainda, algoritmos de clustering complexos ficam computacionalmente paralisados por elas, atolados numa mistura de sinal biológico real e ruído técnico aleatório. Precisas de uma forma de extrair a estrutura central dos teus dados antes de os analisares. A redução de dimensionalidade com Principal Component Analysis é como resolves isto.
Antes de entrarmos na mecânica da coisa, precisamos de esclarecer um mal-entendido comum. As pessoas muitas vezes pensam que o PCA é apenas um scatter plot a mostrar o PC1 contra o PC2, pensado como uma visualização final para os olhos humanos. Não é. Embora possas fazer o plot dos dois primeiros components, o PCA é fundamentalmente uma base matemática. Ele comprime uma matriz esparsa e com ruído num formato denso para alimentar ferramentas downstream, como neighbor graphs.
Pensa no teu ponto de partida. Acabaste de isolar cerca de dois mil genes altamente variáveis. Cada gene representa uma dimensão independente no teu dataset. Corres a função scanpy tools pca para calcular os principal components. Esta função avalia todo o teu dataset e esmaga essas duas mil dimensões de genes num conjunto muito menor de dimensões sintéticas, tipicamente à volta de cinquenta.
Estas dimensões sintéticas são ordenadas pela quantidade de variância que explicam. O primeiro principal component representa o eixo de variação absolutamente mais forte nas tuas células. O segundo representa o próximo mais forte, e por aí em diante. Aqui está o ponto-chave. O primeiro punhado de components captura as diferenças biológicas reais e estruturadas. À medida que desces na lista de components, eles capturam progressivamente menos biologia e mais ruído técnico aleatório. Ao cortares a parte final destes components, estás essencialmente a fazer denoising da tua matriz de dados.
Para avaliar esta redução, precisas de decidir quantos components reter. Usas a função scanpy plot pca variance ratio. Este comando gera um line chart a mostrar a fração da variância total explicada por cada component individual. Tu examinas esta linha à procura do elbow point, que é onde a queda acentuada de repente achata para uma long tail.
Se a curva achatar no component quinze, podes assumir que só precisas de quinze components. No entanto, em workflows de single-cell, nós sobrestimamos deliberadamente o número de principal components. Podes ver o elbow no quinze, mas dizes às tuas funções downstream para usarem cinquenta na mesma. Os algoritmos de clustering downstream são altamente robustos. Eles conseguem facilmente ignorar o ligeiro ruído técnico contido nos components dezasseis a cinquenta. O que eles não conseguem fazer é recuperar o sinal biológico que deitaste fora cedo demais. Se o component vinte e dois contiver a assinatura de variância para um tipo de célula muito raro, descartá-lo significa que esse tipo de célula desaparece completamente da tua análise.
Calculas os components, verificas a variance ratio para confirmar a estrutura dos dados, e segues em frente. A principal conclusão é que o PCA não é uma imagem para se olhar, mas sim um filtro matemático direcionado que sacrifica a profundidade dimensional bruta para remover o ruído e expor os verdadeiros eixos biológicos dos teus dados.
Espero que tenha sido útil. Obrigado por ouvires, e aproveita o resto do teu dia.
8
O Grafo de Vizinhos Mais Próximos e o UMAP
3m 30s
Desconstruímos o núcleo absoluto da topologia single-cell moderna: o grafo de vizinhos mais próximos. De seguida, explicamos como o UMAP traduz esta teia complexa num gráfico 2D legível. Irá aprender por que razão o grafo de vizinhos é o pré-requisito para quase todas as ferramentas avançadas no Scanpy.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 8 de 16. O segredo da análise single-cell moderna não é apenas fazer o plot de pontos numa grelha. É perceber exatamente quais as células que são vizinhas num espaço massivo e de alta dimensionalidade. Se interpretares mal essa estrutura subjacente, todas as visualizações que se seguem vão induzir-te em erro. O mecanismo para capturar essa estrutura é o nearest neighbor graph, e hoje vamos ver como o construir e projetar usando UMAP.
Nesta fase de uma pipeline típica, já correste a Principal Component Analysis. Condensaste milhares de genes em talvez quarenta ou cinquenta principal components. Mas cinquenta dimensões continuam a ser impossíveis de visualizar, e não nos dizem explicitamente quais as células que pertencem à mesma comunidade local. Precisamos de construir uma rede de ligações. No Scanpy, fazes isso usando a função sc dot pp dot neighbors. Este passo calcula o neighborhood graph das tuas células.
Calcular distâncias entre dezenas de milhares de células ao longo de trinta mil genes raw é computacionalmente brutal e altamente suscetível a ruído. Ao calcular os vizinhos com base nos principal components, a matemática é rápida e o ruído técnico já foi eliminado. Para cada célula individual, o algoritmo olha para as suas coordenadas nesses principal components e encontra os seus pares mais próximos. Por default, liga uma célula aos seus quinze nearest neighbors. O output é uma rede matemática onde as células são nodes, e as edges entre elas representam alta similaridade. Este neighborhood graph torna-se a data structure fundamental para downstream tasks.
Assim que tiveres esta rede, vais querer olhar para ela. É aqui que entra o UMAP, chamado através de sc dot tl dot umap. Aqui está o insight principal. Um equívoco muito comum é achar que o UMAP calcula distâncias diretamente a partir dos teus dados raw de expressão génica. Não o faz. O UMAP é completamente cego aos teus genes. É simplesmente um layout engine. O seu único trabalho é pegar nesse nearest neighbor graph pré-calculado e achatá-lo num espaço bidimensional.
O UMAP funciona ao otimizar um layout para corresponder ao graph. Puxa os vizinhos ligados para perto uns dos outros, enquanto afasta as células desligadas. Como depende inteiramente das ligações locais definidas no passo anterior, é excecionalmente bom a preservar a estrutura local. Se um grupo de células estava fortemente ligado no graph de alta dimensão, vai formar uma ilha distinta e compacta no teu plot UMAP 2D. Mas tem em atenção que o espaço vazio entre as ilhas separadas num plot UMAP significa muito pouco. O UMAP sacrifica a precisão espacial global para garantir que os vizinhos locais se mantêm colados.
Esta separation of concerns é vital. A forma que vês num plot UMAP é completamente ditada pelo neighbor graph construído logo antes. Se quiseres alterar a sensibilidade do teu layout a tipos de células raros, não afinas o UMAP. Voltas atrás e ajustas o número de vizinhos na própria construção do graph.
Se achaste estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
9
Clustering com o Leiden
4m 00s
Exploramos como encontrar populações discretas de células utilizando o algoritmo de clustering Leiden. Ao otimizar a modularidade no grafo de vizinhança, o Leiden isola comunidades altamente conectadas. Irá aprender a ajustar o parâmetro de resolução para encontrar grupos estáveis e biologicamente significativos.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 9 de 16. Os algoritmos de clustering tradicionais assumem que os teus dados existem em blobs perfeitamente redondos, organizados à volta de um ponto central. Mas os dados biológicos reais são confusos, interligados e formam estruturas contínuas e complexas. Quando tentas forçar essas estruturas complexas em esferas simples, acabas por dividir single cell types em fragmentos artificiais. Fazer clustering com Leiden resolve isto olhando para a forma como as células se ligam umas às outras, em vez de apenas onde se encontram num espaço abstrato.
As pessoas costumam pensar por default em clustering como o K-means, onde defines um ponto central e agrupas tudo o que está por perto usando distâncias físicas standard. O Leiden não funciona assim. É um algoritmo de clustering graph-based. Ignora completamente as distâncias euclidianas até um centroid. Em vez disso, baseia-se inteiramente na densidade de edges no neighbor graph que construíste anteriormente na tua análise.
Pensa no neighbor graph como uma enorme rede social. As células são indivíduos, e as edges entre eles são amizades. O Leiden faz o que é conhecido como community detection. Procura grupos de células que têm um número muito alto de ligações dentro do seu grupo específico, mas muito poucas ligações para a rede exterior.
Para conseguir isto, o algoritmo otimiza uma métrica chamada modularity. A modularity mede a densidade de links dentro das comunidades em comparação com os links que esperarias se a rede fosse totalmente aleatória. O algoritmo começa por atribuir cada single cell à sua própria comunidade individual. Depois, faz o merge iterativo destas comunidades, movendo nodes para a frente e para trás, verificando constantemente se o novo agrupamento aumenta o score geral de modularity. O Leiden foi desenhado especificamente para refinar estas partições com cuidado, garantindo que as comunidades finais estão densamente ligadas internamente e não sofrem de fragmentos desligados, o que era um problema conhecido no algoritmo Louvain mais antigo.
No Scanpy, corres isto usando a tool function Leiden. Passas-lhe o teu main data object, e ele opera diretamente no neighbor graph existente. O output é uma nova coluna categórica adicionada aos teus dados, contendo um número de cluster para cada single cell.
Aqui está o insight principal. O controlo mais importante que tens sobre todo este processo é o resolution parameter. Este parâmetro funciona como um dial que dita a agressividade com que o algoritmo divide os grupos. Por default, o Scanpy usa uma resolution de um. Se aumentares o valor da resolution, obténs mais clusters. O algoritmo torna-se altamente sensível, dividindo o graph em subpopulações mais pequenas e altamente específicas. Se diminuíres o valor da resolution, obténs menos clusters. O algoritmo torna-se mais tolerante, agrupando porções maiores do graph.
Supõe que corres o Leiden e olhas para o mapa resultante. Podes notar que um único tipo de célula biológica conhecido foi dividido em cinco subpopulações minúsculas e demasiado fragmentadas. O algoritmo encontrou pequenas diferenças, mas, biologicamente, esses cinco grupos pertencem ao mesmo cell state distinto. Para corrigir isto, basta correres a function Leiden novamente, mas desta vez passas explicitamente um número mais baixo para o resolution argument. Ao baixares a resolution, instruis o algoritmo a relaxar os seus critérios. Esses cinco pequenos fragmentos vão fazer merge novamente num cluster sólido e biologicamente significativo.
A resolution exata de que precisas nunca é uma verdade matemática fixa; é um dial ajustável que rodas até que as comunidades estatísticas no graph reflitam com precisão as realidades biológicas do teu tecido.
Obrigado por estares aí. Espero que tenhas aprendido algo novo.
10
Descoberta de Genes Marcadores
4m 20s
Mergulhamos na descoberta de genes marcadores e em testes de expressão diferencial. Explicamos como os testes estatísticos identificam as assinaturas transcriptómicas únicas dos seus clusters. Irá aprender a transitar de clusters numerados anónimos para tipos de células biológicas rotulados com confiança.
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 10 de 16. Isolaste um cluster coeso e distinto de células no teu dataset, mas como sabes se é uma célula T, uma célula B ou um estado totalmente desconhecido? A matemática agrupou-as, mas a biologia tem de te dizer o que elas são. Esse passo de tradução depende inteiramente da descoberta de genes marcadores.
Antes de olharmos para as ferramentas, precisamos de traçar uma linha clara entre clustering e anotação. Os algoritmos de clustering simplesmente agrupam células com base na semelhança estatística em milhares de dimensões e atribuem-lhes uma label arbitrária, como Cluster 0 ou Cluster 1. Esse número não significa nada biologicamente. A descoberta de genes marcadores é o processo de encontrar os genes específicos que impulsionam esse agrupamento estatístico, permitindo-te atribuir nomes biológicos reais a esses clusters.
No Scanpy, encontras estes genes impulsionadores usando uma função chamada rank genes groups. Esta função faz a análise de expressão diferencial. Ela recebe um agrupamento categórico, geralmente os teus clusters calculados, e compara a expressão génica das células dentro de um cluster com as células de todos os outros clusters combinados. O objetivo é encontrar genes que sejam altamente expressos no teu cluster alvo, mas que estejam praticamente silenciosos em todo o lado. Por default, ela compara cada cluster com a união do resto das células, mas também a podes configurar para comparar um cluster com um grupo de referência específico, se estiveres à procura de diferenças subtis entre dois tipos de células altamente relacionados.
Para decidir se um gene é realmente um marcador, o Scanpy corre um teste estatístico para pontuar a diferença na expressão. Podes escolher um t-test standard, mas o Wilcoxon rank-sum test é altamente recomendado e é a escolha standard para dados single-cell. A expressão génica single-cell não segue uma curva de sino normal; é altamente variável, fortemente assimétrica e cheia de valores zero onde um gene simplesmente não foi detetado. O teste de Wilcoxon não assume uma distribuição normal. Em vez de olhar para os valores médios raw, ele faz o rank dos valores de expressão em todas as células e compara os ranks entre o teu cluster alvo e o resto do dataset. Isto torna-o muito mais robusto contra outliers extremos.
Vamos olhar para um cenário específico. Tens um dataset com vários clusters e queres interrogar o Cluster 3. Chamas a função rank genes groups, dizes-lhe para usar as tuas labels de cluster existentes e defines o método para Wilcoxon. O Scanpy processa os números e faz o rank de cada gene com base no quão exclusivamente ele define o Cluster 3. Depois, inspecionas os resultados de topo. Vês que os genes com o rank mais alto são o CD8A e o GZMK. Se perceberes de imunologia, reconheces imediatamente que estes são marcadores clássicos para células T citotóxicas. Como estes genes específicos estão unicamente upregulated aqui em comparação com o resto do dataset, podes rotular com confiança o Cluster 3 como uma célula T CD8 positiva.
O output desta função é guardado silenciosamente no teu objeto AnnData sob o atributo uns. O Scanpy guarda arrays de nomes de genes, scores estatísticos, p-values e log-fold changes para cada cluster simultaneamente. Podes extrair estes arrays para construir dataframes, guardá-los num ficheiro csv ou passá-los diretamente para ferramentas de anotação downstream.
Aqui está o insight principal. A expressão diferencial transforma formas matemáticas arbitrárias em identidades biológicas acionáveis. Sem genes marcadores, tens apenas um mapa de números; com eles, tens um sistema biológico mapeado.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
11
Integração de Dados com o Ingest
3m 53s
Este episódio aborda a integração de dados utilizando a ferramenta Ingest. Explicamos como projetar novos datasets no espaço PCA e UMAP de um atlas de referência pré-anotado. Irá aprender um método rápido e invariante para mapear rótulos entre diferentes experiências.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Análise Single-Cell com Scanpy, episódio 11 de 16. Tens um dataset de referência perfeitamente anotado e uma nova amostra de paciente que precisas de analisar. Normalmente, combiná-los significa correr uma batch correction, recalcular os teus principal components e esperar que um UMAP conjunto massivo faça o render do zero. A integração de dados com o Ingest oferece uma alternativa mais rápida e não destrutiva.
As pessoas costumam confundir o ingest com a batch correction standard. As ferramentas tradicionais de batch correction pegam em múltiplos datasets e calculam um modelo conjunto completamente novo. Elas alteram a representação subjacente dos teus dados de referência para forçar um alinhamento. O Ingest faz o oposto. É uma projeção assimétrica. O teu dataset de referência atua como a ground truth absoluta. O modelo espacial fica bloqueado, e os novos dados são simplesmente passados por ele sem alterar o modelo original de todo.
Pega num atlas de referência de Peripheral Blood Mononuclear Cells perfeitamente anotado. Cada cluster está verificado e tem uma label. Acabaste de receber uma amostra de paciente sem anotações e desorganizada. Queres aplicar essas labels do atlas à tua nova amostra, e queres fazer o plot das novas células exatamente no mesmo espaço de coordenadas da referência.
Para que isto funcione, as variáveis nos teus dois datasets têm de estar alinhadas. Isto significa que ambos os datasets precisam de partilhar exatamente os mesmos genes. Na prática, filtras o teu novo query dataset para que os seus genes correspondam aos highly variable genes já identificados no teu atlas de referência.
O teu dataset de referência tem de estar totalmente processado antes de começares. Precisa de uma Principal Component Analysis existente, de um neighborhood graph calculado e de uma representação UMAP. Também contém as labels categóricas que queres transferir, guardadas nos seus observation metadata.
A execução é um único comando. Chamas a função ingest, passando-lhe o teu novo query dataset, o teu dataset de referência anotado e a observation column específica que queres mapear, como a label do tipo de célula.
Aqui está o insight principal. Quando chamas a função, o ingest pega nos perfis de expressão das tuas novas células e projeta-os matematicamente no principal component space existente do atlas de referência. Ignora completamente o cálculo de uma nova Principal Component Analysis global.
Assim que as query cells aterram nesse layout espacial partilhado, o algoritmo procura os nearest neighbors. Mapeia as query cells diretamente no neighbor graph pré-existente do dataset de referência. O trabalho computacional pesado de construir um graph já foi feito pelo modelo de referência.
Como as novas células agora têm neighbors estabelecidos nos dados de referência, ocorrem duas transferências finais. Primeiro, as coordenadas UMAP dos reference neighbors são atribuídas às novas células. Segundo, as labels de metadata, como os teus tipos de células, são copiadas com base em majority voting desses reference neighbors mais próximos.
O resultado é um query dataset com o exato layout UMAP e anotações de tipo de célula do teu atlas. Podes sobrepor a amostra do paciente, anteriormente sem anotações, diretamente em cima da tua visualização de referência, e as populações biológicas correspondentes vão encaixar perfeitamente nos clusters visuais estabelecidos.
Ao projetar novas células num modelo existente, o ingest muda o teu workflow de reconstruir constantemente espaços globais frágeis, para construir um atlas de referência robusto e fazer fluir perfeitamente todas as futuras experiências através dele.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
12
Visualização de Padrões de Expressão
3m 33s
Exploramos técnicas avançadas de visualização para avaliar a expressão génica entre clusters. Focamo-nos em dot plots e matrix plots, detalhando como estes codificam tanto a intensidade de expressão como a esparsidade. Irá aprender a validar visualmente as suas anotações de tipos de células num piscar de olhos.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 12 de 16. Um feature plot standard é ótimo para mostrar onde um gene específico está ativo, mas falha completamente quando precisas de comparar vinte genes diferentes em dez clusters distintos em simultâneo. Para resolver isso, vamos olhar para a Visualização de Padrões de Expressão. Ao verificar marker genes, o instinto natural é muitas vezes recorrer a um heatmap. Alinhas todas as tuas células, alinhas os teus genes e procuras blocos de cor. Mas os dados de sequenciação de RNA single-cell são notoriamente esparsos. A maioria das células tem contagens a zero para a maioria dos genes. Num heatmap single-cell standard, esta esparsidade cria ruído visual. Acabas a olhar para um mar de cor de fundo, a tentar adivinhar se um gene é realmente um marker específico para um cluster ou se simplesmente sofreu um dropout aleatório em todo o lado. É aqui que entra o dot plot. Em vez de fazer o plot de células individuais, um dot plot agrega-as. Colocas os teus grupos de células, como os teus clusters Leiden, num eixo, e os teus genes de interesse no outro. Em cada interseção, obténs um círculo. Aqui está a ideia principal. Um dot plot codifica duas informações completamente diferentes nesse único círculo. Primeiro, a cor do ponto representa o nível médio de expressão do gene nessas células. Cores mais escuras ou intensas significam maior expressão. Segundo, o tamanho do ponto representa a fração de células naquele cluster que realmente expressam o gene. Um ponto grande significa que quase todas as células do cluster têm pelo menos algum RNA para esse gene. Um ponto minúsculo significa que apenas algumas células o expressam. Esta dupla codificação é incrivelmente poderosa para dados esparsos. Separa a quantidade de um gene que está presente da sua amplitude de distribuição. Digamos que estás a analisar quinze marker genes candidatos em cinco clusters Leiden. Passas os teus dados, a tua lista de genes e as tuas labels de cluster para a função dot plot. Consegues ver instantaneamente se os teus markers de monócitos esperados são simultaneamente altamente expressos e amplamente expressos no Cluster um, estando totalmente ausentes nos outros quatro clusters. Não precisas de forçar a vista a olhar para linhas de células individuais. Os pontos grandes e escuros na linha do Cluster um dão-te validação imediata. Às vezes, não precisas da informação de frequência dada pelo tamanho do ponto. Só queres uma grid limpa a mostrar a expressão média. Para isso, o Scanpy oferece a função matrix plot. Pensa num matrix plot como um heatmap agrupado. Continua a agregar as tuas células por cluster, mas preenche todo o quadrado da grid com cor a representar o valor médio de expressão. Não há variação no tamanho dos pontos. É uma forma mais rápida e densa de verificar padrões amplos de expressão quando tens uma lista enorme de genes e a fração de células que os expressam te importa menos. Ambas as ferramentas recebem o teu data object, uma lista dos teus genes-alvo e a categoria de metadados pela qual queres agrupar. Executam rapidamente e escalam perfeitamente para dezenas de genes. Ao lidar com a esparsidade single-cell, separar a intensidade da expressão da frequência da expressão é a forma mais fiável de confirmar se um marker gene realmente define um cluster. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
13
Exploração de Manifolds com Diffusion Maps
3m 57s
Introduzimos os Diffusion Maps, uma poderosa técnica de embedding para dados biológicos contínuos. Contrastamo-la com o UMAP, explicando por que razão a difusão é mais adequada para analisar a diferenciação celular. Irá aprender a visualizar transições contínuas e processos de desenvolvimento.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 13 de 16. O UMAP é fantástico para separar tipos celulares distintos, mas pode fragmentar violentamente processos biológicos contínuos. Quando estás a estudar o desenvolvimento celular, não queres ilhas isoladas de células; precisas de ver o continuum suave de mudanças de estado. Explorar manifolds com Diffusion Maps resolve exatamente este problema.
No Scanpy, calculas isto usando a tool diffmap. Os utilizadores frequentemente optam pelo UMAP por defeito para toda a redução de dimensionalidade. Tens de perceber que o UMAP é uma técnica de embedding otimizada para encontrar clusters distintos e preservar vizinhanças locais. Os Diffusion Maps são fundamentalmente diferentes. Eles preservam a probabilidade matemática contínua de transição entre estados. Isto torna-os na escolha ideal para analisar processos contínuos como a diferenciação celular.
O algoritmo diffmap trata o teu manifold de dados como uma rede contínua. Baseia-se inteiramente no nearest neighbor graph das tuas células. Assim que esse grafo é estabelecido, o algoritmo simula um random walk através das ligações. Pensa nisto como a modelação de um processo de difusão, semelhante à forma como o calor se propaga num material físico. O algoritmo avalia a facilidade com que um sinal se pode propagar pelas regiões densas dos teus dados. Calcula a probabilidade de transição de um estado celular para outro ao longo de um número específico de steps. Células que partilham uma alta probabilidade de transição são posicionadas mais próximas umas das outras no espaço final de menor dimensionalidade.
Considera acompanhar a diferenciação de uma célula estaminal hematopoiética num eritrócito. Se projetares estes dados usando um embedding que favorece a separação discreta, as células progenitoras intermédias são frequentemente forçadas a formar clusters artificiais e separados. A matemática subjacente fratura a linha do tempo biológica. Se, em vez disso, correres o diffmap, o algoritmo calcula as probabilidades de transição ao longo de todo o caminho de desenvolvimento. O resultado é uma trajetória suave e contínua. A célula estaminal fica numa extremidade e o eritrócito maduro na outra. Cada estado intermédio é plotado ao longo de um caminho ligado, baseado estritamente na probabilidade de transição de estado. Não estás a olhar para snapshots isolados de tipos celulares distintos. Estás a observar um evento biológico fluido.
Aplicar isto no Scanpy segue uma sequência rígida. Primeiro, tens de calcular o neighborhood graph no teu objeto. O diffusion map não pode correr sem essas ligações de vizinhos pré-calculadas. Em seguida, chamas a tool diffmap e passas-lhe o teu objeto AnnData. Podes opcionalmente especificar o número de componentes que queres calcular, o que define as dimensões do output. O Scanpy calcula o diffusion map e armazena as novas coordenadas no atributo de observação multidimensional do teu objeto, sob a key X diffmap.
A tool também armazena os eigenvalues no atributo de dados não estruturados. Estes valores dizem-te quanta variância cada componente de difusão captura. Uma queda acentuada nestes eigenvalues indica que capturaste as transições biológicas mais importantes, e que os componentes subsequentes são provavelmente ruído. Num dataset de diferenciação típico, o primeiro componente de difusão não trivial alinha-se diretamente com o eixo temporal primário do desenvolvimento.
Aqui está o insight principal. Num diffusion map, a distância física entre duas células no plot não é apenas uma medida genérica de similaridade transcriptómica. Essa distância representa explicitamente a probabilidade matemática de ocorrer uma transição biológica entre esses dois estados específicos.
É tudo por agora. Até à próxima!
14
Grafos Abstraídos com o PAGA
3m 32s
Este episódio aborda a Partition-based Graph Abstraction, ou PAGA. Discutimos como medir a conectividade real entre clusters para preservar a topologia global. Irá aprender a utilizar o PAGA para descobrir as verdadeiras relações de linhagem ocultas nos seus dados.
Olá, daqui é o Alex da DEV STORIES DOT EU. Análise Single-Cell com Scanpy, episódio 14 de 16. O simples facto de dois clusters de células estarem lado a lado num plot UMAP não significa que estejam biologicamente relacionados. A proximidade visual em duas dimensões é frequentemente uma ilusão matemática e, se te baseares nela para traçar trajetórias de desenvolvimento, podes ligar pontos que, na realidade, não se tocam num espaço de alta dimensionalidade. Para mapear a conectividade real, com suporte estatístico, precisas de Abstracted Graphs com PAGA.
PAGA significa Partition-based Graph Abstraction. Precisamos de esclarecer imediatamente um equívoco comum. O PAGA não é um embedding de redução de dimensionalidade como o t-SNE ou o UMAP. Não calcula as coordenadas de células individuais para desenhar um scatter plot. Em vez disso, o PAGA cria um grafo simplificado e coarse-grained. Os nós neste grafo são clusters inteiros, ou partições, de células. As arestas que ligam estes nós representam a confiança estatística de que esses clusters partilham uma fronteira contínua.
Quando chamas a função PAGA nos teus dados anotados, apontas para um conjunto específico de labels de grupo, geralmente os teus clusters Leiden ou Louvain. O algoritmo avalia então as fronteiras entre estes grupos, analisando o neighborhood graph single-cell subjacente. Observa as células individuais no cluster A e conta quantos dos seus vizinhos diretos pertencem ao cluster B. Ao contabilizar todas estas ligações cross-cluster e compará-las com um modelo aleatório, o PAGA gera uma matriz de conectividade quantificável. Um valor alto significa que os clusters estão profundamente interligados, sugerindo uma transição biológica. Um valor baixo significa que são ilhas separadas.
Considera um cenário concreto. Estás a seguir o desenvolvimento de células imunitárias e precisas de provar que um cluster progenitor específico dá origem diretamente a um cluster de células T efetoras. Num plot visual standard, o algoritmo de layout pode colocar um cluster totalmente não relacionado bem no meio deles, fazendo com que a sua relação pareça indireta. Ao examinar a matriz de conectividade do PAGA, evitas esta distorção visual. Olhas diretamente para o peso matemático da aresta entre os teus grupos de progenitores e efetores. O PAGA permite-te definir um threshold mínimo de conectividade. Ao aplicares este threshold, filtras ligações espúrias e de baixa confiança. Se a aresta forte entre os teus dois clusters alvo sobreviver ao corte, terás estabelecido uma ligação estatisticamente robusta.
Esta é a parte que importa. O PAGA não fica apenas ao lado dos teus embeddings; pode corrigi-los. Como o PAGA preserva a topologia global de forma tão fiável, podes usar o grafo abstrato para inicializar um embedding UMAP. Em vez de deixares o UMAP começar a partir de um layout espacial aleatório, dizes-lhe para posicionar as células individuais com base no grafo PAGA coarse-grained. Isto ancora a tua visualização bidimensional final à verdadeira realidade de alta dimensionalidade, garantindo que estados biológicos distantes não sejam artificialmente comprimidos.
As visualizações irão sempre distorcer dados complexos para que caibam num ecrã plano, mas a abstração de um neighborhood graph depende inteiramente da proximidade matemática. Confia no grafo em vez da imagem.
É tudo por este episódio. Obrigado por ouvires, e continua a criar!
15
Inferência de Trajetórias com DPT
3m 46s
Exploramos a inferência de trajetórias utilizando o Diffusion Pseudotime (DPT). Explicamos como designar uma célula raiz e calcular distâncias geodésicas através do grafo celular. Irá aprender a organizar as células ao longo de uma linha temporal de desenvolvimento contínua.
Olá, daqui fala o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 15 de 16. A sequenciação single-cell destrói a própria célula que estás a tentar estudar. Obténs um snapshot estático da sua expressão génica, o que significa que não podes gravar um vídeo de uma célula estaminal a diferenciar-se num estado maduro. Para veres esse percurso de desenvolvimento, tens de inferir uma timeline matematicamente, calculando as distâncias transcriptómicas. É exatamente isso que fazemos usando Trajectory Inference com DPT.
DPT significa Diffusion Pseudotime. Antes de olharmos para como o algoritmo opera, precisamos de esclarecer o que esse nome realmente significa. Pseudotime não é tempo cronológico real. Não mede horas, dias, ou a idade biológica de uma célula. É estritamente uma métrica de distância transcriptómica. Mede quantas alterações incrementais de expressão uma célula sofreu em relação a um ponto de partida específico.
Para correres isto no Scanpy, usas a função chamada sc dot tl dot dpt. Esta função opera no neighborhood graph existente do teu dataset, que liga as células com base na sua similaridade. No entanto, um graph por si só não tem uma direção inerente. Para lhe dares direção, tens de definir um ponto de partida. Fazes isto ao definir uma root cell.
Considera um cenário em que estás a estudar o desenvolvimento do sangue. Examinas os teus clusters e identificas as células estaminais hematopoiéticas naive. Escolhes um cell index específico desse grupo e defines-o como a root na estrutura do teu dataset. Isto serve de ponto de origem, ou tempo zero, para todo o cálculo.
Assim que a root estiver estabelecida, corres a função DPT. Aqui está o insight principal. O algoritmo não mede uma distância reta e linear entre a root e outra célula. O desenvolvimento biológico não é uma linha reta; segue caminhos complexos e ramificados. Para captar isto, o DPT calcula distâncias geodésicas ao longo do teu neighborhood graph. Ele avalia a estrutura dos dados ao simular random walks a partir da root. Ele avança de célula em célula através das edges densas do graph, encontrando os caminhos mais prováveis de mudança transcriptómica.
O resultado deste cálculo é um novo array de valores adicionado às tuas anotações de células. Cada célula no teu dataset recebe um score de pseudotime. A root cell fica a zero. À medida que a distância geodésica da root aumenta, o score sobe. No nosso cenário de desenvolvimento do sangue, uma célula progenitora intermédia pode receber um score de zero ponto quatro, enquanto uma célula totalmente madura na extremidade terminal de um branch recebe um score perto de um.
Mapeaste efetivamente um cluster estático de pontos numa ordenação de desenvolvimento contínua, ordenando-os do menos para o mais diferenciado. Agora podes usar este eixo numérico para seguir a dinâmica de genes individuais, fazendo o plot do momento exato em que um fator de transcrição específico se ativa ao longo do caminho de desenvolvimento.
A fiabilidade da tua trajectory inference depende inteiramente do teu ponto de partida, o que significa que uma root escolhida incorretamente resultará numa timeline perfeitamente calculada, mas biologicamente sem sentido.
Se achas estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
16
Aumento de Escala Experimental com o Dask
3m 34s
No nosso último episódio, olhamos para a fronteira experimental do Scanpy: o aumento de escala com o Dask. Explicamos como lidar com datasets que excedem a RAM da sua máquina utilizando lazy evaluation e processamento out-of-core. Obrigado por se juntar a nós neste mergulho profundo no Scanpy!
Olá, daqui é o Alex da DEV STORIES DOT EU. Scanpy Single-Cell Analysis, episódio 16 de 16. O que acontece quando o teu dataset single-cell atinge cinco milhões de células e esgota completamente a memória do teu computador? Não o consegues filtrar, não o consegues normalizar, e o teu kernel simplesmente crasha. A solução para este limite rígido de memória é o scale-up experimental com Dask.
As pessoas costumam ouvir falar do Dask e pensam imediatamente em processamento paralelo num cluster distribuído para acelerar o código. Embora o Dask consiga fazer isso, o seu principal superpoder no Scanpy neste momento é a gestão de memória out-of-core através de lazy evaluation. Não se trata apenas de fazer as coisas mais depressa. Trata-se de fazer coisas que antes eram impossíveis numa única máquina.
Os workflows standard do Scanpy dependem de arrays in-memory. Isto exige que todo o dataset resida na tua RAM ativa. Quando usas o backend Dask, o Scanpy substitui estes arrays standard dentro do teu objeto AnnData por arrays Dask. Um array Dask é essencialmente uma coleção de muitos arrays mais pequenos, chamados chunks. Em vez de carregar a matriz inteira para a memória de uma só vez, o Dask deixa a maior parte dos dados em segurança no disco.
Quando corres uma função de preprocessing do Scanpy suportada pelo Dask, ele não calcula o resultado imediatamente. É aqui que entra a lazy evaluation. Em vez de processar números, o Dask constrói uma receita. Ele cria um task graph que descreve exatamente que operações matemáticas precisam de ser realizadas em cada chunk individual de dados.
Considera um cenário em que tens um dataset massivo de dois milhões de células no disco, e precisas de calcular métricas de quality control. Se tentares isto com um array standard, o teu sistema vai bloquear enquanto tenta puxar tudo para a RAM. Mas se o teu objeto AnnData contiver um array Dask, simplesmente chamas a função standard de quality control do Scanpy. A função retorna quase instantaneamente. A tua memória não dispara porque nenhum número foi efetivamente processado ainda. O Scanpy apenas registou a tua intenção.
Quando estiveres finalmente pronto para fazer o plot dessas métricas ou guardar as summary statistics, dizes explicitamente ao Dask para computar o resultado. Esta é a parte que importa. Neste exato momento, o Dask puxa o primeiro chunk de dados do teu disco rígido, calcula as métricas apenas para esse chunk, guarda o pequeno resultado e, de seguida, descarta imediatamente o chunk de dados brutos da memória. Depois, passa para o chunk seguinte. A tua memory footprint ativa permanece minúscula. É ditada inteiramente pelo tamanho de um único chunk, e não pelos milhões de células no dataset completo.
Neste momento, este backend do Dask no Scanpy está categorizado como experimental. Nem todas as funções no ecossistema o suportam ainda. No entanto, passos core de preprocessing, como normalization, scaling e highly variable gene selection, estão totalmente equipados para lidar com operações massivas out-of-core.
Quando mudas de eager processing in-memory para lazy processing no disco, o tamanho do teu dataset já não é limitado pela RAM do teu hardware, mas apenas pela tua paciência.
Isto leva-nos ao fim da nossa série sobre single-cell. Recomendo vivamente que explores a documentação oficial do Scanpy e tentes construir estes data graphs de forma hands-on. Se tiveres ideias sobre que tecnologias devemos abordar na nossa próxima série, visita devstories dot eu e diz-nos. Obrigado por ouvirem, happy coding a todos!
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Este site não utiliza cookies. O nosso fornecedor de alojamento pode registar o seu endereço de IP para efeitos analíticos. Saber mais.