2013-07-03 9 views
5

L'input su sklearn.clustering.DBSCAN deve essere pre-processato?Come scalare l'input DBSCAN in scikit-learn

Nell'esempio http://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html#example-cluster-plot-dbscan-py le distanze tra i campioni di ingresso X sono calcolati e normalizzati:

D = distance.squareform(distance.pdist(X)) 
S = 1 - (D/np.max(D)) 
db = DBSCAN(eps=0.95, min_samples=10).fit(S) 

In un altro esempio v0.14 (http://jaquesgrobler.github.io/online-sklearn-build/auto_examples/cluster/plot_dbscan.html) alcuni scalatura viene eseguita:

X = StandardScaler().fit_transform(X) 
db = DBSCAN(eps=0.3, min_samples=10).fit(X) 

I basare il mio codice sul secondo esempio e fare in modo che il clustering delle impression funzioni meglio con questo ridimensionamento. Tuttavia, questo ridimensionamento "standardizza le funzionalità rimuovendo la media e il ridimensionamento alla varianza dell'unità". Cerco di trovare i cluster 2d. Se ho i miei cluster distribuiti in un'area quadrata - diciamo 100x100, non vedo alcun problema nel ridimensionamento. Tuttavia, se sono distribuiti in un'area rettangolare, ad es. 800x200 il ridimensionamento 'schiaccia' i miei campioni e modifica le distanze relative tra loro in una dimensione. Ciò deteriora il clustering, non è vero? O sto capendo sth. sbagliato? Devo applicare un po 'di pre-elaborazione, o posso semplicemente inserire i miei dati "grezzi"?

risposta

12

Dipende da ciò che si sta tentando di fare.

Se si esegue DBSCAN su dati geografici e le distanze sono espresse in metri, probabilmente non si desidera normalizzare nulla, ma impostare anche la soglia epsilon in metri.

E sì, in particolare un ridimensionamento non uniforme fa distorsione distanze. Mentre un ridimensionamento non distorto equivale a usare solo un valore epsilon diverso!

noti che nel primo esempio, apparentemente una matricedistanza somiglianza e non viene elaborato. S = (1 - D/np.max(D)) è un euristico per convertire una matrice di similarità in una matrice di dissomiglianza. Epsilon 0,95 significa quindi efficacemente al massimo "0,05 della massima dissimilarità osservata". Una versione alternativa che dovrebbe produrre lo stesso risultato è:

D = distance.squareform(distance.pdist(X)) 
S = np.max(D) - D 
db = DBSCAN(eps=0.95 * np.max(D), min_samples=10).fit(S) 

considerando che nel secondo esempio, fit(X) elabora effettivamente i dati grezzi ingresso, e non una matrice distanza. IMHO è un brutto scherzo, per sovraccaricare il metodo in questo modo. È conveniente, ma a volte porta a equivoci e forse persino a un uso errato.

Nel complesso, non prenderei DBSCAN di sklearn come referente. L'intera API sembra essere fortemente guidata dalla classificazione, non dal clustering. Solitamente, non si effettua il clustering in fit, ma lo si fa solo per i metodi supervisionati. Inoltre, sklearn al momento non utilizza gli indici per l'accelerazione e ha bisogno della memoria O(n^2) (che di solito DBSCAN non dovrebbe).

In generale, è necessario assicurarsi che la distanza funzioni. Se la tua funzione di distanza non funziona, no, l'algoritmo basato sulla distanza produrrà i risultati desiderati. Su alcuni set di dati, le distanze ingenue come Euclidee funzionano meglio quando si normalizzano i dati per la prima volta. Su altri set di dati, hai una buona comprensione della distanza (ad esempio, dati geografici. Effettuare una standardizzazione in modo oggettivo non ha senso, né la distanza euclidea!)

+0

Grazie mille per la tua risposta veloce.Mi piace identificare le fonti di luce lampeggianti che potrebbero spostarsi casualmente, il che porta a una sbavatura gaussiana. Inoltre ho il rumore sovrapposto. Al momento sto ignorando le intensità dei lampeggi e mi limito ad alimentare le posizioni 2d degli eventi lampeggianti. Quindi penso che la distanza euclidea sia ok? Dalla tua risposta capisco nel mio caso che non devo pre-elaborare i dati (che sono posizioni in nm). Ma per quanto riguarda l'implementazione sklearn? Ha effettivamente bisogno di somiglianze come input o posso semplicemente dargli le posizioni e applica la misura di distanza Euclidea stessa? – Alex

+0

Se i pixel sono equamente distribuiti su xey, allora non normalizzare e utilizzare Euclide. Per quanto riguarda sklearn, dovrai scavare nella documentazione e nel codice sorgente. Credo che se si alimentano dati grezzi, calcolerà una matrice di distanza euclidea da sola. (Ma NON usare indici per l'accelerazione. Prova ELKI, dovrebbe essere molto più veloce con gli indici). –

+0

Ok, grazie. Darei un'occhiata all'ELKI e scaverò nei documenti sklearn. – Alex