如何用quanteda基于自定义数值词典计算文档NetSentScore(大语料适配)
问题描述
基于关联词语与数值情感得分的自定义词典,计算每个文档的NetSentScore,公式为:NetSentScore(单文档)= 正词得分总和 + 负词得分总和。已定义词典ScoreDict并将语料处理为dfm,但语料规模极大(超50万文档、约800个特征),转换为数据框会导致内存溢出,需要基于quanteda的高效解决方案。
词典与语料示例:
# 自定义得分词典 ScoreDict <- tibble::tibble( score= c(-5,-9,1,8,9,-10), word = c("bad", "horrible", "open","awesome","gorgeous","trash") ) # 示例语料 text <- c("this is a bad movie very bad","horrible movie, just awful","im open to new dreams", "awesome place i loved it","she is gorgeous","that is trash") # 处理后的dfm dfm_obj <- text %>% corpus() %>% tokens(remove_punct = TRUE) %>% tokens_remove(stopwords("en")) %>% dfm()
示例计算:text1中"bad"出现2次,对应得分-5,NetSentScore为2*-5 = -10。
解决方案
利用quanteda的稀疏矩阵特性,直接通过特征匹配与矩阵乘法计算,无需转换为数据框,内存效率极高:
- 将词典转换为命名得分向量,方便与dfm特征匹配:
# 构建命名得分向量,名称为词语,值为对应得分 score_vec <- ScoreDict$score names(score_vec) <- ScoreDict$word
- 生成与dfm特征完全匹配的得分向量:
对dfm的每个特征,若存在于词典中则取对应得分,否则设为0(不影响最终得分):
# 获取dfm的所有特征名称 feat_names <- featnames(dfm_obj) # 匹配得分,无匹配项设为0 match_score <- ifelse(feat_names %in% names(score_vec), score_vec[feat_names], 0)
- 计算每个文档的NetSentScore:
通过稀疏矩阵乘法直接计算,quanteda会自动优化稀疏矩阵的运算效率:
# 矩阵乘法得到每个文档的得分 netsent_score <- dfm_obj %*% match_score # 转换为易读的向量格式(可选) netsent_score <- as.vector(netsent_score) names(netsent_score) <- docnames(dfm_obj)
结果验证
运行上述代码后,示例语料的得分结果为:
text1 text2 text3 text4 text5 text6 -10 -9 1 8 9 -10
与预期完全一致。
优势说明
- 全程基于quanteda的稀疏矩阵操作,无需转换为密集数据框,内存占用极低,适合处理超大规模语料;
- 矩阵乘法是向量化运算,计算速度远快于循环或逐行处理;
- 代码简洁,完全兼容quanteda的工作流,无需额外依赖。
内容的提问来源于stack exchange,提问作者R_Student
相关产品推荐
相关产品推荐

