5

Sto provando a utilizzare l'implementazione Neighbor neighbor di scikit per trovare i vettori di colonna più vicini a un vettore di colonna dato, fuori da una matrice di valori casuali.Perché il vicinato più prossimo di scikit-learn non sembra restituire le distanze di similarità del coseno adeguate?

si suppone che questo codice per trovare i vicini più prossimi della colonna 21 quindi controllare la somiglianza del coseno effettiva di tali vicini contro colonna 21.

from sklearn.neighbors import NearestNeighbors 
import sklearn.metrics.pairwise as smp 
import numpy as np 

test=np.random.randint(0,5,(50,50)) 
nbrs = NearestNeighbors(n_neighbors=5, algorithm='auto', metric=smp.cosine_similarity).fit(test) 
distances, indices = nbrs.kneighbors(test) 

x=21 

for idx,d in enumerate(indices[x]): 

    sim2 = smp.cosine_similarity(test[:,x],test[:,d]) 


    print "sklearns cosine similarity would be ", sim2 
    print 'sklearns reported distance is', distances[x][idx] 
    print 'sklearns if that distance was cosine, the similarity would be: ' ,1- distances[x][idx] 

uscita sembra

sklearns cosine similarity would be [[ 0.66190748]] 
sklearns reported distance is 0.616586738214 
sklearns if that distance was cosine, the similarity would be: 0.383413261786 

Così l'output di il ginocchio non è né la distanza del coseno né la somiglianza del coseno. Cosa dà? Inoltre, per quanto mi riguarda, ho pensato che l'implementazione dei Neighbours più vicini di sklearn non fosse un approccio Vicini più vicini approssimativi, ma non sembra rilevare i veri vicini migliori nel mio set di dati, rispetto ai risultati che ottengo se iterato su la matrice e controllare le somiglianze della colonna 211 con tutte le altre. Sto fraintendendo qualcosa di fondamentale qui?

risposta

7

Ok il problema era che il metodo .molto() di NearestNeighbours, per impostazione predefinita, presuppone che le righe siano campioni e che le colonne siano caratteristiche. Ho dovuto trasporre la matrice prima di passarla per adattarla.

MODIFICA: Inoltre, un altro problema è che il callable passato come metrica dovrebbe essere una distanza richiamabile, non una similitudine richiamabile. Altrimenti riceverai i K Farthest Neighbors:/

+0

'2 - 2 * similarità del coseno' è la distanza L2 dei vettori normalizzati – eickenberg

+0

Puoi cambiare il tuo esempio per renderlo più piccolo, ad es. (20, 40) invece di (500, 500)? Ci è voluto un po 'per girare sul mio computer e non ha bisogno di essere così grande per dimostrare il punto. Rendere la forma non quadrata può aiutare a disambiguare i campioni e gli assi delle feature. Se, a parità di altre condizioni, si scrive 'sim2 = smp.cosine_similarity (test [x,:], test [d,:])' nel proprio ciclo, quindi tutti i valori finiscono in coincidenza. – eickenberg

+0

Ho modificato gli importi di riga/colonne, ora dovrebbe essere più veloce – pplat