1

我使用了 R 包 lsa 中的函数 lsa 来获取语义空间。输入是一个术语文档矩阵。问题是 lsa 默认使用的 dimcalc_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. 为什么要加 1 到 d?2.如果第一个奇异值的分数大于份额,该函数将保留所有奇异值,而我认为该函数应该只保留第一个。

4

1 回答 1

1

您的第一个问题是“为什么+ 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

因此,根据输入矩阵和给定的份额(默认为 0.5)lsa获取维度,并运行奇异值分解以将原始 TDM 映射到新的.dimcalc_share()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仍然是<=to的位置share。那是行不通的:

> 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

您针对此示例修改的第二个问题是“如果第一个值是 > share,dimcalc_share() = 18 而不是 = 1?”

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

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

于 2015-01-02T15:34:26.077 回答