为了账号安全,请及时绑定邮箱和手机立即绑定

使用 StackingClassifier 进行训练/测试分割而不是 CV

使用 StackingClassifier 进行训练/测试分割而不是 CV

哈士奇WWW 2024-01-15 17:22:00
我最近一直在尝试 StackingClassifiers,通常它与交叉验证一起使用(默认值:K-fold,num-folds = 5)。就是这样写的:from sklearn.pipeline import Pipelinefrom sklearn.tree import DecisionTreeClassifierfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.datasets import load_breast_cancerfrom sklearn.model_selection import train_test_split, RandomizedSearchCV, KFoldX, y = load_breast_cancer(return_X_y=True, as_frame=True)model = StackingClassifier(estimators=[        ('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),        ('knn', Pipeline([('knn', KNeighborsClassifier())])),    ],final_estimator = final_estimator, n_jobs = 10, passthrough = False, cv = KFold())model.fit(X, y)效果很好。然而,k 折交叉验证作为训练堆叠分类器的一种方法确实相当慢。理想情况下,我想使用 80% 的训练数据用于训练组件模型,另外20%用于训练 Final_estimator 的方法。根据docs,您可以使用一个迭代器来生成训练测试分割作为cv(交叉验证)的输入(这很奇怪,因为它不再是 CV)。所以我想分为两部分的问题是否可以使用 StackingClassifier 以这种方式工作,其中根本不使用交叉验证(CV),而是使用训练/测试分割(主要是为了加快拟合速度)?如果是这样,这看起来怎么样?我将设置什么作为cv的输入?另一张纸条。查看用户指南中的潜在 CV 选项 ShuffleSplit 和 nsplits=1 似乎是一个不错的选择,我尝试了它。model = StackingClassifier(estimators=[        ('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),        ('knn', Pipeline([('knn', KNeighborsClassifier())])),    ],final_estimator = final_estimator, n_jobs = 10, passthrough = False, cv = ShuffleSplit(n_splits=1))model.fit(X, y)但不幸的是这不起作用并引发错误:ValueError: cross_val_predict only works for partitions
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

sklearn 的 Stacked Classifier 页面指出“... estimators_ 适合整个 X,而Final_estimator_使用cross_val_predict的基本估计器的交叉验证预测进行训练。”

我认为如果您想使用基于 80%-20% 的传统训练测试方法,您应该在 StackedClassifier 之外进行。主要原因是使该过程与根据上面记录的注释使用堆叠分类器的方式保持一致。

我已经完成了此操作,我的管道/设置描述性如下。我不介意花费额外的时间对每个分类器进行训练测试,因为最终分类器对 StackedClassifier 的处理效率更高:

  1. 以 70%-30% / 80%-20% 的分割运行单独的分类器(KNN、决策树、随机森林、朴素贝叶斯等)。找到最佳参数化。

  2. 设置 StackedClassifier,其中每个分类器都适合您通过整个数据确定的最佳参数(此阶段没有分割)

  3. 检查并验证最终分类器相对于各个分类器性能的结果。

我认为花费的额外时间是不可避免的,因为您正在引入为各个分类器分割数据的额外步骤。对于最终分类器 CV 阶段,即使进行分割,最终模型输入也应在整个数据上运行,以实现单个和最终分类器的最大效率。


查看完整回答
反对 回复 2024-01-15
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

您可以获得的最快加速是KFold(n_splits=2):


model = StackingClassifier(estimators=[

        ('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),

        ('knn', Pipeline([('knn', KNeighborsClassifier())])),

    ],final_estimator = final_estimator, n_jobs = 10, passthrough = False, cv = KFold(n_splits=2))

cvparam只接受“分区”或“分区者”(正如他们所说的“根据定义”)。它们是KFold(), StratifiedKFold,但不是ShuffleSplit或train_test_split。


分区器:


n =5

x = range(90,100)

cv = KFold(n_splits=n).split(x)


for i,j in cv:

    print("TRAIN:",i,"TEST",j)

TRAIN: [2 3 4 5 6 7 8 9] TEST [0 1]

TRAIN: [0 1 4 5 6 7 8 9] TEST [2 3]

TRAIN: [0 1 2 3 6 7 8 9] TEST [4 5]

TRAIN: [0 1 2 3 4 5 8 9] TEST [6 7]

TRAIN: [0 1 2 3 4 5 6 7] TEST [8 9]

非分区者:


n =5

x = range(90,100)

# cv = KFold(n_splits=n).split(x)

cv = ShuffleSplit(n_splits=n, train_size=.8).split(x)


for i,j in cv:

    print("TRAIN:",i,"TEST",j)

TRAIN: [7 9 0 1 6 4 8 3] TEST [2 5]

TRAIN: [3 2 7 0 8 4 6 1] TEST [5 9]

TRAIN: [5 1 8 7 4 0 2 6] TEST [9 3]

TRAIN: [7 1 5 8 6 9 4 0] TEST [2 3]

TRAIN: [7 0 3 2 6 1 5 9] TEST [4 8]


查看完整回答
反对 回复 2024-01-15
  • 2 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信