我刚刚将numpy和scikit-learn的版本升级到最新版本,即numpy-1.16.3和sklearn-0.21.0(对于Python 3.7)。很多崩溃,例如数字矩阵上的简单PCA将不再起作用。例如,考虑以下玩具矩阵:
df[paste0("perc_", inds)] <- mapply(`/`, df[inds], df["expenses"])
然后在其上运行PCA:
Xt
Out[3561]:
matrix([[-0.98200559, 0.80514289, 0.02461868, -1.74564111],
[ 2.3069239 , 1.79912014, 1.47062378, 2.52407335],
[-0.70465054, -1.95163302, -0.67250316, -0.56615338],
[-0.75764211, -1.03073475, 0.98067997, -2.24648769],
[-0.2751523 , -0.46869694, 1.7917171 , -3.31407694],
[-1.52269241, 0.05986123, -1.40287416, 2.57148354],
[ 1.38349325, -1.30947483, 0.90442436, 2.52055143],
[-0.4717785 , -1.46032344, -1.50331841, 3.58598692],
[-0.03124986, -3.52378987, 1.22626145, 1.50521572],
[-1.01453403, -3.3211243 , -0.00752532, 0.56538522]])
此操作失败:
import sklearn.decomposition as skd
est2 = skd.PCA(n_components=4)
est2.fit(Xt)
我的印象是numpy已在非常基本的层次上进行了重组,包括单列矩阵引用,因此np.sum,np.sqrt等函数的行为不像旧版本那样。
有人知道numpy的前进方向是什么,究竟在这里发生了什么?
答案 0 :(得分:1)
此时,您的代码fit
在scipy.linalg.svd
上运行Xt
,并且正在查看奇异值S
。
self.mean_ = np.mean(X, axis=0)
X -= self.mean_
U, S, V = linalg.svd(X, full_matrices=False)
# flip eigenvectors' sign to enforce deterministic output
U, V = svd_flip(U, V)
components_ = V
# Get variance explained by singular values
explained_variance_ = (S ** 2) / (n_samples - 1)
total_var = explained_variance_.sum()
在我的工作情况下:
In [175]: est2.explained_variance_
Out[175]: array([6.12529695, 3.20400543, 1.86208619, 0.11453425])
In [176]: est2.explained_variance_.sum()
Out[176]: 11.305922832602981
np.sum
解释说,从v 1.15开始,它采用了initial
参数(参考ufunc.reduce
)。默认值为initial=np._NoValue
In [178]: np._NoValue
Out[178]: <no value>
In [179]: type(np._NoValue)
Out[179]: numpy._globals._NoValueType
因此,这部分解释了错误中的_NoValueType
参考。
您的scipy
版本是什么?
In [180]: import scipy
In [181]: scipy.__version__
Out[181]: '1.2.1'
我想知道您的scipy.linalg.svd
是否返回的S
数组是“旧的” ndarray
,并且没有完全实现此initial
参数。我无法解释为什么会发生这种情况,但是无法解释为什么数组sum
遇到np._NoValue
的问题。