【问题标题】:Tuning the classification threshold in mlr在 mlr 中调整分类阈值
【发布时间】:2019-07-06 00:27:19
【问题描述】:

我正在使用 mlr 包训练朴素贝叶斯模型。

我想调整分类的阈值(阈值)。 tutorial 提供了这样做的示例,同时还在嵌套的 CV 设置中进行了额外的超参数调整。 我实际上不想在找到最佳阈值时调整任何其他(超)参数。

基于here 的讨论,我设置了一个 makeTuneWrapper() 对象并将另一个参数 (laplace) 设置为固定值 (1),然后在嵌套的 CV 设置中运行 resample()。

nbayes.lrn <- makeLearner("classif.naiveBayes", predict.type = "prob")
nbayes.lrn

nbayes.pst <- makeParamSet(makeDiscreteParam("laplace", value = 1))
nbayes.tcg <- makeTuneControlGrid(tune.threshold = TRUE)
# Inner 
rsmp.cv5.desc<-makeResampleDesc("CV", iters=5, stratify=TRUE)
nbayes.lrn<- makeTuneWrapper(nbayes.lrn, par.set=nbayes.pst, control=nbayes.tcg, resampling=rsmp.cv5.desc, measures=tpr) 
# Outer 
rsmp.cv10.desc<-makeResampleDesc("CV", iters=10, stratify=TRUE)
nbayes.res<-resample(nbayes.lrn, beispiel3.tsk, resampling= rsmp.cv10.desc, measures=list(tpr,ppv), extract=getTuneResult)

print(nbayes.res$extract)

为嵌套 CV 中的内部循环设置重采样方案似乎是多余的。无论如何,对tuneThreshold() 的内部调用显然做了更彻底的优化。但是,在没有重采样方案的情况下调用 makeTuneWrapper() 会导致错误消息。

我有两个具体的问题

1.) 有没有更简单的方法来调整阈值(并且只有阈值)?

2.) 鉴于上述设置:如何访问实际测试的阈值?

编辑:

这将是一个代码示例,用于根据@Lars Kotthoff 的回答调整不同度量(准确度、灵敏度、精度)的阈值。

### Create fake data
y<-c(rep(0,500), rep(1,500))
x<-c(rep(0, 300), rep(1,200), rep(0,100), rep(1,400))
balanced.df<-data.frame(y=y, x=x)
balanced.df$y<-as.factor(balanced.df$y)
balanced.df$x<-as.factor(balanced.df$x)
balanced.tsk<-makeClassifTask(data=balanced.df, target="y",   positive="1")
summarizeColumns(balanced.tsk)

### TuneThreshold
logreg.lrn<-makeLearner("classif.logreg", predict.type="prob")
logreg.mod<-train(logreg.lrn, balanced.tsk)
logreg.preds<-predict(logreg.mod, balanced.tsk)
threshold_tpr<-tuneThreshold(logreg.preds, measure=list(tpr))
threshold_tpr
threshold_acc<-tuneThreshold(logreg.preds, measure=list(acc))
threshold_acc
threshold_ppv<-tuneThreshold(logreg.preds, measure=list(ppv))
threshold_ppv

【问题讨论】:

    标签: machine-learning classification threshold mlr


    【解决方案1】:

    你可以直接使用tuneThreshold()

    require(mlr)
    
    iris.model = train(makeLearner("classif.naiveBayes", predict.type = "prob"), iris.task)
    iris.preds = predict(iris.model, iris.task)
    
    res = tuneThreshold(iris.preds)
    
    

    很遗憾,您无法访问使用tuneThreshold() 时测试的阈值。但是,您可以将阈值视为“正常”超参数并使用 mlr 中的任何调整方法。这将允许您获得值和相应的性能。

    【讨论】:

    • 谢谢,很有帮助!
    • 不确定如何将阈值视为正常的超参数。对于 Naive Bayes 或逻辑回归等学习器,阈值未列为可调参数。由于 tuneThreshold() 的结果使用“th”作为阈值,我简单地尝试了一下。'makeParamSet(makeDiscreteParam("th", values=seq(from=0.05, to=0.95, by=0.05)))' 但是采用正常的当使用 'tuneParams("classif.logreg", task=balanced.tsk, resampling=rsmp.holdout.desc, par.set=param_set, control=tune_ctrl_grid)' 调用 tuneParams() 时,教程中的过程会导致错误。
    • 您可能必须将学习者包装在“学习者”中,以便您将阈值设置为参数。不幸的是,这并不简单。
    • 嗨@LarsKotthoff,感谢您的发帖。我有一个关于tuneThreshold 的问题:stats.stackexchange.com/q/446362/127926。这是关于通过makeTuneControlRandom(..., tune.threshold = TRUE) 与学习器参数一起调整它与通过tuneThreshold(r$pred) 直接使用它之间的区别。请问可以看一下吗?
    猜你喜欢
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多