使用PCA时出现数学域错误



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

domain error :
C:UsersAkshenndraAnaconda2libsite-packagessklearndecompositionpca.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.linarg实现。它只适用于密集数组,不能扩展到大维数据。"(有大量0值)

我认为应该添加1作为numpy-log1p描述页。由于log(p+1)=0时p=0(而log(e-99)=-99),并且作为链接中的报价

对于实值输入,log1p对于浮点精度中小到1+x==1的x也是准确的

代码可以修改如下,以使您试图解决的问题更加合理:

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

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

我只是打印一些错误信息(spectrum_[I]和spectrum_[j]的值),然后我发现:

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

(也许它们不一样,但我想它们太近了)

所以,这里是

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

它将在计算日志(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)

相关内容

  • 没有找到相关文章