python vs R中的矩阵乘法没有为SVD白化返回相同的结果

Posted

技术标签:

【中文标题】python vs R中的矩阵乘法没有为SVD白化返回相同的结果【英文标题】:Matrix Multiplication in python vs R not returning the same results for SVD whitening 【发布时间】:2022-01-12 03:02:49 【问题描述】:

我正在R中的python中尝试this简单的白化功能

Python

def svd_whiten(X):
    U, s, Vt = np.linalg.svd(X, full_matrices=False)

    #print(U)
    #print(Vt)
    # U and Vt are the singular matrices, and s contains the singular values.
    # Since the rows of both U and Vt are orthonormal vectors, then U * Vt
    # will be white
    X_white = np.dot(U, Vt)

    return X_white

读取 Python 数据

df = pd.read_csv("https://raw.githubusercontent.com/thistleknot/Python-Stock/master/data/raw/states.csv")

pd.DataFrame(svd_whiten(df.iloc[:,2:]))

R

ZCA_svd <- function(x)

  internal <- svd(x)
  
  U = internal$u
  #print(U)
  Vt = internal$v
  #print(Vt)
  s = internal$d
  #U, s, Vt = np.linalg.svd(X, full_matrices=False)

  # U and Vt are the singular matrices, and s contains the singular values.
  # Since the rows of both U and Vt are orthonormal vectors, then U * Vt
  # will be white
  
  #dot(U,Vt)
  X_white = U%*%Vt
  #np$dot(U,Vt)
  #

  return(X_white)

R 数据

x_ = read.csv(file="https://raw.githubusercontent.com/thistleknot/Python-Stock/master/data/raw/states.csv",header =TRUE,row.names = 1)

x = x_[,2:ncol(x_)]

ZCA_svd(x)

如果我在 R 或 Python 中打印 U 和 Vt 的值,它们是相同的,但是当相乘时,R 和 Python 的结果不同。

为了增加乐趣,如果我使用 reticulate 并通过 np$dot(U, Vt) 导入 numpy。结果与 U%*%Vt 相同。因此。我不确定要使用哪个“correct”版本。

【问题讨论】:

该代码提供了一个可链接的 csv,而无需我将结果转储到问题中。 【参考方案1】:

通常写成wiki,其中V*是V的转置:

这就是你在scipy.linalg.svd 得到的回报:

将矩阵 a 分解为两个酉矩阵 U 和 Vh,以及一个一维矩阵 奇异值数组 s(实数,非负数)使得 a == U @ S @ Vh,其中 S 是一个适当形状的零矩阵,主对角线为 s。

而对于 R 中的 svd,它们会返回 V。因此应该是:

Vt = t(internal$v)

然后在 R 中:

ZCA_svd(x)

 head(ZCA_svd(x))
            [,1]        [,2]        [,3]        [,4]        [,5]        [,6]
[1,]  0.26067006  0.02112997  0.09365719  0.01843731  0.05470893  0.01750415
[2,] -0.17174605 -0.23530453  0.15122167 -0.27738192  0.03830312 -0.21142466
[3,] -0.10659408  0.07042392  0.06732517 -0.12081178  0.09487670 -0.01726953
[4,]  0.10659431  0.13668984  0.18523379  0.03799714  0.06525643 -0.09888497
[5,] -0.12998931 -0.05254591 -0.14654516 -0.15600721  0.13455552 -0.09930468
[6,] -0.07010493  0.01084335 -0.05152612 -0.07803706 -0.03505320  0.43416503
            [,7]        [,8]        [,9]
[1,] -0.02021101  0.08766270 0.073049749
[2,]  0.15877490  0.24157032 0.009806777
[3,]  0.03148085  0.09361557 0.100372380
[4,] -0.03620529  0.09898168 0.044607751
[5,]  0.02847737 -0.30396604 0.574410291
[6,]  0.03105272  0.13842155 0.076071540

在python中:

pd.DataFrame(svd_whiten(df.iloc[:,2:])).head(6)
 
          0         1         2         3         4         5         6         7         8
0  0.260670  0.021130  0.093657  0.018437  0.054709  0.017504 -0.020211  0.087663  0.073050
1 -0.171746 -0.235305  0.151222 -0.277382  0.038303 -0.211425  0.158775  0.241570  0.009807
2 -0.106594  0.070424  0.067325 -0.120812  0.094877 -0.017270  0.031481  0.093616  0.100372
3  0.106594  0.136690  0.185234  0.037997  0.065256 -0.098885 -0.036205  0.098982  0.044608
4 -0.129989 -0.052546 -0.146545 -0.156007  0.134556 -0.099305  0.028477 -0.303966  0.574410
5 -0.070105  0.010843 -0.051526 -0.078037 -0.035053  0.434165  0.031053  0.138422  0.076072

【讨论】:

我想这可以解释 Vt 中的 t。我相信我已经尝试过 U%*%t(Vt) 但它会出错关于不符合的数组。无论哪种方式,它都按照您的建议工作。

以上是关于python vs R中的矩阵乘法没有为SVD白化返回相同的结果的主要内容,如果未能解决你的问题,请参考以下文章

Python CUDA 并行化多个小矩阵的 SVD

术语文档矩阵中的SVD不能给出我想要的值

R程序中非常大的矩阵的svd

使用 spark 在 aws 上的 python 中的大矩阵的 SVD

python numpy svd

【转】矩阵分解之SVD和SVD++