Визуализация кластерного анализа в Python (модули hcluster и matplotlib)

Задача: провести кластерный анализ и его результат представить в виде дендрограммы.
Инструменты: модули hcluster, matplotlib
Это короткий пост больше для того, чтобы не забыть чем для того, чтобы рассказать в подробностях о том, что происходит.
Допустим у нас есть набор данных и мы хотим посмотреть не образуют ли некоторые из этих данных группы и если да то какие. После чего мы хотим отобразить эти наши группы и отношения найденные между ними так, как это показано на картинке. Такой вид графиков называется дендрограмма. Обе эти задачи поможет нам решить , который является частью SciPy.
Модуль hcluster не устанавливается вместе со SciPy, так что ставить его надо отдельно. В Убунту это нехитрое действие выглядит так
Для рисования дендрограмм используются возможности matplotlib, так что если у вас он вдруг ещё не установлен:
Поехали с места в карьер. Этот пример проведёт анализ и нарисует вам дендрограмму случайного набора данных размерностью 12x100
import numpy
from numpy.random import rand
import matplotlib.pyplot as plt
X = rand(12,100)
X[0:5,:] *= 2
Y = pdist(X)
Z = linkage(Y)
dendrogram(Z)
plt.show()
Если вы используете ipython с опцией -pylab, то последняя строчка вам без надобности.
- Первые две строчки создают набор рэндомных данных (поэтому графики в этом посте всё время разные :) ).
- pdist рассчитывает расстояние между m (в нашем случае 12) наблюдениями в n-мерном пространстве (в нашем случае 100мерном).
- linkage - осуществляет кластеризацию на основе данных полученных pdist
- dendrogram - расчитывает параметры дендрограммы и отрисовывает её.
Как и большинство утилит проекта SciPy, hcluster пытается держаться поближе к синтаксису Matlab и старается по возможности дублировать сами матлабовские функции. Поэтому интересующимся подробностями того, что мы сейчас натворили я могу посоветовать почитать раздел Cluster Analysis в отличном .
А мы продолжим резвиться с визуализацией. Давайте менять подписи. Представим, что 12 наших рядов это 12 месяцев.
import numpy
from numpy.random import rand
import matplotlib.pyplot as plt
X = rand(12,100)
X[0:5,:] *= 2
Y = pdist(X)
Z = linkage(Y)
mon = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
R = dendrogram(Z, labels = mon, leaf_font_size = 15)
plt.show()
Месяцы мы называли по порядку, но на графике они, естественно, отсортированы по своим кластерам. У функии dendrogram есть ещё воз и маленькая тележка параметров, которыми вы можете контролировать вывод вашей дендрограммы.
Допустим для наших целей важно знать к какому сезону принадлежит каждый месяц. Давайте их раскрасим, и попутно приведём наш график в порядок:
import numpy
from numpy.random import rand
import matplotlib.pyplot as plt
import matplotlib.axes as ax
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_xlabel('Months')
ax1.set_title('Dendrogram')
X = rand(12,100)
X[0:5,:] *= 2
Y = pdist(X)
Z = linkage(Y)
mon = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
wint = ["Dec","Jan", "Feb"]
spr = ["Mar", "Apr", "May"]
summ = [ "Jun", "Jul", "Aug"]
aut = ["Sep", "Oct", "Nov"]
R = dendrogram(Z,labels =mon,leaf_font_size=15)
for tl in ax1.get_xticklabels():
if tl.get_text() in wint:
tl.set_color('b')
elif tl.get_text() in spr:
tl.set_color('r')
elif tl.get_text() in summ:
tl.set_color('y')
elif tl.get_text() in aut:
tl.set_color('k')
plt.savefig('dendrogram_hcluster.png')
Мы получаем значения подписей основных делений, сравниваем их со списками, хранящими имена месяцев для разных сезонов и окрашиваем их в соответствующие цвета. Результат работы скрипта не отобразится, а запишется на диск в .png файл (dendrogram_hcluster.png)
Спасибо
Viglidit shkarno, no mne ne ochen poniatno smicl deictvia…chto vi xotim naricovat?
2ksenia
Мы распределяем годы по группам. Годы которые более схожи между собой объединяются в более близкие группы, те что сильно различаются находятся в более далёких друг от друга группах.
magik, вы хотели, наверное, сказать месяцы…
нЕмного неправдободобно тогда