【问题标题】:Reproducing Singular Value Decompition in R在 R 中重现奇异值分解
【发布时间】:2016-09-09 17:24:03
【问题描述】:

我有一个逐个文档矩阵的示例(来自 Landauer 和 Dumais,1997 年):

wxd <- matrix(c(1,1,1,0,0,0,0,0,0,0,0,0,
            0,0,1,1,1,1,1,0,1,0,0,0,
            0,1,0,1,1,0,0,1,0,0,0,0,
            1,0,0,0,2,0,0,1,0,0,0,0,
            0,0,0,1,0,1,1,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,1,0,0,
            0,0,0,0,0,0,0,0,0,1,1,0,
            0,0,0,0,0,0,0,0,0,1,1,1,
            0,0,0,0,0,0,0,0,1,0,1,1)
          ,12, 9)
rownames(wxd) <- c("human", "interface", "computer", "user", "system", 
               "response", "time", "EPS", "survey", "trees", "graph", "minors")
colnames(wxd) <- c(paste0("c", 1:5), paste0("m", 1:4))

我可以使用svd() 函数对此矩阵执行奇异值分解,并拥有三个矩阵U、S 和V:

SVD <- svd(wxd)
U <- SVD$u
S <- diag(SVD$d)
V <- SVD$v

我可以将这些矩阵相乘并返回我的原始矩阵(在一些小的余量或误差范围内):

U %*% S %*% t(V)

我还可以取U 和V 矩阵的前两列和S 矩阵的前两列和行,以获得原始数据的最小二乘最佳近似值。这与我上面提到的论文中相同过程的结果相符:

U[ , 1:2] %*% S[1:2, 1:2] %*% t(V[ , 1:2])

我想确保我理解这个函数在做什么(尽我所能),并且我已经能够生成 V 和 S 矩阵来匹配来自 svd() 函数的矩阵:

ATA <- t(wxd) %*% wxd
V2 <- eigen(ATA)$vectors

S2 <- sqrt(diag(eigen(ATA)$values))

但是,我生成的 U 矩阵的前 9 列具有相同的绝对值,然后再添加 3 列。这个U 矩阵的一些元素与svd() 函数中的U 矩阵有不同的符号:

AAT <- wxd %*% t(wxd)
U2 <- eigen(AAT)$vectors

所以我的问题是,为什么U 矩阵与我尝试从头开始计算时不同?

【问题讨论】:

    标签: r svd decomposition singular


    【解决方案1】:

    wxd 的等级为 9。因此,您的AAT 只有9 非零特征值(其余的都非常小~1e-16)。对于那些零特征值,特征向量是任意的,只要它们跨越与 R^12 中其他特征向量所跨越的子空间正交的子空间。

    现在,默认情况下,svd 仅计算 nu=min(n,p) 左奇异向量(与右特征向量类似),其中 n 是行数,p 是输入中的列数(参见 ?svd )。因此,您只能得到9 左奇异向量。要生成所有12,请调用svd:

    svd(wxd,nu=nrow(wxd))
    

    但是,那些额外的3 左奇异向量将不再对应于eigen(AAT)$vectors 找到的那些,因为这些特征向量被任意确定以跨越该正交子空间。

    至于为什么某些符号发生了变化,请回想一下,特征向量仅由比例因子决定。尽管这些特征向量被归一化,但它们可能相差-1。要检查只需将U 中的一项与U2 中的对应一项相除。你应该得到所有1s 或-1s 的列:

    U[,1:9]/U2[,1:9]
    ##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
    ## [1,]    1   -1    1   -1    1   -1    1    1    1
    ## [2,]    1   -1    1   -1    1   -1    1    1    1
    ## [3,]    1   -1    1   -1    1   -1    1    1    1
    ## [4,]    1   -1    1   -1    1   -1    1    1    1
    ## [5,]    1   -1    1   -1    1   -1    1    1    1
    ## [6,]    1   -1    1   -1    1   -1    1    1    1
    ## [7,]    1   -1    1   -1    1   -1    1    1    1
    ## [8,]    1   -1    1   -1    1   -1    1    1    1
    ## [9,]    1   -1    1   -1    1   -1    1    1    1
    ##[10,]    1   -1    1   -1    1   -1    1    1    1
    ##[11,]    1   -1    1   -1    1   -1    1    1    1
    ##[12,]    1   -1    1   -1    1   -1    1    1    1
    

    更新以解释为什么特征向量只能根据比例因子确定

    这可以从特征向量的定义中看出。来自Wikipedia,

    在线性代数中,线性变换的特征向量或特征向量是一个非零向量,在对其应用线性变换时不会改变其方向。

    在有限维向量空间中,线性变换是用向量乘以方阵A,因此定义是(这是我希望 SO 支持 LaTeX 降价的地方,因为这不是代码;即*在这里是矩阵乘法):

    A * v = lambda * v
    

    称为矩阵A 的特征值方程,其中lambda 是与特征向量v 关联的特征值。从这个等式可以清楚地看出,如果v 是A 的特征向量,那么对于某个标量k 的任何k * v 也是A 的特征向量以及相关的特征值lambda。

    【讨论】:

    • 非常感谢,我想我明白了。因此,如果我运行SVD &lt;- svd(wxd,nu=nrow(wxd)),我可以使用 U 的前 9 列(例如,U[,1:9] %*% S %*% t(V))将原始矩阵重新组合在一起。但是,这似乎不适用于 U2(例如,U2[,1:9] %*% S2 %*% t(V2))。我错过了什么吗?
    • @snarble: 这是因为与 svd 不同,U2 和 V2 是通过使用 AAT 和 ATA 分别调用 eigen 来计算的,因此左右特征向量可以通过“+/-1”以不同的方式“相互缩放”。如果我们通过将U2[,1:9] 乘以校正U[,1:9]/U2[,1:9](它们是所有1s 或-1s 的列)来纠正这个问题,并将V2 乘以V/V2,那么我们很容易得到(U2[,1:9] * U[,1:9] / U2[,1:9]) %*% S2 %*% t(V2 * V / V2),这将恢复wxd。
    • 这很有帮助。如何确保我的两个矩阵 U 和 V 相互缩放以与 svd 函数相同?
    • @snarble:我不相信你可以。让我问你:通过从U2 和V2 恢复wxd,你真正想达到什么目的?
    • 好的,谢谢。我想编写自己的函数来执行 SVD,这样我就可以确定我知道发生了什么,或者至少我想完全了解运行 svd(wxd) 时发生的事情。
    猜你喜欢
    • 2023-03-22
    • 2011-09-28
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 2011-06-30
    • 2010-10-31
    • 2015-04-16
    • 2023-03-15
    相关资源
    最近更新 更多