有没有办法在 One-Class SVM 上进行网格搜索超参数优化

Is there a way to perform grid search hyper-parameter optimization on One-Class SVM

有没有办法使用 GridSearchCV 或任何其他内置的 sklearn 函数来找到 OneClassSVM 分类器的最佳超参数?

我目前所做的是使用 train/test 拆分自己执行搜索,如下所示:

Gamma 和 nu 值定义为:

gammas = np.logspace(-9, 3, 13)
nus = np.linspace(0.01, 0.99, 99)

探索所有可能的超参数并找到最佳超参数的函数:

clf = OneClassSVM()

results = []

train_x = vectorizer.fit_transform(train_contents)
test_x = vectorizer.transform(test_contents)

for gamma in gammas:
    for nu in nus:
        clf.set_params(gamma=gamma, nu=nu)

        clf.fit(train_x)

        y_pred = clf.predict(test_x)

        if 1. in y_pred:  # Check if at least 1 review is predicted to be in the class
            results.append(((gamma, nu), (accuracy_score(y_true, y_pred),
                                              precision_score(y_true, y_pred),
                                              recall_score(y_true, y_pred),
                                              f1_score(y_true, y_pred),
                                              roc_auc_score(y_true, y_pred),
                                              ))
                               )

    # Determine and print the best parameter settings and their performance
    print_best_parameters(results, best_parameters(results))

结果存储在以下形式的元组列表中:

((gamma, nu)(accuracy_score, precision_score, recall_score, f1_score, roc_auc_score))

为了找到最好的精度,f1,roc_auc 分数和参数我写了自己的函数:

best_parameters(results)

是的,有一种方法可以在不对输入数据执行交叉验证的情况下搜索超参数。此方法称为 ParameterGrid() 并存储在 sklearn.model_selection 中。这是官方文档的link:

http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.ParameterGrid.html

您的案例可能如下所示:

grid = {'gamma' : np.logspace(-9, 3, 13),
        'nu' : np.linspace(0.01, 0.99, 99)}

要使用 网格 断言所有可能的步骤,您可以键入 list(ParameterGrid(grid))。我们也可以通过 len(list(ParameterGrid(grid))) 检查它的长度,它总共给出了 1287 个模型,因此有 1287 个模型适合训练数据。

要使用该方法,您需要一个 for 循环。暗示你有 clf 变量,因为你不适合从 sklearn.svm 导入的一个 class SVM,循环将如下所示:

for z in ParameterGrid(grid):
    clf.set_params(**z)
    clf.fit(X_train, y_train)
    clf.predict(X_test)
    ...

我希望这就足够了。不要忘记 grid 中的名称应该与 one-class SVM 的参数一致。要获取这些参数的名称,您可以键入 clf.get_params().keys(),然后您会看到 'gamma' 和 'nu'.

我 运行 遇到了同样的问题,并在搜索解决方案时发现了这个问题。我最终找到了一个使用 GridSearchCV 的解决方案,并将此答案留给搜索并找到此问题的其他人。

GridSearchCV class 的 cv 参数可以将可迭代的屈服 (train, test) 拆分作为索引数组作为其输入。您可以生成仅使用训练折叠中正 class 中的数据的拆分,以及正 class 中的剩余数据加上测试折叠中负 class 中的所有数据。

您可以使用 sklearn.model_selection.KFold 进行分割

from sklearn.model_selection import KFold

假设 Xpos 是 nXp numpy 数据数组,class 是 OneClassSVMXneg 是已知异常示例的 mXp 数据数组。

您可以先使用

Xpos生成拆分
splits = KFold(n_splits=5).split(Xpos)

这将构建一个形式为 (train, test) 的元组生成器,其中 train 是一个 numpy 整数数组,其中包含训练折叠中示例的索引,而 test 是一个 numpy包含测试折叠中示例索引的数组。

然后您可以使用

XposXneg 组合成一个数据集
X = np.concatenate([Xpos, Xneg], axis=0)

OneClassSVM 会预测 1.0 它认为正例 class 和预测 -1.0 它认为异常的例子。我们可以使用

为我们的数据制作标签
y = np.concatenate([np.repeat(1.0, len(Xpos)), np.repeat(-1.0, len(Xneg))])

然后我们可以制作一个新的 (train, test) 分割生成器,其中包含测试折叠中包含的异常示例的索引。

n, m = len(Xpos), len(Xneg)

splits = ((train, np.concatenate([test, np.arange(n, n + m)], axis=0)
          for train, test in splits)

然后您可以使用数据 X, y 以及您希望的任何评分方法和其他参数将这些拆分传递给 GridSearchCV

grid_search = GridSearchCV(estimator, param_grid, cv=splits, scoring=...)

编辑: 我没有注意到 Vivek Kumar 在另一个答案的评论中提出了这种方法,并且 OP 拒绝了它,因为他们没有相信它会与他们选择最佳参数的方法一起使用。我仍然更喜欢我所描述的方法,因为 GridSearchCV 将自动处理多处理并提供异常处理和信息警告和错误消息。

评分方式的选择也很灵活。您可以通过将字典映射字符串传递给可调用评分来使用多种评分方法,甚至可以定义自定义 计分调用。这在 Scikit-learn 文档 here 中有描述。选择最佳参数的定制方法可能会通过自定义评分函数来实现。 OP 使用的所有指标都可以使用文档中描述的字典方法包含在内。

您可以找到一个真实世界的例子 here。当它合并到 master 中时,我会记下来更改 link。