У меня есть алгоритм анализа распределения слов. Он генерирует векторы наблюдений для каждого целевого слова, и из этой таблицы я использую stats.spearmanr () для вычисления расстояний (масштабируется от [-1,1] до [0,1]), генерируя матрицу расстояний (Y). Затем я используюierarchy.average (), чтобы получить кластеризацию (Z). Наконец, дендрограмма генерируется и строится.
У меня проблема в том, что масштаб дендрограммы зависит от количества целевых слов. Я предполагал, что его ось расстояния изменялась в диапазоне [0,1] (как получено (и изменено) с помощью spearmanr ()), как представлено выше. Но это [0, 0,5] для, скажем, 50 слов, но [0, 1] для 150 и [0, 2] для 1000.
Почему это так (что шкала расстояний имеет значения больше значений Y)?
Буду признателен за любые идеи по этому вопросу, потому что я не могу найти какой-либо подсказки в документации и в Интернете (что заставляет меня беспокоиться из-за неправильных вопросов ...). И мне нужен фиксированный масштаб или, по крайней мере, способ узнать, какой из них использует дендрограмма, для целей спецификации уровня среза. Заранее спасибо за любую помощь.
Упрощенный код:
# coding: utf-8
# Estatísticas e visualização
import numpy as np
import scipy, random
import scipy.stats
# Clusterização e visualização do dendrograma
import scipy.cluster.hierarchy as hac
import matplotlib.pyplot as plt
def remap(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
random.seed('7622')
sizes = [50, 250, 500, 1000, 2000]
for n in sizes:
# Generate observation matrix
X = []
for i in range(n):
vet = []
for j in range(300):
# Generate random observations
vet.append(random.randint(0, 50))
X.append(vet)
# X is a matrix where lines are variables (target words) and columns are observations (contexts of occurrence)
Y = scipy.stats.spearmanr(X, axis=1)
# Y rescaling
for i in range(len(Y[0])):
Y[0][i] = [ remap(v, -1, 1, 0, 1) for v in Y[0][i] ]
print 'Y [', np.matrix(Y[0]).min(), ',', np.matrix(Y[0]).max(), ']'
# Clustering
Z = hac.average(Y[0])
print 'n=', n, \
'Z [', min([ el[2] for el in Z ]), ',', max([ el[2] for el in Z ]), ']'
[ОБНОВЛЕНИЕ] Результаты приведенного выше кода:
Y [ 0.401120498124 , 1.0 ]
n= 50 Z [ 0.634408300876 , 0.77633631869 ]
Y [ 0.379375733574 , 1.0 ]
n= 250 Z [ 0.775241869849 , 0.969704246048 ]
Y [ 0.37559031365 , 1.0 ]
n= 500 Z [ 0.935671154717 , 1.16505319575 ]
Y [ 0.370600337649 , 1.0 ]
n= 1000 Z [ 1.19646327361 , 1.47897594053 ]
Y [ 0.359010408057 , 1.0 ]
n= 2000 Z [ 1.56890165007 , 1.96898566034 ]