我继承了大约一年前编写的一些代码,所以我想当时是使用numpy 1.13(现在为v1.15.2),scipy 1.00rc(现在为v1.1.0)和sklearn 0.19(现在是0.20.0版)。
它实现Fisher’s LDA来将 n 维空间缩减为1… 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
我仍在学习这里发生的事情的数学细节,但是令我惊讶的是,该代码被声明为“可运行”。
我在这里错过了什么吗?版本变更是否带来了这种退步,还是存在更基本的代码缺陷?我该如何解决这个问题?
答案 0 :(得分: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,请参阅here。请确保绕过反函数并将eigh
直接应用于cov_w + I
甚至是cov_w
。