【问题标题】:math domain error while using PCA使用 PCA 时出现数学域错误
【发布时间】:2016-08-23 14:17:35
【问题描述】:

我正在使用 python 的 scikit-learn 包来实现 PCA。我正在学习数学

domain error :
C:\Users\Akshenndra\Anaconda2\lib\site-packages\sklearn\decomposition\pca.pyc in _assess_dimension_(spectrum, rank, n_samples, n_features)
     78         for j in range(i + 1, len(spectrum)):
     79             pa += log((spectrum[i] - spectrum[j]) *
---> 80                       (1. / spectrum_[j] - 1. / spectrum_[i])) + log(n_samples)
     81 
     82     ll = pu + pl + pv + pp - pa / 2. - rank * log(n_samples) / 2.

ValueError: math domain error

我已经知道当我们取负数的对数时会导致数学域错误,但我不明白这里怎么会有一个负数?因为此代码适用于其他数据集。 可能这与 sci-kitlearn 网站上写的内容有关——“这个实现使用了奇异值分解的 scipy.linalg 实现。它只适用于密集数组,不能扩展到大维数据。”(有大0 值的数量)

【问题讨论】:

  • 你能创建一个最小的例子来重现这个错误,使用随机数据吗?
  • 我也有同样的问题——正在记录 log(0)

标签: python scikit-learn pca


【解决方案1】:

我认为您应该添加 1,例如 the numpy log1p description page。 由于当 p = 0 时 log(p+1) = 0(而 log(e-99) = -99),并且作为链接中的引用

对于实值输入,log1p 也适用于 x 小到 1 + x == 1 的浮点精度

代码可以修改如下,让你尝试解决的更合理:

for i in range(rank):
    for j in range(i + 1, len(spectrum)):
        pa += log((spectrum[i] - spectrum[j]) *
        (1. / spectrum_[j] - 1. / spectrum_[i]) + 1) + log(n_samples + 1)
    ll = pu + pl + pv + pp - pa / 2. - rank * log(n_samples + 1) / 2

【讨论】:

    【解决方案2】:

    我不知道我是否正确,但我确实找到了解决它的方法。

    我只是打印了一些错误信息(频谱_[i]和频谱_[j]的值),我发现:

    有时候,它们是一样的!!!

    (也许他们不一样,但他们太接近了,我猜)

    所以,这里

    pa += log((spectrum[i] - spectrum[j]) *
                      (1. / spectrum_[j] - 1. / spectrum_[i])) + log(n_samples)
    

    计算log(0)时会报错。

    我的解决方法是在0上加一个很小的数1e-99,所以变成log(0 + 1e-99)

    所以您可以将其更改为:

                pa += log((spectrum[i] - spectrum[j]) *
                      (1. / spectrum_[j] - 1. / spectrum_[i]) + 1e-99) + log(n_samples)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      • 2016-05-13
      • 2017-01-04
      • 1970-01-01
      相关资源
      最近更新 更多