I am trying to use the hmeasure metric Hand,2009 as my custom metric for training SVMs in caret. As I am relatively new to using R, I tried adapt the twoClassSummary function. A
This code works. I m posting a solution in case anyone else wants to use/improve upon this. The problems were caused by incorrect referencing of the Hmeasure object and a typo/comment on the returned value of the function.
library(caret)
library(doMC)
library(hmeasure)
library(mlbench)
set.seed(825)
registerDoMC(cores = 4)
data(Sonar)
table(Sonar$Class)
inTraining <- createDataPartition(Sonar$Class, p = 0.5, list = FALSE)
training <- Sonar[inTraining, ]
testing <- Sonar[-inTraining, ]
hmeasureCaret<-function (data, lev = NULL, model = NULL,...)
{
# adaptation of twoClassSummary
require(hmeasure)
if (!all(levels(data[, "pred"]) == levels(data[, "obs"])))
stop("levels of observed and predicted data do not match")
hObject <- try(hmeasure::HMeasure(data$obs, data[, lev[1]]),silent=TRUE)
hmeasH <- if (class(hObject)[1] == "try-error") {
NA
} else {hObject$metrics[[1]] #hObject$metrics[c('H')] returns a dataframe, need to return a vector
}
out<-hmeasH
names(out) <- c("Hmeas")
out
}
#environment(hmeasureCaret) <- asNamespace('caret')
ctrl <- trainControl(method = "repeatedcv",number = 10, repeats = 5, summaryFunction = hmeasureCaret,classProbs=TRUE,allowParallel = TRUE,
verboseIter=FALSE,returnData=FALSE,savePredictions=FALSE)
set.seed(123)
svmTune <- train(Class ~ ., data = training,method = "svmRadial",trControl = ctrl,preProc = c("center", "scale"),tuneLength = 15,metric="Hmeas",
verbose = FALSE)
svmTune
predictedProbs <- predict(svmTune, newdata = testing , type = "prob")
true.class<-testing$Class
hmeas.check<- HMeasure(true.class,predictedProbs[,2])
summary(hmeas.check)