R:平均余弦相似度分数的 For 循环

问题描述 投票:0回答:1

我正在尝试使用 R 中

stringsim
包中的
stringdist
来计算两组文本之间的余弦相似度分数。这些文本是存储在两个单独的字符向量中的词干标记。最终,我试图获得 data1 中每个项目与 data2 中每个项目相比的相似性分数,然后对这些进行平均以获得 data1 中每个项目的一个分数。

我已经能够使用

stringsim
单独计算每个比较的分数,并使用
outer
计算每个数据帧的子集。但是每个数据框中都有很多行,因此单独执行它们是不可行的。我正在尝试创建一个
for
循环来迭代它,但似乎无法获得我正在寻找的结果。我对
for
循环非常陌生,所以我确信我错过了一些东西,但我不知道它是什么。

这是每个数据框中前五个项目的简短子集,以显示我的数据的样子:

data1 <- c("California State Univers stand beacon excel divers peopl pedagogi place singular determin provid student access opportun lead transform self societi", 
"encourag student alumni passion empathet forev curious ask consequenti action look embodi Californian spirit", 
"Scope Mission California State Univers promot student success opportun high-qual educ prepar student becom leader chang workforc make CSU vital econom engin California", 
"Educat ethnic econom academ divers student bodi nation", "renown qualiti teach prepar job-readi graduat")

data2 <- c("Exist law Sherman Food Drug Cosmet Law contain various provis regard packag label advertis food drug cosmet", 
"bill appropri unspecifi amount Gener Fund Western Institut Food Safeti Secur within Univers California Davi fund research increas knowledg scientif understand caus detect foodborn diseas", 
"SECTION 1 Legislatur herebi find declar follow part healthi nutrit lifestyl Californian encourag increas consumpt fresh fruit veget b California farmer produc highest qualiti food world Howev despit regul mandat safe product process practic foodborn ill occur c Californian eat minim process food Research find resist pathogen bacteria well new pathogen bacteria emerg food suppli d Food safeti team effort everyon � s respons farm processor retail consum", 
"SEC 2 sum ____ $ ____ herebi appropri Gener Fund Western Institut Food Safeti Secur within Univers California Davi fund reserch increas knowledg scientif understand caus detect foodborn diseas", 
"act add repeal Section 8157 Educat Code relat apprenticeship make appropri therefor")

这些是我已经开始工作的代码:

require("stringdist")
stringsim(data1[1], data2[1], method = "cosine")

outer(data1, data2, stringsim, method = "cosine")

这些是我尝试过的似乎很接近的东西,但还没有完全产生我想要的东西:

for(i in data1) {
  for(j in data2) {
    stringsim(data1[i], data2[j], method = "cosine")
  }
}
# returns the last item in each data frame for i and j


scores = list()
for(i in data2) {
  scores[[i]] <- stringsim(data1[1], data2[i], method = "cosine")
}
scores
# returns NA for each observation instead of a similarity score


for (i in 1:length(data1)) {
  stringsim(data1[i], data2[1], method = "cosine")
}
# returns the number of observations in the sample, not similarity scores

我也尝试过使用

textSimilarity
包中的
text
函数做类似的事情,但是遇到了
textEmbed
函数的问题,所以我还没有得到它来计算任何相似度分数(因此没有没有尝试循环它)。我将我在
text
包中尝试过的代码包含在内,以便更容易或更有效地实现此目的。

require("text")
data1.sub <- textEmbed(data1)
data2.sub <- textEmbed(data2)
test <- textSimilarity(data1.sub, data2.sub, method = "cosine")

我已经被困在这个问题上有一段时间了,所以任何解决这个问题的帮助将不胜感激!

r for-loop cosine-similarity stringdist
1个回答
0
投票

一般来说,for循环都会提供一个向量,然后循环遍历这个向量中的所有元素。因此,问题在于,通过编写

for(i in data1){...}
,您已经循环了
data1
的元素。 当您调用
data1[i]
时,R 在
data1
中查找具有由
data1
的第 i 个元素指定的名称的元素,在您的情况下返回
NA

您可以运行以下代码:

# create storage matrix
stringsim.mat <- matrix(NA, nrow=length(data1), ncol=length(data2))

for(i in 1:length(data1)){ #loop from first to last element in data1
  for(j in 1:length(data2)){ #loop from first to last element in data2
    stringsim.mat[i,j] <- stringsim(data1[i], data2[j], method = "cosine")
  }
}
stringsim.mat

它创建一个字符串相似度矩阵,其中

data1
中的每个元素为一行,
data2
中的每个元素为一列。然后它循环遍历两个向量中的所有元素并存储相应单元格中元素的相似性度量。

请注意,更优雅(并且可能更快)的解决方案是运行:

stringdist::stringsimmatrix(data1, data2, method = "cosine")

两者返回相同的输出。

© www.soinside.com 2019 - 2024. All rights reserved.