Путаница с маркировкой оси дендрограммы - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть большая (106x106) корреляционная матрица в пандах со следующей структурой:

+---+-------------------+------------------+------------------+------------------+------------------+-----------------+------------------+------------------+------------------+-------------------+
|   |         0         |        1         |        2         |        3         |        4         |        5        |        6         |        7         |        8         |         9         |
+---+-------------------+------------------+------------------+------------------+------------------+-----------------+------------------+------------------+------------------+-------------------+
| 0 |               1.0 |   0.465539925807 |   0.736955649673 |   0.733077703346 |  -0.177380436347 | -0.268022641963 |  0.0642473239514 | -0.0136866435594 |  -0.025596700815 | -0.00385065532308 |
| 1 |    0.465539925807 |              1.0 |  -0.173472213691 |   -0.16898620433 | -0.0460674481563 | 0.0994673318696 |   0.137137216943 |   0.061999118034 |  0.0944808695878 |   0.0229095105328 |
| 2 |    0.736955649673 |  -0.173472213691 |              1.0 |   0.996627003263 |  -0.172683935315 |  -0.33319698831 | -0.0562591684255 | -0.0306820050477 | -0.0657065745626 |  -0.0457836647012 |
| 3 |    0.733077703346 |   -0.16898620433 |   0.996627003263 |              1.0 |  -0.153606414649 | -0.321562257834 | -0.0465540370732 | -0.0224318843281 | -0.0586629098513 |  -0.0417237678539 |
| 4 |   -0.177380436347 | -0.0460674481563 |  -0.172683935315 |  -0.153606414649 |              1.0 | 0.0148395123941 |   0.191615549534 |   0.289211355855 |    0.28799868259 |    0.291523969899 |
| 5 |   -0.268022641963 |  0.0994673318696 |   -0.33319698831 |  -0.321562257834 |  0.0148395123941 |             1.0 |   0.205432455075 |   0.445668299971 |   0.454982398693 |    0.427323555674 |
| 6 |   0.0642473239514 |   0.137137216943 | -0.0562591684255 | -0.0465540370732 |   0.191615549534 |  0.205432455075 |              1.0 |   0.674329392219 |   0.727261969241 |     0.67891326835 |
| 7 |  -0.0136866435594 |   0.061999118034 | -0.0306820050477 | -0.0224318843281 |   0.289211355855 |  0.445668299971 |   0.674329392219 |              1.0 |   0.980543049288 |    0.939548790275 |
| 8 |   -0.025596700815 |  0.0944808695878 | -0.0657065745626 | -0.0586629098513 |    0.28799868259 |  0.454982398693 |   0.727261969241 |   0.980543049288 |              1.0 |    0.930281915882 |
| 9 | -0.00385065532308 |  0.0229095105328 | -0.0457836647012 | -0.0417237678539 |   0.291523969899 |  0.427323555674 |    0.67891326835 |   0.939548790275 |   0.930281915882 |               1.0 |
+---+-------------------+------------------+------------------+------------------+------------------+-----------------+------------------+------------------+------------------+-------------------+

Здесь усечено для простоты.

Если я вычислю связь, а затем построю дендрограммуиспользуя следующий код:

from scipy.cluster.hierarchy import dendrogram, linkage
Z = linkage(result_df.corr(),'average')
plt.figure()
fig, axes = plt.subplots(1, 1, figsize=(20, 20))
axes.tick_params(axis='both', which='major', labelsize=15)

dendrogram(Z=Z, labels=result_df_null_cols.columns, 
           leaf_rotation=90., ax=axes, 
           color_threshold=2.)

Это дает дендрограмму, например: enter image description here

Мой вопрос касается оси Y.Во всех примерах, которые я видел, ось Y ограничена 0,2, что я прочитал, чтобы интерпретировать как (1-corr).По моему результат, граница намного выше.0 - это элементы с высокой степенью корреляции (1-1 = 0), а 2 - отсечение для низкокоррелированных элементов (1 - -1 = 2).

Я нашел следующий ответ , но не согласуется сэтот ответ и ссылки на лекции здесь .

В любом случае - надеясь, что кто-то сможет уточнить, какой источник является правильным, и помочь распространить некоторые знания по теме.

1 Ответ

0 голосов
/ 02 апреля 2019

Метрика, которая использовалась для linkage(), представляет собой евклидово расстояние, см. здесь , а не фактические значения.Следовательно, оно может превышать 2, и оно зависит только от типа метрики расстояния, которое мы используем.

Это поддерживает точки, упомянутые в этом ответе.

1) Ось Y является мерой близости отдельных точек данных или кластеров.

Затем эти расстояния используются для вычисления дерева с использованием следующего вычисления между каждой парой кластеров.

Из документации:

enter image description here

В упомянутом образце

Даже если отдельные значения не выходят за пределы (-1, +1), мы получим следующую дендрограмму.

enter image description here

from scipy.spatial import distance
distance.pdist(df, 'euclidean')

Причина в том, что массив расстояний размером 45 (10 C 2 - каждая пара столбцов;порядок объясняется здесь ) будет иметь следующие значения:

array([1.546726  , 0.79914141, 0.79426728, 2.24085106, 2.50838998,
       2.22772899, 2.52578923, 2.55978527, 2.51553289, 2.11329023,
       2.10501739, 1.66536963, 1.6303103 , 1.71821177, 2.04386712,
       2.03917033, 2.03614219, 0.0280283 , 2.33440388, 2.68373496,
       2.43771817, 2.68351612, 2.73148741, 2.66843754, 2.31758222,
       2.67031469, 2.4206485 , 2.66539997, 2.7134241 , 2.65058045,
       1.44756593, 1.39699605, 1.55063416, 1.56324546, 1.52001219,
       1.32204039, 1.30206957, 1.29596715, 1.2895916 , 0.65145881,
       0.62242858, 0.6283212 , 0.08642582, 0.11145739, 0.14420816])

Если мы построим матрицу случайных значений с равномерным dist.(-1, 1) размером (160, 160), дендрограмма будет выглядеть примерно так!

enter image description here

Следовательно, решение вашей проблемы:

Вам необходимо преобразовать значения корреляции в некоторую форму меры расстояния.

  1. мы могли бы использовать ту же квадратную форму () , предложенную в другом ответе .Это метод клейкой ленты для достижения двух аспектов измерения расстояния.Он должен быть нулевым [между одними и теми же двумя точками] и неотрицательным для любых двух точек.Это может быть достигнуто путем вычитания каждого значения corr из одного.

  2. Непосредственно мы можем использовать функцию distance.pdist с корреляцией в качестве метрики.Реализация доступна здесь .Не забудьте преобразовать фрейм данных, потому что нам нужна корреляция между каждым столбцом, а не строкой.

Пример для понимания решения:

size = (10000,1)
col1 = np.random.randint(0,100,size) # base column
col2 = col1 * 0.9 + np.random.normal(0,2,size) # huge corr with small noise
col3 = col1 * 0.1 + np.random.normal(0,100,size) # uncorrelated column
col4 = col1 * (-0.5) + np.random.normal(0,1,size) # negatively corr

data = np.hstack((col1,col2,col3,col4))
df = pd.DataFrame(data , columns=list('ABCD'))

df.corr()

    A   B   C   D
A   1.000000    0.997042    0.029078    -0.997614
B   0.997042    1.000000    0.029233    -0.994677
C   0.029078    0.029233    1.000000    -0.028421
D   -0.997614   -0.994677   -0.028421   1.000000

#pdist_values = distance.squareform(1 - df.corr().values )
pdist_values = distance.pdist(df.T, 'correlation')
z = linkage(pdist_values, method='average')
dendrogram(z, labels=df.columns)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...