首页 > 解决方案 > 如何捕捉触发 sklearn.GridSearchCV.fit() 警告的原因?

问题描述

在他们调用的 rasa_nlu 函数中GridSearchCV.fit()clf.fit()它引发了一些警告,我想捕捉并修改以了解触发它们的原因:

Fitting 2 folds for each of 6 candidates, totalling 12 fits
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
/home/mike/Programming/Rasa/myflaskapp/rasaenv/lib/python3.5/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
[Parallel(n_jobs=1)]: Done  12 out of  12 | elapsed:    0.1s finished

以下是如何GridSearchCV构建的:

cv_splits = self._num_cv_splits(y) #when I printed it out it gave me "2", I was expected something more related to the labels

GridSearchCV(SVC(C=1,
                probability=True,
                class_weight='balanced'),
            param_grid=tuned_parameters,
            n_jobs=num_threads,
            cv=cv_splits,
            scoring='f1_weighted',
            verbose=1)

哪些ylabels转换为数字

y: [1 0 2 1 1 1 1 1 1 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 3 3]

labels: ['greet', 'goodbye', 'inform', 'greet', 'greet', 'greet', 'greet', 'greet', 'greet', 'goodbye', 'goodbye', 'goodbye', 'goodbye', 'goodbye', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'inform', 'laughing', 'laughing']

理想情况下,我想抓住其中哪些触发了警告。

更新

直到现在我试图获取原点,我仍然没有找到捕获警告的方法:

 fit_result = self.clf.fit (X, y)
 y_pred = self.clf.predict (X)
 print ("set (y) -set (y_pred): \ n", set (y) -set (y_pred))

但它只是给了我一个空集set ()

是否也需要使用.predict (X)?和结果有区别clf.fit ()吗?

标签: python-3.xscikit-learnwarningsrasa-nlu

解决方案


首先在 Rasa NLU 的 sklearn 意图分类器中执行网格搜索的代码:

self.clf.fit(X, y)

如果我这样做,我能够完全抑制警告:

with warnings.catch_warnings():
    warnings.filterwarnings("ignore")

    self.clf.fit(X, y)

如果您想将捕获的警告限制在特定模块或行号,过滤警告功能有更多选项。看这里

我能找到的捕获警告并对其进行处理的最佳方法是实际将警告提升为错误。抓住错误,然后做任何我想做的事。

with warnings.catch_warnings():
    warnings.filterwarnings("error")

    try:
        self.clf.fit(X, y)
    except:
        ... do some code ...

但请记住,这样做意味着拟合不会持续存在,并且需要在您添加额外代码后再次调用。在小型训练集上还不错,但在大型训练集上却很烦人。


话虽如此,在深入研究并探索了错误的原因之后,它确实似乎可以被大多数人忽略,或者更好的是忽略并替换为只有 2 个训练示例的意图警告。如果您在示例中注意到 sklearn 会打印出:

对 6 个候选者中的每一个进行拟合 2 折,总共 12 次拟合

然后你收到了关于 f-score 的六个警告。很可能只有两个示例无法预测您的标签。

在您的示例中,您提供了 40 个示例。但随后这 40 个被分成训练集和测试集。如果您的意图只有 2 个示例,一个将进入训练集,一个将进入测试集。

我重新创建了一个与您的数据集相似的数据集,仅基于标签和创建折叠的位置:

TRAIN: [1 1 0 3 3 3 3 3 1 2 2] TEST: [3 3 3 3 1 1 1 1 0 3 2 2 2]
TRAIN: [3 3 3 3 1 1 1 1 0 3 2 2 2] TEST: [1 1 0 3 3 3 3 3 1 2 2]

不难相信测试集会将 0 误分类为另一个标签。如果他们这样做了,那么 f 分数将是不明确的。

在这方面有几篇很好的 Stack Overflow 帖子,比如这个。如果特定标签在预测集中没有真阳性,那么它会导致零除以零。因此,sklearn 将其设置为 0。


推荐阅读