You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

quanteda中dfm_lookup出现100%稀疏性问题及函数差异咨询

关于quanteda中dfm_lookup稀疏性问题及相关函数差异解析

1. dfm_lookup出现100%稀疏性的原因

问题核心是输入dfm_lookup的DFM已经是词典聚合后的结果,而非原始词项的DFM:

  • 你先执行了dtm <- dfm(tokens(corp2), dictionary = lex),这个操作生成的DFM列是词典的topic(如cardiac、non_specific),而非原始文本中的单个词项(如pericarditis、heart)。
  • 随后用dfm_lookup(dtm, lex, valuetype = "glob")时,函数会在dtm的特征(列名)中查找词典里的关键词,但此时dtm的列名是topic名称,完全没有匹配项,因此结果全为0,显示100%稀疏。

正确的做法是给dfm_lookup传入原始词项的DFM,而非聚合后的DFM:

# 生成原始词项的DFM(未按词典聚合)
dtm_raw <- dfm(corp2)
# 对原始DFM执行词典匹配
dtm_lu <- dfm_lookup(dtm_raw, lex, valuetype = "glob")
print(dtm_lu)

2. 两个语句的核心差异

dtm <- dfm(tokens(corp2), dictionary = lex)

  • 作用:直接从tokens对象生成词典聚合后的DFM,一步完成分词到词典匹配的全流程。
  • 输入:tokens对象+词典,输出的DFM列是词典的topic分类。

dtm_lu <- dfm_lookup(dtm, lex, valuetype = "glob")

  • 作用:对已存在的DFM进行二次聚合,将DFM中匹配词典关键词的特征(列)归到对应的topic下。
  • 输入:必须是包含原始词项的DFM(而非聚合后的),否则无法匹配到关键词。

简单说:前者是"从分词直接生成聚合DFM",后者是"对已有词项DFM做词典聚合",两者适用场景不同,但最终正确执行后结果一致。

3. dfm(tokens(corp2), dictionary = lex)的运行逻辑

  1. 分词校验:接收预处理后的tokens对象corp2,遍历每个文档的词项;
  2. 词典匹配:检查每个词项是否匹配词典lex中的任意关键词(默认用valuetype = "glob"匹配规则,支持通配符);
  3. 计数聚合:将匹配到同一topic的词项计数累加,比如文档中同时出现pericarditis和heart,都会计入cardiac列的计数;
  4. 结果输出:生成以文档为行、词典topic为列的DFM,自动过滤未匹配到词典的词项。

修正后的完整示例代码

doc <- data.frame(symptoms = c("patient trouble breathing", "breathlessness", "heart palpitations", 
                              "elevated troponin", "chest tightness, pericarditis", "patient drowsy, headaches, low blood pressure", 
                              "tummy pain, vomiting", "heart attack", "edema, achypnea"))

# 创建语料库并预处理
corp <- corpus(doc, text_field = 'symptoms')
corp2 <- corp %>% 
  tokens(remove_punct = T, remove_numbers = T, remove_symbols = T) %>% 
  tokens_tolower() %>% 
  tokens_remove(stopwords('en'))

# 构建词典
terms <- structure(list(keywords = c("myocarditis", "pericarditis", "heart","heart-attack", "chest-pain", "tightness","tummy",
                                     "irritability", "vomiting", "tachypnea",   "achypnea", "tachypnoea",   
                                     "lethargy",    "drowsiness", "drowsy"),
                        topic = c("cardiac", "cardiac","cardiac", "cardiac","cardiac", "non_specific", "non_specific",
                                  "non_specific","non_specific","non_specific", "non_specific","non_specific",
                                  "children", "children","children")) ,class = "data.frame", row.names = c(NA, -15L))
lex <- split(terms$keywords, terms$topic) %>% dictionary()

# 方法1:直接从tokens生成聚合DFM
dtm <- dfm(tokens(corp2), dictionary = lex)
print(dtm)

# 方法2:先生成原始DFM,再用dfm_lookup聚合
dtm_raw <- dfm(corp2)
dtm_lu <- dfm_lookup(dtm_raw, lex, valuetype = "glob")
print(dtm_lu)

# 查看未匹配项(需传入原始DFM)
dfm_lookup(dtm_raw, lex, nomatch = "_UNMATCHED")

内容的提问来源于stack exchange,提问作者Magnetar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:50:39