Делаю алгоритм горной кластеризации для анализа многослойных сетов растровых геоданных.
Для вычислении растояния в алгоритме использую scipy.spatial.distance pdist и cdist. К сожалению, набор измерений дистанции по умолчанию у scipy не даёт нужного эффета - нужен метод определения подобия кривых хи-квадрат описан тут.
pdist и cdist позволяют производить обсчёт дистанций методами отличными от стандартных документация по scipy.spatial.distance.pdist пункт 23
В результате сделал следующий тестовый скрипт по хи-квадрат, показавший хорошие результаты:
import numpy as np from scipy.spatial.distance import pdist, squareform a = np.array( [ [1,1,1,2], [3,3,3,5], [1,2,3,4], [2,4,6,8], [1,2,3,2], [3,4,5,4], ] ) X2_1=lambda u, v: np.sqrt( ( (u - np.mean(u)*(u+v)/(np.mean(u)+np.mean(v)))**2/( np.mean(u)*(u+v)/(np.mean(u)+np.mean(v))) ).sum() + ( (v - np.mean(v)*(u+v)/(np.mean(u)+np.mean(v)))**2/( np.mean(v)*(u+v)/(np.mean(u)+np.mean(v))) ).sum() ) b = pdist( a, X2_1 ) c = pdist( a, "correlation" ) print a print squareform(b) print squareform(c)
массив
[[1 1 1 2] [3 3 3 5] [1 2 3 4] [2 4 6 8] [1 2 3 2] [3 4 5 4]]
[[ 0. 0.17053338 0.61237244 0.69006556 0.82285074 0.7154544 ] [ 0.17053338 0. 0.81416039 1.00385442 0.95791547 0.78956039] [ 0.61237244 0.81416039 0. 0. 0.67082039 0.90886834] [ 0.69006556 1.00385442 0. 0. 0.74833148 1.09295263] [ 0.82285074 0.95791547 0.67082039 0.74833148 0. 0.4330127 ] [ 0.7154544 0.78956039 0.90886834 1.09295263 0.4330127 0. ]]
[[ 0.00000000e+00 -2.22044605e-16 2.25403331e-01 2.25403331e-01 1.00000000e+00 1.00000000e+00] [ -2.22044605e-16 0.00000000e+00 2.25403331e-01 2.25403331e-01 1.00000000e+00 1.00000000e+00] [ 2.25403331e-01 2.25403331e-01 0.00000000e+00 2.22044605e-16 3.67544468e-01 3.67544468e-01] [ 2.25403331e-01 2.25403331e-01 2.22044605e-16 0.00000000e+00 3.67544468e-01 3.67544468e-01] [ 1.00000000e+00 1.00000000e+00 3.67544468e-01 3.67544468e-01 0.00000000e+00 2.22044605e-16] [ 1.00000000e+00 1.00000000e+00 3.67544468e-01 3.67544468e-01 2.22044605e-16 0.00000000e+00]]
Вроде бы всё хорошо, но есть большое НО:
При расчёте реальных растров процесс вычисления дистанций превращается для хи-квадрат в многочасовой. Понятно что в методе с пользовательской функцией начинают крутится питоновские циклы вместо бинарных стандартных методов написанных на C или C++
Могу переписать функцию для формулы в C++ но тогда встаёт вопрос как потом её интегрировать в качетве пользовательской функции для scipy.spatial.distance.pdist и sdist?
п.с:
Пробовал реализовать пример последний с instant Но установленная версия instant-1.5.0 не имеет функции Instant() c методом create_extension и вообще по данному пакету информация очень фрагментарная … не исключаю что плохо искал.