2014-09-19 90 views
0

簡短問題:是否可以在caretSBF $分數函數中使用矩陣式操作?插圖:使用矩陣式操作定製特徵選擇

動機:當在R中使用大矩陣時,在矩陣方式下工作的操作[例如, rowMeans(X)]通常比一行一行的方法快得多[例如,適用(X,1,平均值)]。這裏是一個基準例如,使用矩陣與一百萬行和100列:

rows = 1000000 
cols = 100 
X <- matrix(rnorm(rows*cols),nrow = rows) 

ptm <- proc.time() 
tt <- apply(X, 1, function(x) { t.test(x[1:50],x[51:100], var.equal = FALSE)$p.value }) 
proc.time() - ptm 
# user system elapsed 
# 312.420 0.685 313.633 

library(genefilter) 
ptm <- proc.time() 
ftt <- rowFtests(X, fac = factor(c(rep(0,50), rep(1,50))), var.equal=FALSE) 
proc.time() - ptm 
# user system elapsed 
# 21.400 1.336 23.257 

詳細信息:在插入符包,得分濾波器的caretSBF功能可以用於選擇用於交叉特徵驗證建模。我想使用自定義得分函數來代替caretSBF $分數(這一部分我可以做),但我希望它是矩陣式的(就像上面 - 這一部分我不能這樣做)。當我第一次看到這些功能時,我看不出明顯的原因,爲什麼這樣做不起作用。我想要做這樣的事情:

mySBF$score <- function(x, y) { 
    genefilter::rowFtests(x, fac = y)$p.value 
} 

代替默認的:

$score 
function (x, y) 
{ 
    if (is.factor(y)) 
     anovaScores(x, y) 
    else gamScores(x, y) 
} 
<environment: namespace:caret> 

但我不能使它發揮作用。 caretSBF不支持基於矩陣的操作嗎?

回答

2

矩陣式操作是否僅僅由caretSBF不支持?

不,不是真的。 score函數一次只能用於一個預測器。

但是,您可以使用train中的自定義模型到達那裏。 Here是一個在建模之前進行特徵提取的例子。您可以使用多變量過濾器進行調整,並使用該子集來擬合模型。這是一個非常糟糕的例子:

> library(caret) 
> set.seed(1) 
> training <- LPH07_1(200) 
> 
> crappy <- getModelInfo("lm", regex = FALSE)[[1]] 
> crappy$fit <- function (x, y, wts, param, lev, last, classProbs, ...) { 
+ dat <- if (is.data.frame(x)) x else as.data.frame(x) 
+ ## randomly filter all but 3 predictors 
+ dat <- dat[, sample(1:ncol(dat), 3)] 
+ dat$.outcome <- y 
+ lm(.outcome ~ ., data = dat, ...) 
+ } 
> crappy$predict <- function (modelFit, newdata, submodels = NULL) { 
+ if (!is.data.frame(newdata)) 
+  newdata <- as.data.frame(newdata) 
    ## make sure to apply the subsetting part here too 
+ predict(modelFit, newdata[, predictors(modelFit$terms)]) 
+ } 
> 
> 
> mod <- train(y ~ ., data = training, 
+    method = crappy) 
> mod 
Linear Regression 

200 samples 
10 predictor 

No pre-processing 
Resampling: Bootstrapped (25 reps) 

Summary of sample sizes: 200, 200, 200, 200, 200, 200, ... 

Resampling results 

    RMSE Rsquared RMSE SD Rsquared SD 
    3.08 0.077  0.258 0.0864  


> predictors(mod) 
[1] "Var08" "Var03" "Var04" 

最大

+0

謝謝蹩腳的例子:)我喜歡這個建議的解決方法。但是我很難讓它爲glmnet模型工作。使用newdata [,predictors(modelFit $ terms)]無法使用預測中的子集,但是如果我做newdata [,rownames(modelFit $ beta)],它確實有效 - 但如果我在trainControl中設置classProbs = TRUE 。任何想法是什麼?我將用更新的示例編輯我的問題。 – Owen 2014-09-23 22:45:08

+0

這表明SBF的在線文檔不正確?它表示:「[分數]函數分別作爲輸入預測變量和結果,分別稱爲x和y。輸出應該是一個**命名的向量**,其中的名稱對應於x的列名。 「這使得它聽起來像x必須是矩陣 - 因爲該函數還能如何輸出一個分數向量?幫助(sbfControl)有類似的語言。 – Owen 2014-09-25 20:46:57