【问题标题】:Inconsistencies between latest numpy and scikit-learn versons?最新的 numpy 和 scikit-learn 版本之间的不一致?
【发布时间】:2019-05-12 23:24:19
【问题描述】:

我刚刚将我的 numpy 和 scikit-learn 版本升级到最新版本,即 numpy-1.16.3 和 sklearn-0.21.0(适用于 Python 3.7)。很多东西都在崩溃,例如数字矩阵上的简单 PCA 将不再起作用。例如,考虑这个玩具矩阵:

Xt
Out[3561]: 
matrix([[-0.98200559,  0.80514289,  0.02461868, -1.74564111],
        [ 2.3069239 ,  1.79912014,  1.47062378,  2.52407335],
        [-0.70465054, -1.95163302, -0.67250316, -0.56615338],
        [-0.75764211, -1.03073475,  0.98067997, -2.24648769],
        [-0.2751523 , -0.46869694,  1.7917171 , -3.31407694],
        [-1.52269241,  0.05986123, -1.40287416,  2.57148354],
        [ 1.38349325, -1.30947483,  0.90442436,  2.52055143],
        [-0.4717785 , -1.46032344, -1.50331841,  3.58598692],
        [-0.03124986, -3.52378987,  1.22626145,  1.50521572],
        [-1.01453403, -3.3211243 , -0.00752532,  0.56538522]])

然后在其上运行 PCA:

import sklearn.decomposition as skd
est2 = skd.PCA(n_components=4)
est2.fit(Xt)

这失败了:

Traceback (most recent call last):

  File "<ipython-input-3563-1c97b7d5474f>", line 2, in <module>
    est2.fit(Xt)

  File "/home/sven/anaconda3/lib/python3.7/site-packages/sklearn/decomposition/pca.py", line 341, in fit
    self._fit(X)

  File "/home/sven/anaconda3/lib/python3.7/site-packages/sklearn/decomposition/pca.py", line 407, in _fit
    return self._fit_full(X, n_components)

  File "/home/sven/anaconda3/lib/python3.7/site-packages/sklearn/decomposition/pca.py", line 446, in _fit_full
    total_var = explained_variance_.sum()

  File "/home/sven/anaconda3/lib/python3.7/site-packages/numpy/core/_methods.py", line 36, in _sum
    return umr_sum(a, axis, dtype, out, keepdims, initial)

TypeError: float() argument must be a string or a number, not '_NoValueType'

我的印象是 numpy 已经在一个非常基础的层面进行了重组,包括单列矩阵引用,这样 np.sum、np.sqrt 等函数的行为就不像旧版本中那样。

有谁知道 numpy 的前进道路是什么以及这里到底发生了什么?

【问题讨论】:

  • 上面应该是est2.fit(Xt)
  • 我看到Xtnumpy.matrixmatrix 类的行为与常规的 numpy 数组对象不同。您是否尝试过使用常规 numpy 数组而不是 numpy.matrix 来运行示例?
  • 使用与您相同的版本(Py3.6 除外),您的代码运行良好。我不知道numpy 的任何重大更改会带来问题,尽管我不太了解PCA 正在做什么。
  • @WarrenWeckesser,使用np.matrix 不是问题。这段代码为我运行。 _NoValueType 错误表明np.sum 的相对(np 1.15)新的initial 参数可能存在问题,可能在不兼容的scipy 版本中。
  • 为了它的价值:我刚刚用 Python 3.7、numpy 1.16.3、scipy 1.2.1 和 scikit-learn 0.21.0 尝试了你的代码,并且成功了。这是在 64 位 Linux 平台上。

标签: numpy scikit-learn python-3.7


【解决方案1】:

此时,您的代码 fit 在您的 Xt 上运行 scipy.linalg.svd,并且正在查看奇异值 S

    self.mean_ = np.mean(X, axis=0)
    X -= self.mean_

    U, S, V = linalg.svd(X, full_matrices=False)
    # flip eigenvectors' sign to enforce deterministic output
    U, V = svd_flip(U, V)

    components_ = V

    # Get variance explained by singular values
    explained_variance_ = (S ** 2) / (n_samples - 1)
    total_var = explained_variance_.sum()

在我的工作案例中:

In [175]: est2.explained_variance_                                              
Out[175]: array([6.12529695, 3.20400543, 1.86208619, 0.11453425])
In [176]: est2.explained_variance_.sum()                                        
Out[176]: 11.305922832602981

np.sum 解释说,从 v 1.15 开始,它需要一个 initial 参数(参考 ufunc.reduce)。而默认是initial=np._NoValue

In [178]: np._NoValue                                                           
Out[178]: <no value>
In [179]: type(np._NoValue)                                                     
Out[179]: numpy._globals._NoValueType

这部分解释了错误中的_NoValueType 引用。

你的scipy 是什么版本?

In [180]: import scipy                                                          
In [181]: scipy.__version__                                                     
Out[181]: '1.2.1'

我想知道您的 scipy.linalg.svd 是否返回一个 S 数组,它是一个“旧”ndarray,并且没有完全实现这个 initial 参数。我无法解释为什么会发生这种情况,但无法解释为什么数组sumnp._NoValue 存在问题。

【讨论】:

  • 感谢您指向scipy 版本。我有 1.1.0。重新安装 scipynumpynumpy-base 解决了这个问题。
猜你喜欢
  • 2018-02-17
  • 2020-04-27
  • 2021-05-02
  • 2016-08-18
  • 2015-08-20
  • 2017-04-01
  • 2019-04-09
  • 2020-05-15
  • 2017-02-16
相关资源
最近更新 更多