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
.
的函数会很简单
我使用 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
.