R语言使用dfm_subset删空行后匹配原推文数据集及内存不足问题问询
可行解决方案
核心逻辑:不需要转成稠密矩阵计算行和,直接使用对应包的原生稀疏矩阵统计函数获取非空行索引,同时过滤dfm和原数据集即可保证二者一一对应。
方案1:基于当前使用的quanteda框架(最优)
你代码中已经用到的ntoken()函数本身就是直接统计dfm每行的有效token数,完全不会触发稠密矩阵转换,内存占用极低。
你只需要调整原有代码的顺序,先保存非空行的索引再做过滤即可:
# 原有生成edsdfm的代码保持不变 corpus_tweets <- corpus(mydata$text) corpus_tweets <- iconv(corpus_tweets,"UTF-8","latin1",sub="") # 去除表情、换行符 corpus_tweets <- gsub("#\\w+", "", corpus_tweets) # 去除话题标签 corpus_tweets <- gsub("[[:punct:]]", "", corpus_tweets) # 去除标点 corpus_tweets <- gsub("[[:digit:]]", "", corpus_tweets) # 去除数字 corpus_tweets <- gsub("^\\s+|\\s+$", "", corpus_tweets) corpus_tweets <- tolower(corpus_tweets) corpus_tweets <- removeWords(corpus_tweets , stopwords("spanish")) edsdfm <- tokens(corpus_tweets, remove_punct = T, remove_numbers = T, remove_url = T, remove_symbols = T) %>% tokens_ngrams(n = 1:2) %>% dfm() # 新增:先统计非空行索引,该操作仅读取稀疏矩阵的内置属性,无额外内存开销 non_empty_idx <- ntoken(edsdfm) > 0 # 同步过滤dfm和原数据框,二者行数完全对应 edsdfm_filtered <- dfm_subset(edsdfm, non_empty_idx) mydata_filtered <- mydata[non_empty_idx, ]
后续你用edsdfm_filtered跑LDA得到的结果,直接对应mydata_filtered里的每一条推文,不会出现错位问题。
方案2:如果使用tm包的DocumentTermMatrix格式
如果后续切换到tm包的DTM格式,也不要用apply计算行和,调用slam包的row_sums函数即可,它专门针对稀疏矩阵设计,不会转成稠密矩阵:
library(slam) # 仅统计非零元素的和,内存占用极低 row_totals <- row_sums(dtm) non_empty_idx <- row_totals > 0 # 同步过滤 dtm_filtered <- dtm[non_empty_idx, ] mydata_filtered <- mydata[non_empty_idx, ]
原错误原因说明
之前运行报错是因为apply处理稀疏矩阵时,会强制把整个稀疏矩阵转换成普通的稠密矩阵,文本类稀疏矩阵的稠密化会让内存占用暴涨几十到上百倍,才会出现需要分配14.9G内存的错误,用对应框架的原生稀疏矩阵操作函数就可以完全规避这个问题。
内容的提问来源于stack exchange,提问作者Javier Sacristán
相关产品推荐
相关产品推荐

