我正在尝试使用插入包调整' df'我的队列分析的gam模型的参数。
使用以下数据:
cohort = 1:60
age = 1:26
grid = data.frame(expand.grid(age = age, cohort = cohort))
size = data.frame(cohort = cohort, N = sample(100:150,length(cohort), replace = TRUE))
df = merge(grid, size, by = "cohort")
log_k = -3 + log(df$N) - 0.5*log(df$age) + df$cohort*(df$cohort-30)*(df$cohort-50)/20000 + runif(nrow(df),min = 0, max = 0.5)
df$conversion = rpois(nrow(df),exp(log_k))
数据说明:群组编号是潜在客户的到达时间。 N是当时到达的潜在客户的数量。转化是那些被转换为' (买了东西)。年龄是转换发生时队列的年龄(到达时间)。对于给定的群组,随着年龄的增长,转换次数会减少。这种效应遵循幂律。 但是每个群组的总转化率也可以在时间上缓慢变化(群组数量)。因此,我想在模型中使用时间变量的平滑样条曲线。
我可以从gam包中找到一个gam模型
library(gam)
fit = gam(conversion ~ log(N) + log(age) + s(cohort, df = 4), data = df, family = poisson)
fit
> Call:
> gam(formula = conversion ~ log(N) + log(age) + s(cohort, df = 4),
> family = poisson, data = df)
> Degrees of Freedom: 1559 total; 1553 Residual
> Residual Deviance: 1869.943
但是,如果我尝试使用CARET包训练模型
library(caret)
fitControl = trainControl(verboseIter = TRUE)
fit.crt = train(conversion ~ log(N) + log(age) + s(cohort,df),
data = df, method = "gamSpline",
trControl = fitControl, tune.length = 3, family = poisson)
我收到此错误:
+ Resample01: df=1
model fit failed for Resample01: df=1 Error in as.matrix(x) : object 'N' not found
- Resample01: df=1
+ Resample01: df=2
model fit failed for Resample01: df=2 Error in as.matrix(x) : object 'N' not found .....
请问有谁知道我在这里做错了吗?
由于
答案 0 :(得分:3)
您的代码有两个问题。
train
函数可能有点单调乏味,具体取决于您使用的方法(正如您所注意到的)。对于method = "gamSpline"
,train
函数会在公式中为每个独立术语添加一个平滑术语。因此,它会将您的变量转换为s(log(N), df)
,s(log(age) df)
和s(s(cohort, df), df)
。
等s(s(cohort, df), df)
没有意义。因此,您必须将s(cohort, df)
更改为cohort
。
我不确定原因,但train
method = "gamSpline"
log
并不喜欢将函数(例如s()
)放入公式中。我认为这是因为此方法已将df$N <- log(df$N)
函数应用于您的变量。通过先将日志应用于变量可以解决此问题。例如logN <- log(df$N)
或logN
并使用age
作为变量。当然,为s()
做同样的事情。
我的猜测是,您不希望此方法根据您提供的代码将平滑术语应用于所有自变量。如果可能的话,我不确定这是否可行以及如何做到这一点。
希望这有帮助。
编辑:如果你想要比我在第2点提供的解决方案更优雅的解决方案,请务必阅读@topepo的评论。如果我理解正确的话,此建议还允许您将{{1}}函数应用于您想要的变量。