我正在使用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)