2016-06-25 13 views
5

Mam zestaw wektorów 100 tysięcy i potrzebuję pobrać 25 najlepszych wektorów opartych na podobieństwie cosinusów.Jak szybko obliczyć podobieństwo cosinusa dla dużej liczby wektorów w Pythonie?

Scipy i Sklearn mają implementacje do obliczania odległości/podobieństwa kosinusów 2 wektory, ale muszę obliczyć Cosine Sim dla rozmiaru 100k X 100k, a następnie wyjąć top-25. Czy jest jakiś szybki implemenet w Pythonie to obliczyć?

Zgodnie @Silmathoron Sugestia, to co robię -

#vectors is a list of vectors of size : 100K x 400 i.e. 100K vectors each of dimenions 400 
vectors = numpy.array(vectors) 
similarity = numpy.dot(vectors, vectors.T) 


# squared magnitude of preference vectors (number of occurrences) 
square_mag = numpy.diag(similarity) 

# inverse squared magnitude 
inv_square_mag = 1/square_mag 

# if it doesn't occur, set it's inverse magnitude to zero (instead of inf) 
inv_square_mag[numpy.isinf(inv_square_mag)] = 0 

# inverse of the magnitude 
inv_mag = numpy.sqrt(inv_square_mag) 

# cosine similarity (elementwise multiply by inverse magnitudes) 
cosine = similarity * inv_mag 
cosine = cosine.T * inv_mag 

k = 26 

box_plot_file = file("box_data.csv","w+") 

for sim,query in itertools.izip(cosine,queries): 
    k_largest = heapq.nlargest(k, sim) 
    k_largest = map(str,k_largest) 
    result = query + "," + ",".join(k_largest) + "\n" 
    box_plot_file.write(result) 
box_plot_file.close() 
+0

Co masz na myśli, mówiąc o "najbliższym 25 wektorach"? Top 25 najbliższych par? Albo coś innego? –

+0

Dla każdego wektora, wyliczę podobieństwo cosinusa do każdego innego wektora i wybiorę 25 wektorów dla każdego wektora w odniesieniu do podobieństwa cosinusów. – user3667569

+0

to zależy od tego, jak szybko tego chcesz ... jeśli pokażesz nam przykład swojej implementacji z czasem, jaki zajmie (potencjalnie na podpróbce, jeśli jest naprawdę zbyt wolny) i podasz nam pożądany wzrost prędkości, wtedy możemy powiedzieć jeśli możesz go przyspieszyć za pomocą lepszego algorytmu w Pythonie lub jeśli potrzebujesz przejść do cython lub wielowątkowości ... – Silmathoron

Odpowiedz

2

chciałbym spróbować mądrzejszy algorytmy pierwsze, zamiast przyspieszenia brutalnej siły (obliczeniowej wszystkie pary wektorów). KDTrees może działać, scipy.spatial.KDTree(), jeśli twoje wektory mają niski wymiar. Jeśli mają one duży rozmiar, najpierw możesz potrzebować losowej projekcji: http://scikit-learn.org/stable/modules/random_projection.html

Powiązane problemy