可能重复:
在 R 中查找余弦相似度
我在 R 中有一个类似于这个的大表。我想找到每个项目之间的余弦相似度,例如对 (91, 93), (91, 99), (91, 100) ... (101, 125)。最终输出应该是
No_1 No_2 Similarity
...
6518 6763 0.974
…
桌子看起来像这样。
No_ Product.Group.Code R1 R2 R3 R4 S1 S2 S3 U1 U2 U3 U4 U6
91 65418 164 0.68 0.70 0.50 0.59 NA NA 0.96 NA 0.68 NA NA NA
93 57142 164 NA 0.94 NA NA 0.83 NA NA 0.54 NA NA NA NA
99 66740 164 0.68 0.68 0.74 NA 0.63 0.68 0.72 NA NA NA NA NA
100 76712 164 0.54 0.54 0.40 NA 0.39 0.39 0.39 0.50 NA 0.50 NA NA
101 56463 164 0.67 0.67 0.76 NA NA 0.76 0.76 0.54 NA NA NA NA
125 11713 164 NA NA NA NA NA 0.88 NA NA NA NA NA NA
因为有些行有NA
,所以我编写了一些辅助函数来仅比较两行都不为 NA 的列。
compareNA <- function(v1,v2) {
same <- (!is.na(v1) & !is.na(v2))
same[is.na(same)] <- FALSE
return(same)
}
selectTRUE <- function(v1, truth) {
# This function selects only the variables which correspond to the truth vector
# being true.
for (colname in colnames(v1)) {
if( !truth[ ,colname] ) {
v1[colname] <- NULL
}
}
return(v1)
}
trimAndTuck <- function(v1){
# Turns list into vector and removes first two columns
return (unlist(v1, use.names = FALSE)[-(1:2)])
}
cosineSimilarity <- function(v1, v2) {
truth <- compareNA(v1, v2)
return (cosine(
trimAndTuck(selectTRUE(v1, truth)),
trimAndTuck(selectTRUE(v2, truth))
))
}
allPairs <- function(df){
for ( i in 1:length(df)) {
for (j in 1:length(df)) {
print( cosineSimilarity(df[i,], df[j,]) )
}
}
}
跑步allpairs
确实给了我正确的答案,但它是在一系列 1x1 向量中这样做的。我很清楚我所写的内容可能是对功能之神的侮辱,但我不知道该怎么写。
如何重写(矢量化?)以便它以正确的格式返回数据?
编辑:我正在使用作为 LSA 包一部分的余弦函数。这是关于使用余弦函数处理 NA 值,而不是如何计算标准余弦相似度。