Cpt*_*emo 13 proxy r matrix tm
我想计算语料库作者之间的余弦距离.我们来看一个包含20个文档的语料库.
require(tm)
data("crude")
length(crude)
# [1] 20
Run Code Online (Sandbox Code Playgroud)
我想找出这20个文件中的余弦距离(相似度).我创建了一个术语 - 文档矩阵
tdm <- TermDocumentMatrix(crude,
control = list(removePunctuation = TRUE,
stopwords = TRUE))
Run Code Online (Sandbox Code Playgroud)
那么我将它转化成一个矩阵,它传递给dist()了的代理包
tdm <- as.matrix(tdm)
require(proxy)
cosine_dist_mat <- as.matrix(dist(t(tdm), method = "cosine"))
Run Code Online (Sandbox Code Playgroud)
最后我删除了余弦距离矩阵的对角线(因为我对文档与其自身之间的距离不感兴趣)并计算每个文档与语料库的另外19个文档之间的平均距离
diag(cosine_dist_mat) <- NA
cosine_dist <- apply(cosine_dist_mat, 2, mean, na.rm=TRUE)
cosine_dist
# 127 144 191 194
# 0.6728505 0.6788326 0.7808791 0.8003223
# 211 236 237 242
# 0.8218699 0.6702084 0.8752164 0.7553570
# 246 248 273 349
# 0.8205872 0.6495110 0.7064158 0.7494145
# 352 353 368 489
# 0.6972964 0.7134836 0.8352642 0.7214411
# 502 543 704 708
# 0.7294907 0.7170188 0.8522494 0.8726240
Run Code Online (Sandbox Code Playgroud)
到目前为止一直很好(有小型语料库).问题是这种方法对于较大的文档集不能很好地扩展.因为两次调用as.matrix(),将tmtdm从代码传递到代理并最终计算平均值,这似乎效率低下.
是否有可能设想一种更聪明的方法来获得相同的结果?
Num*_*ats 14
由于tm术语文档矩阵只是包中的稀疏"简单三元矩阵",因此slam可以使用其中的函数直接计算余弦相似度定义的距离:
library(slam)
cosine_dist_mat <- 1 - crossprod_simple_triplet_matrix(tdm)/(sqrt(col_sums(tdm^2) %*% t(col_sums(tdm^2))))
Run Code Online (Sandbox Code Playgroud)
这利用了稀疏矩阵乘法.在我手中,220个文档中有2963个术语,97%稀疏度的tdm只花了几秒钟.
我没有对此进行分析,所以我不知道它是否比它更快proxy::dist().
注意:这个工作,你应该不是强迫的TDM到常规基质,即不做tdm <- as.matrix(tdm).
第一.伟大的代码MAndrecPhD!但我相信他的意思是:
cosine_dist_mat <- crossprod_simple_triplet_matrix(tdm)/(sqrt(col_sums(tdm^2) %*% t(col_sums(tdm^2))))
Run Code Online (Sandbox Code Playgroud)
他编写的代码返回相异度分数.我们希望对角线上的1是余弦相似度,而不是0. https://en.wikipedia.org/wiki/Cosine_similarity.我可能会弄错,你们真的想要不同的分数,但我想我会提到它,因为我花了一点点思考才能完成.