Scikit-learn,GroupKFold 与洗牌组?

Posted

技术标签:

【中文标题】Scikit-learn,GroupKFold 与洗牌组?【英文标题】:Scikit-learn, GroupKFold with shuffling groups? 【发布时间】:2017-04-10 17:12:38 【问题描述】:

我正在使用 scikit-learn 中的 StratifiedKFold,但现在我还需要注意“组”。有很好的功能 GroupKFold,但我的数据非常依赖时间。与帮助中的相似,即周数是分组索引。但每周应该只有一次。

假设我需要 10 折。我需要先打乱数据,然后才能使用 GroupKFold。

洗牌是在群体意义上的——所以整个群体应该相互洗牌。

有没有办法以某种方式使用 scikit-learn 优雅?在我看来,GroupKFold 可以先对数据进行洗牌。

如果没有办法用 scikit 做到这一点,任何人都可以编写一些有效的代码吗?我有大型数据集。

矩阵、标签、组作为输入

【问题讨论】:

【参考方案1】:

编辑:此解决方案不起作用。

我认为使用sklearn.utils.shuffle 是一个优雅的解决方案!

对于 X、y 和组中的数据:

from sklearn.utils import shuffle
X_shuffled, y_shuffled, groups_shuffled = shuffle(X, y, groups, random_state=0)

然后将 X_shuffled、y_shuffled 和 groups_shuffled 与 GroupKFold 一起使用:

from sklearn.model_selection import GroupKFold
group_k_fold = GroupKFold(n_splits=10)
splits = group_k_fold.split(X_shuffled, y_shuffled, groups_shuffled)

当然,您可能想要多次洗牌并在每次洗牌时进行交叉验证。您可以将整个事情放在一个循环中 - 这是一个完整的示例,包含 5 次随机播放(并且只有 3 次拆分,而不是您需要的 10 次):

X = np.arange(20).reshape((10, 2))
y = np.arange(10)
groups = [0, 0, 0, 1, 2, 3, 4, 5, 6, 7]

n_shuffles = 5
group_k_fold = GroupKFold(n_splits=3)

for i in range(n_shuffles):
    X_shuffled, y_shuffled, groups_shuffled = shuffle(X, y, groups, random_state=i)
    splits = group_k_fold.split(X_shuffled, y_shuffled, groups_shuffled)
    # do something with splits here, I'm just printing them out
    print 'Shuffle', i
    print 'groups_shuffled:', groups_shuffled
    for train_idx, val_idx in splits:
        print 'Train:', train_idx
        print 'Val:', val_idx

【讨论】:

不幸的是,这种策略似乎行不通。请参阅***.com/q/41859613/1551810,它显示它只是重新排列每个折叠的元素,但它没有给出新的拆分!【参考方案2】:

同一组不会出现在两个不同的折叠中(不同组的数量必须至少等于折叠的数量)

在 GroupKfold 中,组的形状与数据形状相同

对于 X、y 和组中的数据:

import numpy as np
import pandas as pd
from sklearn.model_selection import GroupKFold
from sklearn.model_selection import GridSearchCV
from xgboost import XGBClassifier
import datetime

X = np.array([[1,2,1,1], [3,4,7,8], [5,6,1,3], [7,8,4,7]])
y=np.array([0,2,1,2])
groups=np.array([2,1,0,1])  
group_kfold = GroupKFold(n_splits=len(groups.unique))
group_kfold.get_n_splits(X, y, groups)

 param_grid =
        'min_child_weight': [50,100],
        'subsample': [0.1,0.2],
        'colsample_bytree': [0.1,0.2],
        'max_depth': [2,3],
        'learning_rate': [0.01],
        'n_estimators': [100,500],
        'reg_lambda': [0.1,0.2]        
        

xgb = XGBClassifier()

grid_search = GridSearchCV(xgb, param_grid, cv=group_kfold.split(X, Y, groups), n_jobs=-1)

result = grid_search.fit(X,Y)

【讨论】:

以上是关于Scikit-learn,GroupKFold 与洗牌组?的主要内容,如果未能解决你的问题,请参考以下文章

如何获得可重现但不同的 GroupKFold 实例

如何结合 Scikit Learn 的 GroupKFold 和 StratifieKFold

sklearn可视化不同数据划分方法的差异:KFold, ShuffleSplit,StratifiedKFold, GroupKFold, StratifiedShuffleSplit.......

小窥KFold及其变体

[机器学习与scikit-learn-3]:scikit-learn模型地图与模型选择

[机器学习与scikit-learn-4]:scikit-learn机器学习的一般流程与案例演示