1

我继承了大约一年前编写的一些代码,所以我猜当时它使用的是numpy 1.13(现在是 v1.15.2)、scipy 1.00rc(现在是 v1.1.0)和sklearn 0.19(现在是 v.0.20。 0)。

它实现了Fisher 的 LDA以将n维空间减少到 1…<em>n-1 维空间,从而产生一个 numpy 复数数组作为其结果(由于浮点不精确)。然后该数组被愉快地挑选并馈入sklearn.cluster.MeanShift其中立即引发异常:

  File "/…/lib/python3.6/site-packages/sklearn/cluster/mean_shift_.py", line 416, in fit
    X = check_array(X)
  File "/…/lib/python3.6/site-packages/sklearn/utils/validation.py", line 531, in check_array
    _ensure_no_complex_data(array)
  File "/…/lib/python3.6/site-packages/sklearn/utils/validation.py", line 354, in _ensure_no_complex_data
    "{}\n".format(array))
ValueError: Complex data not supported

我仍在学习这里发生的数学细节,但令我感到奇怪的是,这段代码被宣布为“可运行”。

我在这里错过了什么吗?是版本变化带来了这种回归,还是存在更根本的代码缺陷?我将如何解决这个问题?

4

1 回答 1

0

在评论/聊天中,我们发现了至少一个问题,即

(cov_w + I)^-1 @ cov_b                       (1)

不是真实的,而是返回重要的虚部。这里@是矩阵乘法,cov_w 和 cov_b 是协方差矩阵,I 是单位矩阵。这可以通过计算 (cov_w + I)^-1 的矩阵平方根来解决,我们称之为 SQ,然后使用 (1) 类似于

SQ @ cov_b @ SQ                              (2)

因此具有相同的特征值,如果 V 是 (2) 的特征向量,则 (1) 的(右)特征向量是 SQ @ V。

我们得到的是,因为 (2) 是一个对称矩阵,它的特征分解可以使用它来计算,numpy.linalg.eigh这保证了纯真实的结果。eigh也可用于计算 SQ,请参见此处。一定要绕过逆向,eigh直接应用在cov_w + I甚至cov_w.

于 2018-10-06T08:50:19.730 回答