首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在sklearn.decomposition.PCA中,为什么components_是阴性的?

在sklearn.decomposition.PCA中,为什么components_是阴性的?
EN

Stack Overflow用户
提问于 2017-06-26 17:53:17
回答 4查看 11.4K关注 0票数 20

我试图跟随Abdi & Williams - 主成分分析 (2010年),并使用numpy.linalg.svd通过SVD构建主组件。

当我显示components_属性时,它们的大小与我手工计算的相同,但是的一些(不是所有的)是相反的符号。是什么引起的?

更新:下面的(部分)答案包含了一些附加信息。

以下列示例数据为例:

代码语言:javascript
复制
from pandas_datareader.data import DataReader as dr
import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import scale

# sample data - shape (20, 3), each column standardized to N~(0,1)
rates = scale(dr(['DGS5', 'DGS10', 'DGS30'], 'fred', 
           start='2017-01-01', end='2017-02-01').pct_change().dropna())

# with sklearn PCA:
pca = PCA().fit(rates)
print(pca.components_)
[[-0.58365629 -0.58614003 -0.56194768]
 [-0.43328092 -0.36048659  0.82602486]
 [-0.68674084  0.72559581 -0.04356302]]

# compare to the manual method via SVD:
u, s, Vh = np.linalg.svd(np.asmatrix(rates), full_matrices=False)
print(Vh)
[[ 0.58365629  0.58614003  0.56194768]
 [ 0.43328092  0.36048659 -0.82602486]
 [-0.68674084  0.72559581 -0.04356302]]

# odd: some, but not all signs reversed
print(np.isclose(Vh, -1 * pca.components_))
[[ True  True  True]
 [ True  True  True]
 [False False False]]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-06-30 12:56:31

正如您在回答中指出的,奇异值分解(SVD)的结果在奇异向量方面并不是唯一的。实际上,如果X的SVD是\sum_1^r \s_i u_i v_i^\top:

当s_i以递减的方式排列时,您可以看到您可以更改u_1和v_1的符号(即“翻转”),减号将取消,因此公式仍然有效。

这表明SVD是唯一的,直到左、右奇异向量成对的符号变化为止。

由于PCA只是X的一个SVD (或X^\顶X的特征值分解),因此不能保证它每次执行时都不会在同一个X上返回不同的结果。可以理解的是,scikit学习实现想要避免这种情况:它们保证返回的左、右奇异向量(存储在U和V中)总是相同的,方法是(这是任意的),使u_i的最大绝对值系数为正。

正如您所看到的,阅读来源:首先,他们用linalg.svd()计算U和V。然后,对于每个向量u_i (即U的行),如果其绝对值中的最大元素为正,则它们什么也不做。否则,它们将u_i改为- u_i,并将相应的左奇异向量v_i改为- v_i。正如前面所述,这不会改变SVD公式,因为减号抵消了。然而,现在保证在这个处理后返回的U和V总是相同的,因为符号上的不确定性已经消除了。

票数 14
EN

Stack Overflow用户

发布于 2017-06-26 23:23:44

经过一番挖掘,我澄清了一些,但不是全部,我在这个问题上的困惑。这个问题已经在stats.stackexchange 这里上讨论过了。数学上的答案是:"PCA是一种简单的数学变换,如果改变了分量的符号,就不会改变包含在第一个分量中的方差。“但是,在这种情况下(使用sklearn.PCA),歧义的来源要具体得多:在PCA的源(第391项)中:

代码语言:javascript
复制
U, S, V = linalg.svd(X, full_matrices=False)
# flip eigenvectors' sign to enforce deterministic output
U, V = svd_flip(U, V)

components_ = V

反过来,svd_flip被定义为这里。但是,我不确定为什么这些标志被转换为“确保确定性输出”。(U,S,V在这一点上已经找到)。因此,尽管sklearn的实施并不是不正确的,但我不认为这完全是凭直觉的。任何熟悉贝塔(系数)概念的金融界人士都会知道,第一个主成分最有可能类似于一个广泛的市场指数。问题是,sklearn的实施会给第一个主成分带来强大的负负荷。

我的解决方案是一个不实现版本的哑弹式svd_flip。它非常简单,因为它没有sklearn参数(如svd_solver ),但确实有许多专门针对此目的的方法。

票数 4
EN

Stack Overflow用户

发布于 2017-06-26 18:21:48

用这里的PCA在三维空间中,你基本上可以迭代地找到: 1)最大方差保持的一维投影轴,2)垂直于1的最大方差保持轴。第三轴是垂直于前两轴的轴。

根据解释的方差列出components_。第一个解释了最大的方差,依此类推。注意,通过PCA操作的定义,当您试图在第一步找到投影向量时,最大限度地保留了方差,向量的符号并不重要:让M作为您的数据矩阵(在您的情况下,它的形状为(20,3))。当数据被投影时,设v1是保持最大方差的向量。当您选择-v1而不是v1时,您将获得相同的方差。(你可以看看这个)。然后,在选择第二个向量时,设v2为垂直于v1的向量,并保持最大方差。同样,选择-v2而不是v2将保持相同的方差。然后,可以选择v3作为-v3或v3。在这里,唯一重要的是v1,v2,v3构成了一个正交基,对于M数据,符号主要取决于算法如何解决PCA运算背后的特征向量问题。特征值分解或SVD解在符号上可能有所不同。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44765682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档