2013-06-07 10 views
12

Çok boyutlu ölçeklemeyi sklearn, pandalar ve numpy ile deniyorum. Im kullanarak veri dosyası 10 sayısal sütun ve eksik değerleri vardır. aşağıdaki gibi ben sklearn.manifold en çok boyutlu ölçekleme ile 2 boyutlu olarak bu on boyutlu verileri alıp görselleştirmek için çalışıyorum:Numpy, Pandalar ve Sklearn'de Çok Boyutlu Ölçeklendirme Uyumu (ValueError)

import numpy as np 
import pandas as pd 
from sklearn import manifold 
from sklearn.metrics import euclidean_distances 

seed = np.random.RandomState(seed=3) 
data = pd.read_csv('data/big-file.csv') 

# start small dont take all the data, 
# its about 200k records 
subset = data[:10000] 
similarities = euclidean_distances(subset) 

mds = manifold.MDS(n_components=2, max_iter=3000, eps=1e-9, 
     random_state=seed, dissimilarity="precomputed", n_jobs=1) 

pos = mds.fit(similarities).embedding_ 

Ama bu değer hatayı alıyorum:

Traceback (most recent call last): 
    File "demo/mds-demo.py", line 18, in <module> 
    pos = mds.fit(similarities).embedding_ 
    File "/Users/dwilliams/Desktop/Anaconda/lib/python2.7/site-packages/sklearn/manifold/mds.py", line 360, in fit 
    self.fit_transform(X, init=init) 
    File "/Users/dwilliams/Desktop/Anaconda/lib/python2.7/site-packages/sklearn/manifold/mds.py", line 395, in fit_transform 
eps=self.eps, random_state=self.random_state) 
    File "/Users/dwilliams/Desktop/Anaconda/lib/python2.7/site-packages/sklearn/manifold/mds.py", line 242, in smacof 
eps=eps, random_state=random_state) 
    File "/Users/dwilliams/Desktop/Anaconda/lib/python2.7/site-packages/sklearn/manifold/mds.py", line 73, in _smacof_single 
raise ValueError("similarities must be symmetric") 
ValueError: similarities must be symmetric 

düşündüm euclidean_distances döndü simetrik matris. Neyi yanlış yapıyorum ve nasıl düzeltebilirim?

+2

ilk kontrol aşağıdaki gibidir:

Bu SciPy ile yapılabilir. bunu rasgele girdilerle denediğimde işe yarıyor. rastgele giriş ile deneyebilirsiniz? –

+0

'scipy.spatial.distance_matrix' kullanmayı deneyin. Ya da sadece euclidean mesafesini kullanıyorsanız, sklearn'in, "Benzerlik =" euclidean "kullanarak hesaplamasını sağlayabilirsiniz. –

+0

Benzer bir soruna rastladım ve toleransı 20 ('np.abs (benzerlikler - benzerlikler. T) .max()' ile çarparak L71'de sklearn/manifold/mds.py'ye yerleştirmek zorunda kaldım. ~ 1e-12 <1e-13 yerine benim için, kontrol çok sıkıydı ve başarısız oldu – jorgeca

cevap

7

Aynı problemden geçtim; Verilerimin np.float32 dizisi olduğu ve azaltılmış float hassasiyetinin uzaklık matrisinin asimetrik olmasına neden olduğu ortaya çıktı. MDS'yi çalıştırmadan önce verilerimi np.float64'a dönüştürerek sorunu çözdüm.

Aşağıda, sorunu göstermek için rasgele verileri kullanan bir örnek:

import numpy as np 
from sklearn.manifold import MDS 
from sklearn.metrics import euclidean_distances 
from sklearn.datasets import make_classification 

data, labels = make_classification() 
mds = MDS(n_components=2) 

similarities = euclidean_distances(data.astype(np.float64)) 
print np.abs(similarities - similarities.T).max() 
# Prints 1.7763568394e-15 
mds.fit(data.astype(np.float64)) 
# Succeeds 

similarities = euclidean_distances(data.astype(np.float32)) 
print np.abs(similarities - similarities.T).max() 
# Prints 9.53674e-07 
mds.fit(data.astype(np.float32)) 
# Fails with "ValueError: similarities must be symmetric" 
+0

Thx , Gerçekten işe yarıyor ama float64, olarak değiştirildikten sonra başka bir uyarı aldım: /Library/Python/2.7/site-packages/sklearn/manifold/mds.py:396: UserWarnin g: MDS API değişti. "sığdır" artık verilerden farklı bir matris oluşturur. Özel bir farklılık matrisi kullanmak için '' farklılık = 'önceden hesaplanmış' 'öğesini ayarlayın. – NullPointer

6

bir süre önce aynı sorun vardı. Daha verimli olduğuna inandığım bir başka çözüm ise, sadece üst üçgen matris için mesafeyi hesaplamak ve daha sonra alt kısma kopyalamaktır. `Np.allclose (benzerlikler, similarites.T)` `TRUE olduğu

from scipy.spatial.distance import squareform,pdist                
similarities = squareform(pdist(data,'speuclidean'))