Numpy、Pandas 和 Sklearn 中的多维缩放拟合(ValueError)

Posted

技术标签:

【中文标题】Numpy、Pandas 和 Sklearn 中的多维缩放拟合(ValueError)【英文标题】:Multidimensional Scaling Fitting in Numpy, Pandas and Sklearn (ValueError) 【发布时间】:2013-06-04 04:01:27 【问题描述】:

我正在尝试使用 sklearn、pandas 和 numpy 进行多维缩放。我使用的数据文件有 10 个数字列,没有缺失值。我正在尝试获取这十维数据并使用 sklearn.manifold 的多维缩放将其在二维中可视化,如下所示:

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_

但我得到这个值错误:

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

我认为 euclidean_distances 返回了一个对称矩阵。我做错了什么,我该如何解决?

【问题讨论】:

首先检查np.allclose(similarities, similarites.T)True。当我尝试使用随机输入时,它可以工作。你可以试试随机输入吗? 试试scipy.spatial.distance_matrix?或者,如果您只是使用欧几里得距离,您可以让 sklearn 使用 dissimilarity="euclidean" 计算它们。 我遇到了类似的问题,我不得不通过将容差乘以 20 来修补 sklearn/manifold/mds.py 中的 L71(np.abs(similarities - similarities.T).max()对我来说是 ~1e-12 而不是 如果降级者可以提供评论,那就太好了。在没有输入的情况下拒绝投票和弹跳在任何方面都没有建设性。浪费时间。 您需要回答 Phillip Cloud 的问题,以及 cmets 中发布的其他问题。您还需要提供测试数据来重现问题。 【参考方案1】:

我遇到了同样的问题;事实证明,我的数据是np.float32 的数组,浮点精度的降低导致距离矩阵不对称。我通过在运行 MDS 之前将我的数据转换为 np.float64 解决了这个问题。

这是一个使用随机数据来说明问题的示例:

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"

【讨论】:

谢谢,真的好用。但在更改为 float64 后,我收到了另一个警告:/Library/Python/2.7/site-packages/sklearn/manifold/mds.py:396: UserWarning: The MDS API has changed。 fit 现在从数据构造一个相异矩阵。要使用自定义相异矩阵,请设置dissimilarity='precomputed'【参考方案2】:

前段时间遇到了同样的问题。另一种我认为效率更高的解决方案是仅计算上三角矩阵的距离,然后复制到下半部分。

可以用 scipy 完成如下:

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

【讨论】:

以上是关于Numpy、Pandas 和 Sklearn 中的多维缩放拟合(ValueError)的主要内容,如果未能解决你的问题,请参考以下文章

用于 sklearn 管道的 pandas 到 numpy 数组

Pandas+Numpy+Sklearn随机取数

Pandas+Numpy+Sklearn随机取数

Pandas+Numpy+Sklearn随机取数

将 pandas 稀疏数据帧转换为稀疏 numpy 矩阵以供 sklearn 使用?

Pandas sklearn one-hot 编码数据帧或 numpy?