Quanteda with topicmodels: removed stopwords appear in results(中文)

Quanteda with topicmodels: removed stopwords appear in results (Chinese)

我的代码:

library(quanteda)
library(topicmodels)

# Some raw text as a vector
postText <- c("普京 称 俄罗斯 未 乌克兰 施压 来自 头 条 新闻", "长期 电脑 前进 食 致癌 环球网 报道 乌克兰 学者 认为 电脑 前进 食 会 引发 癌症 等 病症 电磁 辐射 作用 电脑 旁 水 食物 会 逐渐 变质 有害 物质 累积 尽管 人体 短期 内 会 感到 适 会 渐渐 引发 出 癌症 阿尔茨海默 式 症 帕金森 症 等 兔子", "全 木 手表 乌克兰 木匠 瓦列里·达内维奇 木头 制作 手表 共计 154 手工 零部件 唯一 一个 非 木制 零件 金属 弹簧 驱动 指针 运行 其他 零部件 材料 取自 桦树 苹果树 杏树 坚果树 竹子 黄杨树 愈疮木 非洲 红木 总共 耗时 7 打造 手表 不仅 能够 正常 运行 天 时间 误差 保持 5 分钟 之内 ")

# Create a corpus of the posts
postCorpus <- corpus(postText) 

# Make a dfm, removing numbers and punctuation
myDocTermMat <- dfm(postCorpus, stem = FALSE, removeNumbers = TRUE, removeTwitter = TRUE, removePunct = TRUE)

# Estimate a LDA Topic Model 
if (require(topicmodels)) {
  myLDAfit <- LDA(convert(myDocTermMat, to = "topicmodels"), k = 2)
}

terms(myLDAfit, 11)

代码有效,我看到了结果。这是输出示例:

    Topic 1  Topic 2 
 [1,] "木"     "会"    
 [2,] "手表"   "电脑"  
 [3,] "零"     "乌克兰"
 [4,] "部件"   "前进"  
 [5,] "运行"   "食"    
 [6,] "乌克兰" "引发"  
 [7,] "内"     "癌症"  
 [8,] "全"     "等"    
 [9,] "木匠"   "症"    
[10,] "瓦"     "普"    
[11,] "列"     "京"      

问题来了。我所有的 post 都被分割(中文的必要预处理步骤)并删除了停用词。尽管如此,主题模型 returns 包含已被删除的单字符停用词的主题。如果我打开原始 .txt 文件并对给定的单字符停用词执行 ctrl-f,则不会返回任何结果。但这些术语出现在 R 代码返回的主题中,可能是因为单个字符作为其他多字符词的一部分出现。例如。就是一个被当作停用词的介词,但是成就意味着"success."

与此相关,某些术语被拆分。例如,我正在研究的事件之一包含对俄罗斯总统普京(“普京”)的引用。但是,在主题模型结果中,我看到“普”和“京”的单独术语条目,没有“普京”条目。 (请参阅输出主题 2 中的第 10 行和第 11 行,与原始文本中的第一个单词进行比较。)

这里是否有额外的标记化步骤?

编辑:修改后可重现。出于某种原因,它不会让我 post 直到我也删除了我的介绍性段落。

这是一个解决方法,基于使用更快但 "dumber" 的词标记器,基于 space ("\s") 拆分:

# fails
features(dfm(postText, verbose = FALSE))
## [1] "普"     "京"     "称"     "俄罗斯" "未"     "乌克兰" "施压"   "来自"   "头"     "条"     "新闻"  
# works
features(dfm(postText, what = "fasterword", verbose = FALSE))
## [1] "普京"   "称"     "俄罗斯" "未"     "乌克兰" "施压"   "来自"   "头"     "条"     "新闻"  

因此将 what = "fasterword" 添加到 dfm() 调用中,您将得到此结果,其中 Putin ("普京") 未拆分。

terms(myLDAfit, 11)
##      Topic 1  Topic 2         
##  [1,] "会"     "手表"          
##  [2,] "电脑"   "零部件"        
##  [3,] "乌克兰" "运行"          
##  [4,] "前进"   "乌克兰"        
##  [5,] "食"     "全"            
##  [6,] "引发"   "木"            
##  [7,] "癌症"   "木匠"          
##  [8,] "等"     "瓦列里达内维奇"
##  [9,] "症"     "木头"          
## [10,] "普京"   "制作"          
## [11,] "称"     "共计" 

这是一个有趣的案例,其中 quanteda 的默认分词器建立在 stringi 的文本边界定义之上(请参阅 stri_split_boundaries,在默认设置下不起作用。它可能会在对语言环境进行试验后使用,但这些目前不是可以传递给 quanteda::tokenize() 的选项,dfm() 会调用它。

请将此作为问题提交至 https://github.com/kbenoit/quanteda/issues,我将尝试使用 "smarter" word tokeniser 寻求更好的解决方案。