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

时间:2017-06-22 12:03:18

标签: scikit-learn svm grid-search multilabel-classification hyperparameters

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

我目前所做的是使用火车/测试分割自己执行搜索:

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(结果)

2 个答案:

答案 0 :(得分:3)

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

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导入的单类SVM不合适,循环将如下所示:

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

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

答案 1 :(得分:3)

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

GridSearchCV类的cv参数可以将可迭代的屈服(训练,测试)拆分为索引数组作为其输入。您可以生成仅使用训练折叠中阳性类别的数据,而使用测试折叠中阳性类别的其余数据以及阴性类别的所有数据的分组。

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

from sklearn.model_selection import KFold

假设XposOneClassSVM的正类的nXp numpy数据数组,而Xneg是已知异常示例的mXp数据数组。

您可以首先使用{p>为Xpos生成拆分

splits = KFold(n_splits=5).split(Xpos)

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

然后您可以使用{p>将XposXneg合并为一个数据集

X = np.concatenate([Xpos, Xneg], axis=0)

OneClassSVM会做出预测1.0的预测,例如它认为是肯定类,而预测-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)

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

grid_search = GridSearchCV(estimator, X, y, cv=splits, scoring=...)

编辑:我没有注意到Vivek Kumar在另一个答案的评论中建议使用这种方法,并且OP拒绝了该方法,因为他们不认为它可以使用他们选择最佳参数的方法。我仍然喜欢我描述的方法,因为GridSearchCV将自动处理多处理并提供异常处理以及内容丰富的警告和错误消息。

在计分方法的选择上也很灵活。您可以通过将字典映射字符串传递给评分可调用项来使用多种评分方法,甚至可以定义自定义 为可调用项评分。在Scikit学习文档here中对此进行了描述。选择最佳参数的定制方法可能可以通过自定义评分功能实现。可以使用文档中描述的词典方法来包括OP使用的所有度量。