-1

我正在寻找一个包或“最佳实践”方法来使用高斯(RBF)内核为一类 SVM 自动选择超参数。我目前正在 R 中实现 libsvm 的一类 svm,因此最好采用一种结合它的方法,或者至少,R 是最好的。


编辑

只是为了给我正在寻找的一个更清楚的例子,假设我们有 iris 数据集,我们将其中一种类型作为正例。一种方法是构建一个具有不同选择的 nu 和 gamma 的一类 SVM,然后针对否定情况(其他花卉类型)验证模型的准确性。见下文:

library(datasets)
library(data.table)
library(e1071)
#load the iris data
data(iris)
#separate positive and negative cases
positive_cases <- iris[iris$Species=="virginica",1:4]
negative_cases <- iris[iris$Species!="virginica",1:4]
#get hyperparameter choices
hyp_param_choices <- setDT(expand.grid("nu"=seq(.1,.3,by=.1),
                                       "gamma"=1*10^seq(-2, 2, by=1)))
hyp_param_choices[,err:=0]

for(hyp_i in 1L:nrow(hyp_param_choices)){
  tuned <- svm(x=positive_cases, 
               y=rep(T,nrow(positive_cases)), #True as they are all in the positive class
               nu =  hyp_param_choices[hyp_i,nu],
               gamma = hyp_param_choices[hyp_i,gamma],
               type='one-classification',
               scale=T #scale the data
  )
  svm_neg_pred <- predict(tuned, #predict the negative classes, should all be false
                          negative_cases)
  #error is sum of svm_neg_pred as this counts all the positives .i.e false positive cases divided by total number of negatives
  set(hyp_param_choices, i=hyp_i, j="err", value=(sum(svm_neg_pred)/nrow(negative_cases)))
}
setorder(hyp_param_choices,err)
print(hyp_param_choices)
     nu gamma  err
 1: 0.1 1e+00 0.00
 2: 0.2 1e+00 0.00
 3: 0.3 1e+00 0.00
 4: 0.1 1e+01 0.00
 5: 0.2 1e+01 0.00
 6: 0.3 1e+01 0.00
 7: 0.1 1e+02 0.00
 8: 0.2 1e+02 0.00
 9: 0.3 1e+02 0.00
10: 0.3 1e-02 0.01
11: 0.2 1e-01 0.01
12: 0.2 1e-02 0.02
13: 0.3 1e-01 0.02
14: 0.1 1e-01 0.03
15: 0.1 1e-02 0.05

现在实际上,我的问题在训练数据中有一些误报。我们可以通过将负样本添加到正样本中并将这些负样本从验证测试中排除然后重新运行来将其合并到示例中:

positive_cases <- rbind(iris[iris$Species=="virginica",1:4],
                        iris[iris$Species!="virginica",1:4][sample(nrow(iris[iris$Species!="virginica",]), 
                                                                   10),])

我正在寻找另一种方法来选择论文中最好的一类超参数,或者其他有理由成为一种好方法的方法。


为了提供一些背景知识,我知道Scholkopf 等人对一类 SVM 的原始实现。并理解该方法的目的是将一类数据映射到与内核对应的特征空间,并使用超平面以最大边距将它们与原点分离。在这个意义上,起源可以被认为是所有其他类。我也知道Tax & Duin推出的 SVDD. 这里的目的是创建尽可能小的数据封闭球体。通过这种方法,球外的所有点都是其他类/异常值。我也知道这两种方法在使用高斯核时会推导出等效的最小化函数。这两种方法都使用软边距,也允许在一类中错误分类案例。由于它们是等效的,我将只讨论 OC-SVM,但使用 SVDD 作为答案的方法也将不胜感激!

所以在我的问题中,我的一类是正例,我想针对误分类例(误报)和伽玛(高斯核的宽度)的比例优化 nu。在我的问题中,我知道会有误报,这是问题的本质,无法检测到。我还想在不同的数据集上应用多个 OC-SVM,因此我需要一种自动方法来根据相关数据集中存在的异常值的比例和数据的潜在特征来调整 nu 和 gamma。

由于这个问题本质上是无监督的,因此我显然不能以正常方式使用 CV,其范围为 nu 和 gamma,因为然后将选择与原点距离最小的解决方案。只是要注意我确实有负面案例,但如果可能的话,我宁愿在验证步骤中阻止它们,好像根本不需要使用一类方法,为什么不使用普通的二类分类方法?

我的问题是是否有人找到了在 R 中执行此操作的包或方法?我知道科学文献中有很多方法,包括非常有前途的方法:DTL这里,但这些似乎没有可用的代码,除非伪代码以及如何将其转换为 R 并将其与 libsvm 结合,例如,似乎很大为我目前的能力迈出一步。

任何帮助或建议将不胜感激!

4

1 回答 1

0

你的问题是关于svm实施的。在这里,我为svm以下RBF上下文提供了一个草图。这篇文章中的实现使用caret并且方法取自kernlab包。接下来是一个使用多项式iris数据集的示例。Species我勾勒了训练方面的草图,但测试方面可以很容易地使用predict()来自相同caret或多类 auroc 的测试集和混淆矩阵来完成。

该方法还考虑了交叉验证cv=10

#Some libraries
library(rsample)
library(caret)
library(visdat)
library(recipes)
#Data
data(iris)
# Create training (70%) and test (30%) sets
set.seed(123)
split_strat <- initial_split(iris, prop = 0.7,
                             strata = 'Species')
train_strat <- training(split_strat)
test_strat <- testing(split_strat)

#Tuning a SVM model

# Tune an SVM with radial basis kernel
set.seed(1854) # for reproducibility
model_svm <- caret::train(
  Species ~ .,
  data = train_strat,
  method = "svmRadial",
  trControl = trainControl(method = "cv", number = 10),
  tuneLength = 10
)

# Plot results
ggplot(model_svm) + theme_light()

在此处输入图像描述

您可以更深入地研究寻找的方法,kernlab其中包括更多可添加到caret框架的参数调整选项。我希望这对你有用。

于 2020-07-28T00:54:42.850 回答