Создание кластеров с использованием корреляционной матрицы в Python
Все, у меня есть корреляционная матрица из 21 сектора промышленности. Теперь я хочу разделить эти 21 сектор на 4 или 5 групп, при этом сектора схожего поведения сгруппированы вместе.
Могут ли эксперты пролить свет на то, как это сделать в Python, пожалуйста? Большое спасибо заранее!
2 ответа
Вы можете изучить использование панд DataFrame.corr
и scipy.cluster
Пакет иерархической кластеризации
import pandas as pd
import scipy.cluster.hierarchy as spc
df = pd.DataFrame(my_data)
corr = df.corr().values
pdist = spc.distance.pdist(corr)
linkage = spc.linkage(pdist, method='complete')
idx = spc.fcluster(linkage, 0.5 * pdist.max(), 'distance')
Хорошо, ответ @Wes предлагал использовать для этой задачи несколько хороших функций, однако он использовал их неправильно. После некоторого прочтения документации кажется, что вам нужна сжатая матрица попарных расстояний , прежде чем передавать ее вspc.linkage
функция, которая является верхнетреугольной частью матрицы расстояний, строка за строкой.
Там также говорится, чтоspc.pdist
функция возвращает матрицу расстояний в этой сжатой форме. Однако входные данные НЕ являются корреляционной матрицей или чем-то в этом роде. Ему нужны наблюдения , и он сам превратит их в матрицу с учетом указанной метрики.
Теперь вас не удивит тот факт, что ковариационная или корреляционная матрица уже суммирует наблюдения в матрицу. Вместо того, чтобы представлять расстояние, он представляет корреляцию. Здесь я не уверен, что с математической точки зрения является наиболее разумным, но я считаю, что вы могли бы превратить эту корреляционную матрицу в своего рода матрицу расстояний, просто вычислив1.0 - corr
.
Итак, давайте сделаем это:
pdist_uncondensed = 1.0 - corr
pdist_condensed = np.concatenate([row[i+1:] for i, row in enumerate(pdist_uncondensed)])
linkage = spc.linkage(pdist_condensed, method='complete')
idx = spc.fcluster(linkage, 0.5 * pdist_condensed.max(), 'distance')