R 包 lsa 中要保留多少个奇异值

How many singular values to keep in the R package lsa

我使用 R 包 lsa 中的函数 lsa 来获取语义 space。输入是术语文档矩阵。问题是lsa默认使用的dimcalc_share()函数好像是错误的。函数的帮助页面说函数 "finds the first position in the descending sequence of singular values where their sum meets or exceeds the specified share." 我理解这个词是因为函数保留第 n 个最大的奇异值,使得这些值的总和超过所有奇异值总和的一定百分比。 该函数的源代码是

function(share=0.5)
{
    function(x){
        if(any(which(cumsum(s/sum(s))<=share))){
            d=max(which(cumsum(s/sum(s))<=share))+1
        }
        else{
            d=length(s)
        }
        return(d)
    }
}

我对源代码有两个问题: 1.为什么要给d加1? 2.如果第一个奇异值的分数大于份额,函数将保留所有奇异值,而我认为函数应该只保留第一个。

你的第一个问题是"why the + 1?"

让我们看看这些函数是如何工作的:

# create some files
td = tempfile()
dir.create(td)
write( c("dog", "cat", "mouse"), file=paste(td, "D1", sep="/") )
write( c("ham", "mouse", "sushi"), file=paste(td, "D2", sep="/") )
write( c("dog", "pet", "pet"), file=paste(td, "D3", sep="/") )

# LSA
data(stopwords_en)
myMatrix = textmatrix(td, stopwords=stopwords_en)
myMatrix = lw_logtf(myMatrix) * gw_idf(myMatrix)
myLSAspace = lsa(myMatrix, dims=dimcalc_share())
as.textmatrix(myLSAspace)

             D1         D2         D3
cat   0.3616693  0.6075489  0.3848429
dog   0.4577219  0.2722711  1.2710784
mouse 0.5942734  1.3128719  0.1357196
ham   0.6075489  1.5336529 -0.1634938
sushi 0.6075489  1.5336529 -0.1634938
pet   0.6099616 -0.2591316  2.6757285

因此,lsa 根据输入矩阵和给定份额(默认为 .5)从 dimcalc_share() 获取维度,并运行奇异值分解以将原始 TDM 映射到新的 LSAspace.

这些维度是LSA降维的奇异值个数。 dimcalc_share() 在奇异值 s 的降序序列中找到第一个位置,其中它们的总和(除以所有值的总和)达到或超过指定的份额。

函数被写成 d 等于 max() 位置 <= share:

> # Break it apart
> s <- myMatrix
> share <- .5
> 
> any(which(cumsum(s/sum(s)) <= share)) #TRUE
[1] TRUE
> cumsum(s/sum(s)) <= share
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> d = max(which(cumsum(s/sum(s)) <= share)) + 1
> d
[1] 10

如果你只使用 d -1,这会给你 9 而不是 10,那么你将有一个 cumsum 仍然是 <= 到 [=25] 的位置=].那行不通:

> myMatrix = lw_logtf(myMatrix) * gw_idf(myMatrix)
> myLSAspace2 = lsa(myMatrix, dims=d-1)
Error in SVD$u[, 1:dims] : subscript out of bounds

等价

> dims = 9
> myLSAspace = lsa(myMatrix, dims)
Error in SVD$u[, 1:dims] : subscript out of bounds

所以函数dimshare_calc()在使用+ 1时是正确的。

你的第二个问题,针对这个例子修改过,是"would dimcalc_share() = 18 instead of = 1 if the first value was > share?"

如果第一个值是 > share,那么第一个 if 条件将 return 为假,并且,正如您假设的那样,将使用 length(s),即 18。

您可能会在 CrossValidated 上跟进一个问题,以确认您应该 = 1 的直觉是正确的(尽管这对我来说很有意义)。如果是这样,将 d = 1 重写为 else.

的函数会很简单