You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. Use zero_division parameter to control this behavior.
_warn_prf(average, modifier, msg_start, len(result))

问题原因
  1. 交叉验证拆分的随机性差异:Windows和Linux环境未固定随机种子,导致GridSearchCV的2折交叉验证拆分结果不一致。你的样本量仅10条,部分拆分后的测试集中,模型可能无法预测到某类标签,触发精度计算的警告;而Windows环境刚好拆分出的测试集都能被模型覆盖所有类别,因此无警告。
  2. 加权精度的计算特性:你使用了average='weighted'的精度评分器,当某类标签无预测样本时,该类精度会被强制设为0.0,Scikit-learn会触发此警告。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:10:36