5

Scikit-learn kütüphanesinden DBSCAN algoritmasını kosinüs metriğiyle kullanmaya çalışıyordum ama hatayla sıkışmıştım. kod hattı X bir csr_matrix olanPython'da kosinüs metriği ile DBSCAN hatası

db = DBSCAN(eps=1, min_samples=2, metric='cosine').fit(X)  

olup. dokümantasyon metrik kullanmak mümkün olduğunu söylüyor olsa da,

algoritmanın auto'dan için geçerli

Metrik 'kosinüs' değil: hata şudur. Opsiyon algorithm='kd_tree' ve 'ball_tree''u kullanmayı denedim ama aynısını yaptım. Ancak, euclidean veya l1 metriği kullanırsam hata olmaz.

X matrisi büyüktür, bu nedenle önceden hesaplanmış bir çift geçişli matris kullanamıyorum.

python 2.7.6 ve scikit-learn 0.16.1 kullanıyorum. Veri kümem tam bir sıfıra sahip değil, bu nedenle kosinüs metriği iyi tanımlanmış.

+0

Bu, açıkçası, sklearn'deki bir hatadır. Kosinüs benzerliği bir metrik değildir. Üçgen eşitsizliğine uymuyor, bu yüzden bir KDTree ile çalışmayacak ve seçim yapmak zorunda değilsiniz. Bunların hepsi, algoritmayı 'otomatik' olarak ayarladığınızda neden kullanamayacağını bilmesi gereken bir yöntemi kullanmaya çalışmaktadır. –

+0

@AdamAcosta: Doğru bir şekilde anlarsam, '' auto''' algoritmasının '' ball_tree'' kullanmayı denemek yerine '' brute'' kullanması gerektiğini düşünüyor musunuz? (Katılıyorum.) –

cevap

9

Sklearn'deki dizinler (muhtemelen - bu yeni sürümlerle değişebilir) kosinüs hızlandırılamaz.

algorithm='brute''u deneyin. Eğer kosinüs mesafesi gibi normalize mesafe istiyorsanız

from sklearn.neighbors.ball_tree import BallTree 
print(BallTree.valid_metrics) 
+0

Teşekkürler! Şimdi çalışıyor. İlk olarak, bana bir hata verdi çünkü veri kümem için 'np.double' yerine' np.float32' kullanmıştım. DBSCAN'ın kosinüs metriği için bu tür bir hassaslık gerektirdiğini sanıyorum çünkü ikincisi küçük bir aralığa sahiptir (0 ile 1 arasında). – cheyp

+0

Genel olarak gerekli olmamalıdır, ancak sklearn uygulamasının bu gibi sınırlamaları olabilir. –

4

, ayrıca vektör normalize edilebilir: sklearn sürümünüz top ağacının desteklenen ölçümler görmek hızlandırabilir Metriklerin listesi için

önce ve sonra öklid metriğini kullanın. İki normalleştirilmiş vektörler için dikkat edin u ve v Öklid mesafesi sqrt eşittir (2-2 * cos (u, v)) ( see this discussion)

Sen dolayısıyla böyle bir şey yapabilirsiniz:

Xnorm = np.linalg.norm(X,axis = 1) 
Xnormed = np.divide(X,Xnorm.reshape(Xnorm.shape[0],1)) 
db = DBSCAN(eps=0.5, min_samples=2, metric='euclidean').fit(Xnormed) 

The mesafeler [0,2] 'da kalır, bu yüzden parametrelerinizi buna göre ayarladığınızdan emin olun.

+0

Euclidian-distance-on-normalized-vectors ile DBSCAN algoritmasının neden bu kadar basit-kosinüs mesafesi ile aynı sonucu vereceği üzerine biraz daha genişleyebilir misiniz? Özellikle, karenin/karekökün ne olduğu ve kosinüsün gerçekte * benzerlik * ölçtüğü ve mesafeyi (yani mesafe 1-cos (.;) Olduğu önemlidir.) '' –

+0

Örneğin, 'eps'' nin kosinüs mesafeli 'x' olarak ayarlanması gerektiğini biliyorsanız, DBSCAN ile "euclid" kullanıldığında sqrt (x) 'ye ayarlanmalıdır. Ve, eğer veri böyle ise, sabitleme amacına ulaşan sklearn endeksleme tamam mı? –

+0

@NikanaReklawyks Yukarıda belirttiğim gibi, burada bahsettiğim şey, normal bir mesafe elde etmek için kosinüs mesafesini elde etmek için yapılabilir. Kare işleminden dolayı tam olarak aynı olmayacak. Ayrıca, belirttiğiniz gibi, kosinüs mesafesi, insanların pozitif uzayda kosinüs benzerliğinin tamamlayıcısı olarak adlandırdığı şeydir, uygun bir uzaklık metriği değildir. Ama kosinüs mesafesi hakkında sorulan sorudan bu ayrıntılara girmiyorum. – benbo