#What are the minimum specifications needed to #a) massage an ExpressionSet+formula+parms model spec #into input to an arbitrary machine learning function #in some R package #b) massage the output of an arbitrary machine learning #function in some R package into an MLOutput instance # library(MLInterfaces) library(MASS) data(crabs) setClass("MLIschema", representation( mlpackageName="character", mlfunctionName="character", usesFormula="logical", retObjectBuilder="function", predictMethodName="character", predictParms="list", tuningParms="list")) classifOutBuilder = function(mlfunctionName, rans, call, ...) { new("classifOutput", method=mlfunctionName, predLabels= newPredClass(do.call(predictMethodName, list(rans, ...))), call=call, RObject=rans) } makeMLIschema = function( mlpackageName, mlfunctionName, usesFormula, predictMethodName, predictParms=list(), retObjectBuilder=NULL, ... ) { extra = list(...) # cc = match.call() # ars = cc[-1] # opt = ars[-c(1:4)] # anames = names(ars) # if (!("predictParms" %in% names(anames))) predictParms=list() if (missing(predictParms)) predictParms=list() if (is.null(retObjectBuilder)) { retObjectBuilder=function(mlfunctionName, rans, call, ...) { new("MLOutput", method=mlfunctionName, RObject=rans, call=call, distMat=as.dist(matrix(0,1,1))) }} new("MLIschema", mlpackageName=mlpackageName, mlfunctionName=mlfunctionName, usesFormula=usesFormula, predictMethodName=predictMethodName, retObjectBuilder=retObjectBuilder, predictParms=predictParms, tuningParms=extra) } setMethod("MLearn", c("formula", "data.frame", "MLIschema" , "numeric"), function( formula, data, method, trainInd, mlSpecials = NULL) { # # step 1 -- get the function to be called from the schema object # learnFunNm = paste(method@mlpackageName, method@mlfunctionName, sep="::") if (method@usesFormula==FALSE) stop("method does not accept formula") # # can't just use do.call("nnet::nnet" ... it seems; instead, build # the function using an initial call to resolution operator # thefun = do.call("::", list(method@mlpackageName, method@mlfunctionName)) # # step 2 -- now build the parms to the call # callParms = list(formula=formula, data=data[trainInd,]) if (length(method@tuningParms)>0) { pn = names(method@tuningParms) for (i in 1:length(pn)) callParms[[pn[i]]] = method@tuningParms[[i]] } # # step 3 -- execute and get the original object # RANS = do.call( thefun, callParms ) # # step 4 -- transform value to something we can work with # # new("MLOutput", method=learnFunNm, distMat=as.dist(as.matrix(0,1,1)), # RObject=RANS, call=match.call()) method@retObjectBuilder(learnFunNm, RANS, call=match.call()) }) randomForestI = function(...) makeMLIschema( "randomForest", "randomForest", TRUE, "predict", predictParms=list(), ... ) #debugMethod("MLearn", c("formula", "data.frame", # "MLIschema" , "numeric")) d1 = MLearn(sp~CW, crabs, randomForestI(), c(1:40,101:140) ) #d2 = MLearn(sp~CW, crabs, randomForestI(ntree=20) , c(1:40,101:140))