2016-04-28 122 views
2

我使用python的scikit学习包来实现PCA。我正在逐渐数学数学领域的错误,而使用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值)

+0

你可以创建一个最小使用随机数据重现此错误的例子? – eickenberg

+0

我有同样的问题 - 正在采取日志(0) – user48956

回答

0

我不知道我是否正确,但我真的找到一种方法来解决它。

我只是打印一些错误信息(spectrum_的值[i]和spectrum_ [J]),我发现:

有时,它们是相同的!

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

所以,这里

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

它会报告错误时计算日志(0)。

我的方式来解决它是一个非常小的数目1E-99添加到0,所以它成为数(0 + 1E-99)

所以你可以将其更改为:

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

我想你应该加1而不是the numpy log1p description page。 由于日志(P + 1)= 0时p = 0时(当日志(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