为何sklearn的KFold仅可枚举一次?及xgboost.cv使用问题
问题解答
为什么kf只能被枚举一次?
KFold.split(df)返回的是迭代器(iterator),而非列表这类可重复遍历的容器。迭代器的核心特性是按需生成元素,遍历过程中会逐步消耗内部元素,一旦遍历完成,迭代器就处于"耗尽"状态,再次遍历不会返回任何元素。就像一次性喝完水杯里的水,不重新装水的话,再倒就倒不出东西了。
你的代码里第一次循环已经把迭代器kf的所有元素(两组拆分索引)取完,第二次循环自然没有元素可以输出。
针对xgboost.cv的更优解决方案
你目前将拆分结果存入列表的方法可行,但有两种更简洁的方式:
方案1:直接传入KFold实例(推荐)
xgboost.cv的folds参数支持直接接收交叉验证生成器对象(比如KFold实例),而非拆分后的迭代器或列表。xgboost内部会自动调用生成器的split方法获取拆分索引,每次需要时都会重新生成,完全避免迭代器耗尽的问题:
import pandas as pd from sklearn.model_selection import KFold import xgboost as xgb df = pd.DataFrame([[1,2,3,4,5],[6,7,8,9,10]]) # 实例化KFold对象 kf = KFold(n_splits=2) # 直接传入KFold实例到folds参数 xgb.cv( params={...}, dtrain=xgb.DMatrix(df.iloc[:, :-1], label=df.iloc[:, -1]), folds=kf, # 其他参数... )
方案2:快速将迭代器转为列表
如果需要提前固定拆分结果(比如复现实验),可以直接用list()把split返回的迭代器转为列表,比手动循环更简洁:
kf_splits = list(KFold(n_splits=2).split(df)) xgb.cv(..., folds=kf_splits)
内容的提问来源于stack exchange,提问作者Yue Y
相关产品推荐
相关产品推荐

