【问题标题】:RandomizedSearchCV returning no scoreRandomizedSearchCV 不返回分数
【发布时间】:2020-06-18 23:41:46
【问题描述】:

我已经创建了一个管道来运行我的预处理器并管理缺失值等,但是当我尝试使用 RandomizedSearchCV 时我被卡住了。 普通的 GridsearchCV 工作正常。

它是一种监督学习风格和分类学习任务,预测/分类一个二元目标 (1/0)。

这是我的模型:

# Random Forest
RF = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, 
                            min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
                            max_features='auto', max_leaf_nodes=None, random_state=1337)

这是我设置管道并尝试获得分数的地方,但这可能不起作用。

pipeline_RF = Pipeline(steps=[
        ('preprocessor', preprocessor),
        #('pca', pca),
        ('rf', RF)                          
])

print("\n------------ Randomized Search (Random Forest) ------------")

param_distributions = {
    'rf__n_estimators':  np.random.randint(1, 200, 10),
    'rf__max_depth': np.random.randint(1, 100, 10),
    'rf__min_samples_split': np.linspace(0.1, 1.0, 10, endpoint=True),      
    'rf__min_samples_leaf':  np.linspace(0.1, 0.5, 5, endpoint=True),
    'rf__criterion': ['entropy'],
    'rf__max_features': ['auto']
}

rscv = RandomizedSearchCV(pipeline_RF, param_distributions=param_distributions, cv = StratifiedKFold(n_splits=5), 
                          scoring="recall", n_iter=2, refit=True, n_jobs=-1, random_state=1337, return_train_score=True, verbose=10)

rscv.fit(X_train, y_train)
print("\nBest parameter (CV score=%0.3f):" % rscv.best_score_)
print("\Best Hyperparameters: ", rscv.best_params_)

y_pred = rscv.best_estimator_.predict(X_test)
print("\nPrecision, Recall, F1 and Support: ", precision_recall_fscore_support(y_test, y_pred, average='binary'))

错误信息如下,但对我帮助不大:

------------ Randomized Search (Random Forest) ------------
Fitting 5 folds for each of 2 candidates, totalling 10 fits

[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.
[Parallel(n_jobs=-1)]: Done   1 tasks      | elapsed:    4.4s
[Parallel(n_jobs=-1)]: Done   4 tasks      | elapsed:    8.1s
[Parallel(n_jobs=-1)]: Done  10 out of  10 | elapsed:   18.4s finished


Best parameter (CV score=0.000):
\Best Hyperparameters:  {'rf__n_estimators': 135, 'rf__min_samples_split': 0.30000000000000004, 'rf__min_samples_leaf': 0.30000000000000004, 'rf__max_features': 'auto', 'rf__max_depth': 51, 'rf__criterion': 'entropy'}

Precision, Recall, F1 and Support:  (0.0, 0.0, 0.0, None)

/usr/local/lib/python3.6/dist-packages/sklearn/metrics/_classification.py:1272: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 due to no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, msg_start, len(result))

看起来它设置了超参数(尽管每次运行它时它们似乎都是一样的)。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 仔细查看警告信息;您建模的某些类无法预测,从而导致相应的指标未定义。
  • y_train 的班级余额是多少?
  • @BenReiniger 感谢您的回答!目标变量是“成功”,“否”出现 32893 次,“是”只有“4176”,因此成功率为 12.7%。这是你要求的吗?

标签: python machine-learning scikit-learn


【解决方案1】:

正如desertnaut 在 cmets 中已经指出的那样,您的模型根本无法预测少数类。另一方面,您的代码没问题。您可以通过以下方式验证这一点:

根据您对 BenReiniger 的回复评论,我创建了一个虚拟数据集来重现您的情况:

from sklearn.datasets import make_classification

X, y = make_classification(n_samples=(32893+4176), n_classes=2, weights=[0.88, 0.12])
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2, random_state=42)

此数据集与您的数据集具有相同的类别不平衡性和样本量。当你在这个数据集上运行你的代码时,你会得到同样的警告。现在,这是为什么呢?让我们检查y_pred 的结果作为pandas 数据框:

print(pd.DataFrame(y_pred).astype('category').describe())

# output
count   7414
unique     1
top        0
freq    7414

如您所见,模型仅预测了一类。在这种情况下,定义为tp / (tp + fp) 的正类的精度分数是未定义的,因为涉及除以零。这也是您的警告告诉您的原因:

Use `zero_division` parameter to control this behavior.

您应该能够在自己的数据集上验证这一点。此外,如果您使用另一个评分函数,如accuracy_score,您应该能够看到您的代码在没有警告或错误的情况下运行,并按预期返回分数。如果模型未预测任何正类,则某些指标只是未定义。

这应该澄清一些事情。总之,您的代码没问题。但是您的模型没有针对预测任务进行足够好的训练,您需要正确处理类不平衡。

【讨论】:

  • 非常感谢!这个解释帮助我了解了很多问题!使用准确度评分会给我一个像你提到的结果 - 但特别是因为不平衡 - 我怀疑这是解决我的问题的正确评分方法。我会做一些关于处理类不平衡的研究,我希望这也能改进我正在练习的一些其他模型(但是这些模型适用于 f1/recall/precision 评分)。我认为使用 StratifiedKFold 可以帮助我解决这个问题,但这似乎还不够?再次感谢您的详细解答!
  • 只是为了澄清:提到准确度分数是为了支持这一点,一般来说,一切都按预期工作。在高级不平衡的情况下,准确性绝对是一个误导性的性能指标。您正在使用合适的指标。但所展示的结果是可以预期和合法的。您使用的代码或指标没有任何问题。但是您的模型构建过程需要改进。
  • 我已经明白了,并且对不平衡类的主题进行了一些阅读。通过对我的成功功能使用上采样,我不仅能够让我的 RandomizedSearchCV 正常工作,而且我还能够大幅改进我的其他模型(使用 GridSearchCV 运行)——现在 f1 得分约为 92%(之前约为 55 %)。我用一个仍然不平衡的训练集对此进行了测试。您确实以某种方式启发了我的问题所在,并且将来我肯定会更加注意不平衡的课程。你能帮我理解为什么简单地使用 StratifiedKFold 不能解决这个问题吗?
  • 干得好...! ;)
  • 既然你问了:分割数据时,分层会在每次分割时保留原始类分布。这不会帮助您的模型更有效地学习。但这对您的模型评估非常重要。因为,如果测试集不能充分代表原始问题,那么您的测试基本上是没有意义的。这就是为什么你应该只重新采样训练而不是测试集的原因。否则,您会使您的结果无效。所以,要小心。我希望这会有所帮助并结束它。我们正在向 cmets 部分发送垃圾邮件;)
猜你喜欢
  • 1970-01-01
  • 2021-05-04
  • 2018-12-12
  • 1970-01-01
  • 2016-07-30
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
相关资源
最近更新 更多