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

sklearn中VotingClassifier结合RandomizedSearchCV遇pickle序列化错误求助

问题

在sklearn 1.1.3版本中,尝试将随机超参数搜索(RandomizedSearchCV)与VotingClassifier结合使用时,运行代码出现cannot pickle 'dict_items' object错误,使用GridSearchCV也会触发相同问题。

简化代码如下:

import numpy as np
from sklearn import __version__ as skv
from sklearn.ensemble import RandomForestClassifier as RFClassi
from sklearn.ensemble import HistGradientBoostingClassifier as HGBClassi
from sklearn.tree import DecisionTreeClassifier as DTClassi
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import VotingClassifier
from sklearn.datasets import load_iris

print(f"sklearn version: {skv}")

df_X, target = load_iris(return_X_y=True, as_frame=True)
ensemble = ['rf','dtree','hgb']
hy_pa_grid = {
    'hgb': dict(learning_rate = list(np.linspace(0.01,0.5,10).round(3))),
    'rf':dict(criterion = ['gini', 'entropy']),
    'dtree':dict(criterion = ['gini', 'entropy']),
}
clfs = {'hgb' : HGBClassi(), 'rf': RFClassi(), 'dtree' : DTClassi()}
vc = VotingClassifier(estimators = clfs.items(), voting = 'soft')
params = {
    f"{c}__{p}" : hy_pa_grid[c][p]
    for c in ensemble
    for p in hy_pa_grid[c].keys()
}
print("\n".join(map(str,params.items())))
clf = RandomizedSearchCV(estimator = vc, param_distributions = params)
clf.fit(df_X,target)

运行输出:

sklearn version: 1.1.3
{'rf__criterion': ['gini', 'entropy'], 'dtree__criterion': ['gini', 'entropy'], 'hgb__learning_rate': [0.01, 0.064, 0.119, 0.173, 0.228, 0.282, 0.337, 0.391, 0.446, 0.5]}
Traceback (most recent call last):
  File "vc.py", line 34, in <module>
    clf.fit(df_X,target)                
  File "/home/USER/.local/lib/python3.8/site-packages/sklearn/model_selection/_search.py", line 789, in fit
    base_estimator = clone(self.estimator)
  File "/home/USER/.local/lib/python3.8/site-packages/sklearn/base.py", line 87, in clone
    new_object_params[name] = clone(param, safe=False)
  File "/home/USER/.local/lib/python3.8/site-packages/sklearn/base.py", line 68, in clone
    return copy.deepcopy(estimator)
  File "/usr/lib/python3.8/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle 'dict_items' object

解决办法

错误根源

clfs.items()返回的是dict_items对象,这是一种迭代器类型,无法被Python的pickle模块序列化。而sklearn的交叉验证类(如RandomizedSearchCV)在执行fit时,需要克隆传入的estimator,这个过程依赖深拷贝操作,因此触发序列化错误。

修复步骤

将clfs.items()转换为列表——列表是可序列化的容器类型,能够被深拷贝正常处理。

修改这一行代码:

vc = VotingClassifier(estimators = clfs.items(), voting = 'soft')

改为:

vc = VotingClassifier(estimators = list(clfs.items()), voting = 'soft')

修改后的完整代码

import numpy as np
from sklearn import __version__ as skv
from sklearn.ensemble import RandomForestClassifier as RFClassi
from sklearn.ensemble import HistGradientBoostingClassifier as HGBClassi
from sklearn.tree import DecisionTreeClassifier as DTClassi
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import VotingClassifier
from sklearn.datasets import load_iris

print(f"sklearn version: {skv}")

df_X, target = load_iris(return_X_y=True, as_frame=True)
ensemble = ['rf','dtree','hgb']
hy_pa_grid = {
    'hgb': dict(learning_rate = list(np.linspace(0.01,0.5,10).round(3))),
    'rf':dict(criterion = ['gini', 'entropy']),
    'dtree':dict(criterion = ['gini', 'entropy']),
}
clfs = {'hgb' : HGBClassi(), 'rf': RFClassi(), 'dtree' : DTClassi()}
# 将dict_items转换为列表
vc = VotingClassifier(estimators = list(clfs.items()), voting = 'soft')
params = {
    f"{c}__{p}" : hy_pa_grid[c][p]
    for c in ensemble
    for p in hy_pa_grid[c].keys()
}
print("\n".join(map(str,params.items())))
clf = RandomizedSearchCV(estimator = vc, param_distributions = params)
clf.fit(df_X,target)

运行修改后的代码,即可正常执行随机超参数搜索,不会再触发pickle错误。

内容的提问来源于stack exchange,提问作者Mr Felix U

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:31:01