我在机器学习环境中使用一个普通的8GB服务器处理相对较小的数据集时,内存不足:
> dim(basetrainf) # 这是一个数据框 [1] 58168 118
我唯一采取的预建模步骤是将数据框转换为模型矩阵,这显著增加了内存消耗。这是因为
> lsos() Type Size PrettySize Rows Columns mergem matrix 879205616 838.5 Mb 115562 943 trainf data.frame 80613120 76.9 Mb 106944 119 inttrainf matrix 76642176 73.1 Mb 907 10387 mergef data.frame 58264784 55.6 Mb 115562 75 dfbase data.frame 48031936 45.8 Mb 54555 115 basetrainf data.frame 40369328 38.5 Mb 58168 118 df2 data.frame 34276128 32.7 Mb 54555 103 tf data.frame 33182272 31.6 Mb 54555 98 m.gbm train 20417696 19.5 Mb 16 NA res.glmnet list 14263256 13.6 Mb 4 NA
此外,由于许多R模型不支持示例权重,我必须首先对少数类进行过采样,将数据集的大小加倍(因此trainf、mergef、mergem的行数是basetrainf的两倍)。
此时,R使用1.7GB的内存,使我的总内存使用量达到了7.7GB的4.3GB。
接下来我做的事情是:
> m = train(mergem[mergef$istrain,], mergef[mergef$istrain,response], method='rf')
几秒钟后,Linux的内存不足杀手就会杀死rsession。
我可以对数据进行抽样、欠采样等,但这些都不是理想的方法。除了重写caret和我打算使用的各种模型包之外,我还应该怎么做(有何不同)?
值得一提的是,即使在没有剪枝任何因子的情况下,我也从未在其他ML软件(Weka、Orange等)中遇到过这个问题,可能是因为它们支持示例加权和“数据框”支持,在所有模型中都适用。
完整的脚本如下:
> dim(basetrainf) # 这是一个数据框 [1] 58168 118
我唯一采取的预建模步骤是将数据框转换为模型矩阵,这显著增加了内存消耗。这是因为
caret
、cor
等仅适用于(模型)矩阵。即使删除具有许多级别的因子,矩阵(mergem
如下)仍然相当大。(sparse.model.matrix
/Matrix
通常支持不好,因此我无法使用它。)> lsos() Type Size PrettySize Rows Columns mergem matrix 879205616 838.5 Mb 115562 943 trainf data.frame 80613120 76.9 Mb 106944 119 inttrainf matrix 76642176 73.1 Mb 907 10387 mergef data.frame 58264784 55.6 Mb 115562 75 dfbase data.frame 48031936 45.8 Mb 54555 115 basetrainf data.frame 40369328 38.5 Mb 58168 118 df2 data.frame 34276128 32.7 Mb 54555 103 tf data.frame 33182272 31.6 Mb 54555 98 m.gbm train 20417696 19.5 Mb 16 NA res.glmnet list 14263256 13.6 Mb 4 NA
此外,由于许多R模型不支持示例权重,我必须首先对少数类进行过采样,将数据集的大小加倍(因此trainf、mergef、mergem的行数是basetrainf的两倍)。
此时,R使用1.7GB的内存,使我的总内存使用量达到了7.7GB的4.3GB。
接下来我做的事情是:
> m = train(mergem[mergef$istrain,], mergef[mergef$istrain,response], method='rf')
几秒钟后,Linux的内存不足杀手就会杀死rsession。
我可以对数据进行抽样、欠采样等,但这些都不是理想的方法。除了重写caret和我打算使用的各种模型包之外,我还应该怎么做(有何不同)?
值得一提的是,即使在没有剪枝任何因子的情况下,我也从未在其他ML软件(Weka、Orange等)中遇到过这个问题,可能是因为它们支持示例加权和“数据框”支持,在所有模型中都适用。
完整的脚本如下:
library(caret) library(Matrix) library(doMC) registerDoMC(2)
response = 'class'
repr = 'dummy' do.impute = F
xmode = function(xs) names(which.max(table(xs)))
read.orng = function(path) { # 读取头部信息 hdr = strsplit(readLines(path, n=1), '\t') pairs = sapply(hdr, function(field) strsplit(field, '#')) names = sapply(pairs, function(pair) pair[2]) classes = sapply(pairs, function(pair) if (grepl('C', pair[1])) 'numeric' else 'factor')
# 读取数据 dfbase = read.table(path, header=T, sep='\t', quote='', col.names=names, na.strings='?', colClasses=classes, comment.char='')
# 切换响应变量,移除元数据列 df = dfbase[sapply(pairs, function(pair) !grepl('m', pair[1]) && pair[2] != 'class' || pair[2] == response)]
df }
train.and.test = function(x, y, trains, method) { m = train(x[trains,], y[trains,], method=method) ps = extractPrediction(list(m), testX=x[!trains,], testY=y[!trains,]) perf = postResample(ps$pred, ps$obs) list(m=m, ps=ps, perf=perf) }
# 函数:稀疏相关系数 sparse.cor = function(x){ memory.limit(size=10000) n = dim(x)[2] D = dist(t(x), method="cor") hc = hclust(D) groups = cutree(hc, k=round(n/10)) cor.groups = matrix(0, nrow=n, ncol=n) for (i in 1:max(groups)) { members = which(groups == i) if (length(members) > 1) { cors = cor(x[,members]) cor.groups[members, members] = cors } } cor.groups }
# 函数:移除低方差的预测变量 print('remove low variance predictors') mergef = read.orng('data/orng.tab') mergef = mergef[, -which(sapply(mergef, is.numeric) && apply(mergef, 2, sd) < .01)]
# 函数:移除高相关性的预测变量 print('remove high-correlation predictors') merge.cor = (if (repr == 'sparse') sparse.cor else cor)(mergef) mergef = mergef[, -findCorrelation(merge.cor, cutoff=.75)]
# 函数:尝试不同的方法 do.method = function(method) { train.and.test(mergem, mergef[response], mergef$istrain, method) } res.gbm = do.method('gbm') res.glmnet = do.method('glmnet') res.rf = do.method('parRF')
caret
相对较快地评估一个350,000 x 30数据框的3x3x3参数网格。当并行运行时(每个核心使用的内存过多),这会使我的8GB四核MacBook Pro崩溃,但昨天我发现它在亚马逊的高内存双倍超大实例上运行非常快(http://aws.amazon.com/ec2/instance-types/ @ 约0.42美元/小时作为竞价实例)。 - lockedoff