Определение кластеров из матрицы с использованием порогового значения и именования по размеру кластера в Python - PullRequest
0 голосов
/ 01 мая 2020

У меня есть матрица попарных различий между выборками. Я хотел бы обозначить каждый образец как часть кластера, названного размером кластера, где кластеры определяются абсолютным отсечением в значениях матрицы, например, все эти кластеры с нулевым отличием друг от друга.

Макетные данные:

# Load packages
import numpy as np
import pandas as pd
import seaborn as sns

## Generate fake data
# matrix
d = {'sample_A': [0,2,0,1,1,2,2,1], 'sample_B': [2,0,2,3,3,0,0,3], 'sample_C': [0,2,0,1,1,2,2,1], 'sample_D': [1,3,1,0,2,3,3,1],
     'sample_E': [1,3,1,2,0,3,3,1], 'sample_F': [2,0,2,3,3,0,0,3], 'sample_G': [2,0,2,3,3,0,0,3], 'sample_H': [1,3,1,1,1,3,3,0]}
idx = ["sample_A","sample_B","sample_C","sample_D","sample_E", "sample_F", "sample_G", "sample_H"]
df = pd.DataFrame(data=d,index=idx)
df

# Visualise heatmap (this isn't directly needed for this output)
g = sns.clustermap(df, cmap="coolwarm_r")
g

# Desired output
d = {'cluster_zero': [2,1,2,"NA","NA",1,1,"NA"]}
df3 = pd.DataFrame(data=d,index=idx)
df3

Таким образом, выходные данные помечают каждую выборку как принадлежащую кластеру, определенному как имеющее нулевую попарную разницу в матрице, и называют кластер в порядке размера от наибольшего до наименьшего. В этом случае все образцы B, F и G имеют нулевые различия, поэтому их помещают в кластер 1. Образцы A и C также имеют нулевые различия друг от друга, и поскольку этот кластер меньше, чем B / F / G, они кластер 2. В этом случае нет других выборок с нулевой разницей, поэтому другие выборки не получают кластер.

В идеале я хотел бы иметь возможность контролировать порог разницы, который я использовал для определения кластеры, например, запустите сценарий снова, но с использованием порога <1 или <2, а не нуля. </p>

Существуют различные вопросы, подобные этому (например, Извлечение кластеров из карты кластеров seaborn ), но кажется, что они используют метрики для вычисления расстояния, а не абсолютного числа в матрице. Другой похожий вопрос: генерация числовых кластеров из значений матрицы минимального размера , но при этом учитывается размер каждого кластера, который отличается от желаемого результата.

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 02 мая 2020

Я нашел ответ на свой вопрос в этом блоге: https://joernhees.de/blog/2015/08/26/scipy-hierarchical-clustering-and-dendrogram-tutorial/

Решение, которое я сделал:

from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt

df_arr = np.asarray(df)

Z = hierarchy.linkage(df_arr, 'single')
plt.figure()
dn = hierarchy.dendrogram(Z)

from scipy.cluster.hierarchy import fcluster

# Set maximum threshold for difference e.g. 1
max_d = 1
clusters = fcluster(Z, max_d, criterion='distance')
clusters

Затем я поворачиваю кластеры массив в dataframe и pd.concat его на dataframe расстояния, а затем извлекать список имен образцов с кластером. Последнее, что я беру только кластеры, например,> 2 выборки в каждом кластере:

result = result.groupby('cluster').filter(lambda x : len(x)>2)
...