如何用quanteda实现文本匹配率(ratio of matches)计算?
在quanteda中实现文本匹配率(ratio of matches)计算
问题说明
研究立法文本复用场景中,需要评估不同版本法案草案的文本复用率。Jaccard相似度(交集/并集)因分母随文档组合变化,无法直接体现“原始文本中保留的复用比例”,因此需要实现匹配率(ratio of matches)——以其中一个文档的词元集合/总词数为分母,计算重叠内容的占比。
核心思路
匹配率分为两种计算模式:
- 集合模式:基于独特词元(types),计算参考文档中与目标文档重叠的独特词元占参考文档总独特词元的比例。
- 词袋模式:基于词元出现次数(tokens),计算参考文档中与目标文档重叠的词元总次数占参考文档总词元数的比例。
以下是基于quanteda的具体实现:
代码实现
1. 预处理文本
library(quanteda) library(dplyr) # 原始文本示例 a <- paste("How does it feel, how does it feel?", "To be without a home", "Like a complete unknown, like a rolling stone") b <- paste("How does it feel, how does it feel?", "To be on your own, with no direction home", "A complete unknown, like a rolling stone") # 创建语料库并分词(去标点、转小写) toks <- tibble(texto = c(a, b), id = c("a", "b")) %>% corpus(text_field = "texto", docid_field = "id") %>% tokens(remove_punct = TRUE) %>% tokens_tolower() # 转换为文档特征矩阵(DFM) dfm_obj <- dfm(toks)
2. 集合模式匹配率
计算逻辑:(参考文档与目标文档的共同独特词元数) / (参考文档的独特词元总数)
# 获取每个文档的独特词元数 type_counts <- nfeat(dfm_obj) names(type_counts) <- docnames(dfm_obj) # 计算文档间的共同独特词元数 common_types <- dfm_obj %>% textstat_simil(method = "simple", margin = "documents") %>% as.matrix() # 示例:a相对于b的匹配率 ratio_set_a_to_b <- common_types["a", "b"] / type_counts["a"] cat("集合模式:a相对于b的匹配率 =", ratio_set_a_to_b, "\n") # 输出约0.9286 # 示例:b相对于a的匹配率 ratio_set_b_to_a <- common_types["b", "a"] / type_counts["b"] cat("集合模式:b相对于a的匹配率 =", ratio_set_b_to_a, "\n") # 输出约0.6842
3. 词袋模式匹配率
计算逻辑:(参考文档与目标文档中共同词元的最小计数之和) / (参考文档的总词元数)
# 获取每个文档的总词元数 token_counts <- rowSums(dfm_obj) names(token_counts) <- docnames(dfm_obj) # 提取两个文档的词频向量 a_counts <- as.numeric(dfm_obj["a", ]) b_counts <- as.numeric(dfm_obj["b", ]) # 找到共同词元的索引 common_idx <- which(a_counts > 0 & b_counts > 0) # 计算共同词元的最小计数之和 sum_min_counts <- sum(pmin(a_counts[common_idx], b_counts[common_idx])) # 示例:a相对于b的匹配率 ratio_bag_a_to_b <- sum_min_counts / token_counts["a"] cat("词袋模式:a相对于b的匹配率 =", ratio_bag_a_to_b, "\n") # 输出约0.8095 # 示例:b相对于a的匹配率 ratio_bag_b_to_a <- sum_min_counts / token_counts["b"] cat("词袋模式:b相对于a的匹配率 =", ratio_bag_b_to_a, "\n") # 输出约0.7391
关键说明
- 之前的错误在于使用
tokens_keep后计算Jaccard相似度,Jaccard的分母是并集,而非参考文档的词元数,因此无法得到目标匹配率。 - 集合模式适合关注独特内容的复用比例,词袋模式适合关注整体文本内容的复用比例(考虑重复表述)。
内容的提问来源于stack exchange,提问作者Matías Eyzaguirre Miranda
相关产品推荐
相关产品推荐

