2016-07-25 34 views
2

我正在嘗試使用插入程序包來調整gam模型的'df'參數以用於我的羣組分析。在R Poisson迴歸中使用CARET和GAM(「gamSpline」方法)

數據如下:

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 

但如果我嘗試使用插入符號包訓練模型

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 ..... 

請問有誰知道我在做什麼錯在這裏?

謝謝

回答

3

你的代碼有兩個錯誤。

  1. 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

  2. 我不知道爲什麼,但trainmethod = "gamSpline"不喜歡它,當你把公式中的函數(例如log)。我認爲這是由於這種方法已經將s()函數應用於您的變量。通過將日誌提前應用於變量可以解決此問題。如df$N <- log(df$N)logN <- log(df$N),並使用logN作爲變量。當然,對於age也是這樣。

我的猜測是,你不希望這種方法來平滑項適用於根據您所提供的代碼,所有的獨立變量。如果可能,我不確定這是否可行,以及如何去做。

希望這會有所幫助。

編輯:如果你想要比我在第2點提供的更優雅的解決方案,請務必閱讀@topepo的評論。如果我理解正確,這個建議還允許你將s()函數應用到你想要的變量。

+1

該問題與公式如何從R函數傳遞給R函數有關。 MarcelG是正確的,你需要使用[自定義模型](http://topepo.github.io/caret/custom_models.html#Illustration3)來做你想做的事情。 – topepo

+0

非常感謝!第2點很奇怪,但可以很容易地修復。另一方面,第1點是我認爲改進方法的好主意!再次感謝!在閱讀Topepo的評論之前,我發表了評論。謝謝你的評論 –

+0

@NickMars沒問題的隊友。如果您的問題已完全解答,請隨時接受答案:) – Marcel10