我有一个包含9000个观察值和13个解释变量的数据集。
其中一些是分类变量,因此我将它们转换为虚拟对象,并始终将一个类别设置为空,因为它是基本类别。现在我已经有了53个解释变量。我想做一个岭回归,以获得样本外预测的最佳模型。为此,我想使用glmnet
包。在13个解释变量中,我想创建2-10次的多项式,并构建正常变量和所有多项式变量的所有可能的相互作用项。我也想要相互作用项的2-10次的多项式。
我的问题是glmnet
包只使用矩阵或数据帧作为参数,所以我不能使用公式。如果我试图生成一个包含所有这些变量的数据帧,我会在数据帧中得到太多的列,以至于R关闭。
我能做些什么来解决这个问题?
发布于 2018-06-25 20:08:09
您可以使用model.matrix
指定这一点。以下是使用iris
数据的示例
首先,我将创建一个具有某些级别的虚拟因子列:
df <- iris
df$factor <- as.factor(sample(1:2, nrow(iris), replace = TRUE))
head(df)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species factor
1 5.1 3.5 1.4 0.2 setosa 1
2 4.9 3.0 1.4 0.2 setosa 1
3 4.7 3.2 1.3 0.2 setosa 1
4 4.6 3.1 1.5 0.2 setosa 2
5 5.0 3.6 1.4 0.2 setosa 2
6 5.4 3.9 1.7 0.4 setosa 2
现在让模型矩阵
x <- model.matrix(Species ~ poly(Sepal.Length, 10)*factor-1, #-1 means no intercept
data = df)
ncol(x) #output is 22, do head(x) to see what the columns are
基本上,您有10列用于与第一级Sepal.Length交互的poly列+ 10列用于与第二级Sepal.Length交互的poly列+两个对应于因子变量的热列。
现在使用cv查找最好的lambda:
model <- cv.glmnet(y = iris$Species,
x = x,
alpha = 0,
family = "multinomial",
lambda.min.ratio = 1e-6) #changed it from the default since it looked the optimum is lower then the min lambda tried
plot(model)
发布于 2019-08-04 07:58:13
这不是一个完全的答案-更多的是解释为什么这是如此困难-但肯定是太长的评论。
首先,套索/脊线/弹性网方法基本上建立在模型矩阵(即每个观察值一行和每个预测变量一行的矩阵,即从输入变量派生的变量)上,因此在某些时候确实没有办法构建模型矩阵(尽管您可以分段构建,请参见下文)。
稀疏模型矩阵模型将有助于构建主要涉及因子(转换为指示器或虚拟变量)的模型矩阵,但我认为它不会对您有太大帮助。
这个math overflow question解释说,n
阶的k
变量多项式需要choose(n+k,k)
个派生变量(R术语:这是给出来自n+k
对象的k
大小的可能样本数的二项式系数)。构造一个函数,该函数报告模型矩阵的列数、元素总数(如果有r
行)和模型矩阵的总大小(以Mb为单位):
calc_size <- function(deg,nvars,r=9000) {
cc <- choose(deg+nvars,nvars)
return(c(cc,cc*r,cc*r*8/2^20))
}
calc_size(10,13,r=9000)
告诉您需要114万列、102亿个条目和77 Gb的空间来存储此问题的模型矩阵。这并不需要担心需要多少空间来扩展分类变量。如果您真的想处理53列到10阶的全数字列,则需要1.27*10^11列和of的存储空间。(对于稀疏模型矩阵较少,但组合稀疏(伪变量)和非稀疏列可能会很棘手...)
如果你真的想这样做,你也许可以使用biglasso包。vignette给出了一个从文件支持的31G数据集中拟合n= 2898,p= 1,339,511的数据集的示例。这比你的预期设置要小,但至少是相同的数量级(在4个内核上进行拟合大约需要51分钟……)如果我这样做,我会首先构建模型矩阵(可能是以小块的形式,例如一次500或1000行),并将这些块存储/连接到磁盘上的数据文件中,然后使用biglasso
来拟合模型。
然而,根据您可用的硬件和技术专业知识水平,您可能必须缩减您的目标(在C(10,53)列上使用暴力是不太可能的)。
https://stackoverflow.com/questions/51020700
复制相似问题