Sklearn中DecisionTreeClassifier的GridSearchCV在Linux/macOS偶现UndefinedMetricWarning
问题描述
将决策树分类器的网格搜索工作流从Windows迁移至Linux集群后,频繁触发UndefinedMetricWarning警告,但Windows环境下运行无异常。相关信息如下:
运行代码
import pandas as pd from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import make_scorer,accuracy_score,recall_score,f1_score, precision_score, roc_auc_score import numpy as np from sklearn.model_selection import GridSearchCV data = pd.read_csv("Dtree_test_data.csv") d_tree = DecisionTreeClassifier() scoring = {'accuracy' : make_scorer(accuracy_score), 'precision' : make_scorer(precision_score, average = 'weighted'), 'recall' : make_scorer(recall_score, average = 'weighted'), 'f1_score' : make_scorer(f1_score, average = 'weighted')} features = data[["H-Bonds","Mass"]] labels = data["Class"] parameters = {'max_depth':np.arange(1,3,1), 'min_samples_leaf': np.arange(0.01,0.05,0.01), 'min_impurity_decrease':np.arange(0.01,0.04,0.01), 'criterion':['gini','entropy']} dtree = DecisionTreeClassifier() clf = GridSearchCV(dtree,parameters,verbose=1,n_jobs=12,scoring=scoring,refit=False,return_train_score=True,cv=2) clf.fit(features,labels)
样本数据
H-Bonds Mass Class 0 2 123 0 1 3 45 1 2 1 153 2 3 4 90 0 4 6 300 1 5 1 40 2 6 2 200 0 7 3 245 1 8 4 87 2 9 1 126 1
警告信息
Fitting 2 folds for each of 48 candidates, totalling 96 fits
/../miniconda3/envs/ml-debug-current/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1334: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Usezero_divisionparameter to control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
问题原因
- 交叉验证拆分的随机性差异:Windows和Linux环境未固定随机种子,导致
GridSearchCV的2折交叉验证拆分结果不一致。你的样本量仅10条,部分拆分后的测试集中,模型可能无法预测到某类标签,触发精度计算的警告;而Windows环境刚好拆分出的测试集都能被模型覆盖所有类别,因此无警告。 - 加权精度的计算特性:你使用了
average='weighted'的精度评分器,当某类标签无预测样本时,该类精度会被强制设为0.0,Scikit-learn会触发此警告。 - Scikit-learn版本差异:两个环境的Scikit-learn版本可能不同,新版本对未覆盖类别的精度计算警告逻辑更严格,导致Linux环境出现警告而Windows没有。
解决办法
- 固定全局随机种子:确保跨环境的交叉验证拆分一致,消除随机性影响:
import random random.seed(42) np.random.seed(42) - 设置
zero_division参数:在精度和F1的评分器中指定无预测样本时的处理方式,直接消除警告:'precision' : make_scorer(precision_score, average='weighted', zero_division=1), 'f1_score' : make_scorer(f1_score, average='weighted', zero_division=1) - 改用分层交叉验证:针对小样本的多分类任务,使用
StratifiedKFold确保拆分后每个折的类别分布与原数据一致,减少极端拆分情况:from sklearn.model_selection import StratifiedKFold clf = GridSearchCV(dtree, parameters, verbose=1, n_jobs=12, scoring=scoring, refit=False, return_train_score=True, cv=StratifiedKFold(n_splits=2, shuffle=True, random_state=42))
内容的提问来源于stack exchange,提问作者doom4
相关产品推荐
相关产品推荐

