在下载lexisnexis报纸文章时,语料库中经常有很多重复的文章。我想删除它们,我当时想通过使用余弦相似度统计信息来删除它们,但是我不确定如何实现此目的。有任何想法吗?
答案 0 :(得分:2)
您的问题在细节上相当复杂-例如reproducible example-但这是一个有趣的问题和挑战。这样吧。
比方说,我们有一个由两套相似的文档{{(a1,a2,a3),(b1,b2)}}组成的语料库,其中字母表示相似性。我们希望只保留一个文档,而另一个文档是“重复的”,定义为相似度超过阈值,例如0.80。
我们可以使用textstat_simil()
生成相似度矩阵,然后直接从返回的dist
对象中形成成对集合,然后仅保留其中一个相似集合。
library("quanteda")
# Loading required package: quanteda
# Package version: 1.3.14
mydocs <- c(a1 = "a a a a a b b c d w g j t",
b1 = "l y y h x x x x x y y y y",
a2 = "a a a a a b c s k w i r f",
b2 = "p q w e d x x x x y y y y",
a3 = "a a a a a b b x k w i r f")
mydfm <- dfm(mydocs)
(sim <- textstat_simil(mydfm))
# a1 b1 a2 b2
# b1 -0.22203788
# a2 0.80492203 -0.23090513
# b2 -0.23427416 0.90082239 -0.28140219
# a3 0.81167608 -0.09065452 0.92242890 -0.12530944
# create a data.frame of the unique pairs and their similarities
sim_pair_names <- t(combn(docnames(mydfm), 2))
sim_pairs <- data.frame(sim_pair_names,
sim = as.numeric(sim),
stringsAsFactors = FALSE)
sim_pairs
# X1 X2 sim
# 1 a1 b1 -0.22203788
# 2 a1 a2 0.80492203
# 3 a1 b2 -0.23427416
# 4 a1 a3 0.81167608
# 5 b1 a2 -0.23090513
# 6 b1 b2 0.90082239
# 7 b1 a3 -0.09065452
# 8 a2 b2 -0.28140219
# 9 a2 a3 0.92242890
# 10 b2 a3 -0.12530944
将其设置为阈值条件,我们可以提取要删除的不幸文档的名称,并将其提供给dfm_subset()
中的逻辑条件。
# set the threshold for similarity
threshold <- 0.80
# discard one of the pair if similarity > threshold
todrop <- subset(sim_pairs, select = X1, subset = sim > threshold, drop = TRUE)
todrop
# [1] "a1" "a1" "b1" "a2"
# then subset the dfm, keeping only the "keepers"
dfm_subset(mydfm, !docnames(mydfm) %in% todrop)
# Document-feature matrix of: 2 documents, 20 features (62.5% sparse).
# 2 x 20 sparse Matrix of class "dfm"
# features
# docs a b c d w g j t l y h x s k i r f p q e
# b2 0 0 0 1 1 0 0 0 0 4 0 4 0 0 0 0 0 1 1 1
# a3 5 2 0 0 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0
针对类似文档问题的其他解决方案是按照潜在语义分析的方式将它们形成簇,或者使用主成分分析来缩小文档矩阵。
答案 1 :(得分:1)
如果您有成千上万的文档,则要在RAM中占用大量空间来保存所有相似度得分,但是可以在123
(textstat_proxy()
的基础功能)中设置最小阈值。
在此示例中,所有小于0.9的余弦相似性分数均被忽略。
textstat_simil()
有关性能差异,请参见https://koheiw.net/?p=839。
答案 2 :(得分:1)
您已经收到了一些很好的答案。但是,如果您希望针对特定用例的自动化程度更高的方法,则可以使用LexisNexisTools
包(我写过)。它带有一个名为lnt_similarity()
的函数,它可以完全满足您的需求。我写了一个关于模拟数据here的快速教程。
此处和lnt_similarity()
中解决方案之间的主要区别在于,我还考虑了单词顺序,这在极少数情况下(see this blog post)可能会产生很大的不同。
我还建议您仔细考虑阈值,否则可能会错误地删除一些文章。我包含了一个可视化两篇文章之间差异的函数,称为lnt_diff()
。您可以更好地掌握要删除的数据。