首页 > 解决方案 > 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 的其他方法,而不将其转换为数据框。

提前致谢!

标签: rdataframememoryquantedadfm

解决方案


问题是您试图将稀疏矩阵 ( 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% 的稀疏,因此更积极地修剪更有意义。


推荐阅读