2015-12-09 3 views
4

Я пытаюсь реализовать лапласианом eigenmaps алгоритм, который состоит из:как выполнить обобщенную eigendecomposition здесь?

1) построить график (я использую Knn и сказать, что есть ребро к к ближайшим соседям)

2) ассоциировать каждый ребра с весом

3) определяют диагональ (которая является суммой ряда размещены по диагонали)

4) выполняют обобщенную eigendecomposition (который должен быть Ур = лямбда D V, где L и D вычисляется в коде b elow)

Я думаю, что это можно как-то решить с помощью scipy.linalg.eig (vals), но я не понимаю, как правильно ввести две мои матрицы. Может ли кто-нибудь помочь мне в понимании того, как выполнить обобщенный шаг eigendecomposition?

import numpy as np 
import random as r 
from math import exp as exp 
from scipy.spatial import distance 

def rweights((vectors,features)): 
    return 1 * np.random.random_sample((vectors,features)) - 0 

def vEuclidean(v, m): 
    return np.apply_along_axis(lambda x: distance.euclidean(v,x), 1, m) 

def mEuclideans(m): 
    return np.apply_along_axis(lambda v: vEuclidean(v,m), 1, m) 

def neighbours(vector, neigh): 
    size = (vector.shape[0] - neigh) 
    for i in range(1,size): 
     vector[np.argmax(vector)] = 0.0 
    return vector 

def kNN(m, k): 
    me = mEuclideans(m) 
    return np.array(map(lambda v: neighbours(v, k), me)) 

def diag(m): 
    sums = np.sum(m,1) 
    (vectors,features) = m.shape 
    zeros = np.zeros(vectors*features).reshape((vectors,features)) 
    for i in range(features): 
     zeros[i][i] = sums[i] 
    return zeros 

def vectorWeight(v, sigma): 
     f = lambda x: exp((-(x)/(sigma**2))) 
     size = v.shape[0] 
     for i in range(size): 
      v[i] = f(v[i]) 
     return v 

def weight(m): 
    return np.array(np.apply_along_axis(lambda v: vectorWeight(v,0.5), 1, m)) 

if __name__ == "__main__": 
    np.random.seed(666) 
    m = rweights((5,3)) 
    w = weight(kNN(m, 2)) 
    D = diag(w) 
    L = D-w 
+0

Параметры массива 'a' и' b' объясняются в docstring 'scipy.linalg.eig' (http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.eig .html). Они должны соответствовать вашим 'L' и' D'. Вы пробовали это? Если это так, пожалуйста, опишите более подробно проблему, которая у вас есть. –

+0

@warren. Итак, scipy.linalg.eig (L, D) вернет собственные значения, соответствующие лямбда (w в доке), и v (vl нормированные собственные векторы в doc)? – stian

+0

С аргументами по умолчанию 'left = False, right = True', столбцы второго возвращаемого значения являются (правильными) обобщенными собственными векторами (' vr' в docstring). Это будут ваши 'v'. –

ответ

0

хорошо, этого ответа способствовала Warrens помощи (поэтому он заслуживает кредита), но я нашел видео на спектральную кластеризации https://www.youtube.com/watch?v=Ln0mgyvXNQE, где он использует лапласиан на графике. Я подумал, что было бы неплохо проверить мою реализацию против его результатов. Таким образом, я добавил:

from scipy.linalg import eig  

def distanceM(): 
    return np.array([[0.0,0.8,0.6, 0.1,0.0,0.0], 
    [0.8,0.0,0.9,0.0,0.0,0.0], [0.6,0.9,0.0,0.0,0.0,0.2], 
    [0.1,0.0,0.0,0.0,0.6,0.7],[0.0,0.0,0.0,0.6,0.0,0.8] 
    [0.0,0.0,0.2,0.7,0.8,0.0]]) 

if __name__ == "__main__": 
    w = distanceM() 
    D = diag(w) 
    L = D-w 
    w,vr = eig(L) 
    print vr 

Я считаю, что я получаю ту же лапласианом матрицу, а также одни и те же собственные векторы (второй столбец уг).

Смежные вопросы