Scikit-Learn,groupkfold与洗牌组



我正在使用Scikit-learn的Stratifiedkfold,但现在我还需要观看"组"。有很好的函数groupkfold,但是我的数据非常依赖。因此,如在帮助中,即一周是分组索引。但是每个星期应该只有一倍。

假设我需要10倍。我需要的是首先调整数据,然后才能使用groupkfold。

改组是在群体中 - 因此整个组应彼此混乱。

有没有办法与Scikit-Learn优雅相处?在我看来,groupkfold首先要混合数据。

如果无法使用Scikit做到这一点,有人可以编写一些有效的代码吗?我有很大的数据集。

矩阵,标签,组为输入

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

我认为使用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_shuff 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

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

在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)

这是一个性能解决方案,本质上以尊重原始组的方式重新分配键的值。

代码如下所示,但四个步骤为:

  1. 将小组键矢量供电。这里的关键目标是重新排列首先出现每个分组键。
  2. 使用 np.unique()返回每个唯一键的first_index值和可用于重建grouping-key向量的inverse_index值。
  3. 使用在First_Index值上操作的反向索引的花式索引来构建一个新的分组键,其中每个分组密钥已转换为代表它首先显示在 shuffled 分组向量。
  4. 分组密钥的新向量可以在标准GroupKFold分离器中使用,以获得与原始键不同的拆分集,因为您已重新排序分组索引。

举一个快速的例子,请想象您的原始分组键向量为[3, 1, 1, 5, 3, 5],然后此过程将创建一个新的分组密钥向量[0, 1, 1, 2, 0, 2]。这3个之所以成为0,是因为它们是第一个出现的钥匙,而是1键变成1,因为它们是第二个出现的钥匙,而5的钥匙已成为2,因为它们是出现的第三个钥匙。只要您整理钥匙,您就会得到分组键的转换,从而导致GroupKfold的一组拆分。

代码:

# Say that A is the official grouping key
A = list(range(10)) + list(range(10))
B = list(range(20))
y = np.zeros(20)
X = pd.DataFrame({
    'group': A,
    'var': B
})
X = X.sample(frac=1)
original_grouping_vector = X['group']
unique_values, indexes, inverse = np.unique(original_grouping_vector, return_inverse=True, return_index=True)
new_grouping_vector = indexes[inverse] # This is where the magic happens!
splitter = GroupKFold()
for train, test in splitter.split(X, y, groups=new_grouping_vector):
    print(X.iloc[test, :])

以上将在改组时打印出不同的拆分,因为正在重新排序分组键,从而导致new_grouping_vector的值更改。

相关内容

  • 没有找到相关文章

最新更新