r - Cholmod 错误“问题太大”到底是什么意思?将 dfm 转换为 df 时出现问题
问题描述
这是发布的另一个问题的新版本,现在有一个可重复的示例。
我正在尝试将文档特征矩阵从 29117 Tweets 转换为 R 中的数据框,但出现错误
“asMethod(object) 中的错误:文件 ../Core/cholmod_dense.c 第 105 行的 Cholmod 错误‘问题太大’”
dfm 的大小约为 21MB,有 29117 行和 78294 个特征(推文中的单词分为 1 或 0 列,具体取决于该单词是否出现在推文中)
##generel info;
memory.size(max=TRUE)
# [1] 11418.75
sessionInfo()
# R version 3.6.1 (2019-07-05)
# Platform: x86_64-w64-mingw32/x64 (64-bit)
# Running under: Windows 10 x64 (build 18362)
##install packages, load librarys
# install.packages(c("quanteda", "devtools"))
# devtools::install_github("quanteda/quanteda.corpora")
library("quanteda")
library(RJSONIO)
library(data.table)
library(jsonlite)
library(dplyr)
library(glmnet)
##load data, convert to a dataframe, convert to a dfm
baseurl <- "https://raw.githubusercontent.com/alexlitel/congresstweets/master/data/"
d0 <- fromJSON(paste0(baseurl, "2019-10-07.json"), flatten = TRUE)
d1 <- fromJSON(paste0(baseurl, "2019-10-06.json"), flatten = TRUE)
d2 <- fromJSON(paste0(baseurl, "2019-10-05.json"), flatten = TRUE)
d3 <- fromJSON(paste0(baseurl, "2019-10-04.json"), flatten = TRUE)
d4 <- fromJSON(paste0(baseurl, "2019-10-03.json"), flatten = TRUE)
d5 <- fromJSON(paste0(baseurl, "2019-10-02.json"), flatten = TRUE)
d6 <- fromJSON(paste0(baseurl, "2019-10-01.json"), flatten = TRUE)
d7 <- fromJSON(paste0(baseurl, "2019-09-30.json"), flatten = TRUE)
d8 <- fromJSON(paste0(baseurl, "2019-09-29.json"), flatten = TRUE)
d9 <- fromJSON(paste0(baseurl, "2019-09-28.json"), flatten = TRUE)
d10 <- fromJSON(paste0(baseurl, "2019-09-27.json"), flatten = TRUE)
d11 <- fromJSON(paste0(baseurl, "2019-09-26.json"), flatten = TRUE)
d12 <- fromJSON(paste0(baseurl, "2019-09-25.json"), flatten = TRUE)
d <- rbind(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12)
rm(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12)
d$text <- as.character(d$text)
dfm <-dfm((corpus(select(d, id, text))), remove_punct=TRUE, remove=c( stopwords("english"), "t.co", "https", "rt", "amp", "http", "t.c", "can"))
dfm_df <- convert(dfm, to= 'data.frame')
#Error in asMethod(object) :
#Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 105
下面的代码适用于具有 2000 行的数据集样本(dfm (2MB) 中的 12577 个特征)。
我需要将 dfm 转换为数据框,因为我想添加变量并在二进制逻辑(套索)回归中使用它们作为源以及推文是否是转推并包含 url
d_t <- d[c(1:2000), (1:7)]
##code control variable
#url
d_t$url<- as.integer(ifelse(grepl("://", d_t$text), "1", "0"))
#source used
d_t$source_grp[grepl("Twitter for Android", d_t$source)] <- "Twitter for Android"
d_t$source_grp[grepl("Twitter Web Client", d_t$source)] <- "Twitter Web Client"
d_t$source_grp[grepl("Twitter for iPhone", d_t$source)] <- "Twitter for iPhone"
d_t$source_grp[grepl("Twitter for Windows", d_t$source)] <- "Twitter for Windows"
d_t$source_grp[grepl("Twitter for Samsung Tablets", d_t$source)] <- "Samsung Tablets"
d_t$source_grp[grepl("Twitter for Android Tablets", d_t$source)] <- "Android Tablets"
d_t$source_grp[grepl("Twitter for Windows Phone", d_t$source)] <- "Windows Phone"
d_t$source_grp[grepl("Twitter for BlackBerry", d_t$source)] <- "BlackBerry"
d_t$source_grp[grepl("Twitter for iPad", d_t$source)] <- "Twitter for iPad"
d_t$source_grp[grepl("Twitter for Mac", d_t$source)] <- "Twitter for Mac"
d_t$source_grp[is.na(d_t$source_grp)] <- "Other"
#retweet
d_t$retweet <- ifelse(grepl("RT @", d_t$text), "1", "0") #create a variable that takes the value 1 when it is a RT
##create a x and y matrix
x= model.matrix ( retweet~., cbind(select(d_t, retweet, source_grp, url), convert(dfm((corpus(select(d_t, id, text))), remove_punct=TRUE, remove=c( stopwords("english"), "t.co", "https", "rt", "amp", "http", "t.c", "can")), to="data.frame")) )[,-1]
y=d_t$retweet
lasso <- cv.glmnet(x=x, y=y, alpha=1, nfolds=5, family="binomial")
我读过其他帖子说“问题太大”错误是由于 RAM 的数量。这个数据不是很大,我尝试创建一个具有 30RAM 的虚拟机(在具有 30GB 可用空间的 64 位窗口上),但我仍然得到同样的错误。因此,我想知道是否存在问题的 RAM 量,或者 R 中数据帧中的列数是否存在限制?我可以毫无问题地将相同大小和更大的额外 DFM 添加到内存中。
这不是减少数据集并重新运行代码的解决方案,因为这已经是一个示例。我需要从从 6 mio 行数据集(如果可能)创建的 dfm 创建一个数据框(或类似的东西)
感谢任何帮助/解决方案,以及将变量添加到 dfm 的其他方法,而不将其转换为数据框。
提前致谢!
解决方案
问题是您试图将稀疏矩阵 ( dfm
) 转换为密集对象。在您的情况下,这具有以下尺寸:
> dfm
Document-feature matrix of: 29,117 documents, 78,294 features (100.0% sparse).
> prod(dim(dfm))
[1] 2279686398
或 23 亿个细胞,这就是发生错误的原因。该对象非常稀疏,这就是为什么它作为 dfm 不是问题,但是当您尝试在矩阵中记录如此多的零时会爆炸。大多数对象是空的:
> sparsity(dfm)
[1] 0.9996795
这意味着 99.97% 的单元格为零。即使您可以创建 data.frame,由于特征中极度缺乏信息,拟合 LASSO 模型也行不通。
解决方案?修剪一些特征。
这至少在我的机器上有效:
> dfmtrimmed <- dfm_trim(dfm, min_docfreq = 10, min_termfreq = 20, verbose = TRUE)
Removing features occurring:
- fewer than 20 times: 73,573
- in fewer than 10 documents: 70,697
Total features removed: 73,573 (94.0%).
> dfmtrimmed
Document-feature matrix of: 29,117 documents, 4,721 features (99.6% sparse).
> nrow(convert(dfmtrimmed, to = "data.frame"))
[1] 29117
但这仍然是 99.6% 的稀疏,因此更积极地修剪更有意义。
推荐阅读
- android - 如何将当前日期设置为标题栏中的标题?
- http - 如何从 HttpResponseWithStream 中获取 Deedle DataFrame?
- scala - Scala Play 框架:从 QueryStringBindable 访问消息
- r - R- 10 个变量的平均值乘 10 个变量
- jquery - 如何使用 Greensock 实现视差效果?
- python - 我们想在类 Node 中添加一个函数 length() 来实现用户定义的列表,它将计算列表的长度
- java - 复选框和组合框 javaFX
- sas - SAS:如何避免我的脚本中的无限循环并让它正常运行?
- javascript - 按两个数组中包含的值过滤 JSON 数组(javascript)
- function - cassandra的nosql管理器如何在数据类型为文本时搜索日期值