首页 文章

如何在scikit-learn中生成自定义交叉验证生成器?

提问于
浏览
10

我有一个不 balancer 的数据集,所以我有一个过采样策略,我只在训练数据时应用 . 我想使用像 GridSearchCVcross_val_score 这样的scikit-learn类来探测或交叉验证我的估算器上的一些参数(例如SVC) . 但是我看到你要么传递cv折叠的数量,要么传递标准的交叉验证生成器 .

我想创建一个自定义cv生成器,所以我得到并分层5折并仅过滤我的训练数据(4倍)并让scikit-learn通过我的估计器的参数网格查看并使用剩余的折叠进行验证 .

提前致谢 .

4 回答

  • 7

    交叉验证生成器返回一个长度为 n_folds 的可迭代,其中每个元素都是一个2元组的numpy 1-d数组 (train_index, test_index) ,其中包含该交叉验证运行的测试和训练集的索引 .

    因此,对于10倍交叉验证,您的自定义交叉验证生成器需要包含10个元素,每个元素包含一个包含两个元素的元组:

    • 该运行的训练子集的索引数组,覆盖了90%的数据

    • 该运行的测试子集的索引数组,覆盖10%的数据

    我正在研究一个类似的问题,我为我的数据的不同折叠创建了整数标签 . 我的数据集存储在Pandas数据框 myDf 中,其中交叉验证标签的列为 cvLabel . 我构建自定义交叉验证生成器 myCViterator 如下:

    myCViterator = []
    for i in range(nFolds):
        trainIndices = myDf[ myDf['cvLabel']!=i ].index.values.astype(int)
        testIndices =  myDf[ myDf['cvLabel']==i ].index.values.astype(int)
        myCViterator.append( (trainIndices, testIndices) )
    
  • -1

    Scikit-Learn提供了一个解决方法,使用他们的Label k-fold迭代器:

    LabelKFold是k-fold的变体,可确保同一标签不在测试和训练集中 . 例如,如果您从不同的科目获得数据并且您希望通过对不同科目的测试和培训来避免过度拟合(即,学习人员特定的特征),则这是必要的 .

    要在过采样的情况下使用此迭代器,首先,您可以在数据框中创建一个列(例如 cv_label ),该列存储每行的索引值 .

    df['cv_label'] = df.index
    

    然后,您可以应用过采样,确保在过采样中复制 cv_label 列 . 此列将包含过采样数据的重复值 . 您可以从这些标签创建单独的系列或列表,以便以后处理:

    cv_labels = df['cv_label']
    

    请注意,在运行交叉验证器/分类器之前,您需要从数据框中删除此列 .

    将数据分成要素(不包括 cv_label )和标签后,创建 LabelKFold 迭代器并运行所需的交叉验证功能:

    clf = svm.SVC(C=1)
    lkf = LabelKFold(cv_labels, n_folds=5)
    predicted = cross_validation.cross_val_predict(clf, features, labels, cv=lkf)
    
  • 12

    我有一个类似的问题,这个快速的黑客正在为我工作:

    class UpsampleStratifiedKFold:
        def __init__(self, n_splits=3):
            self.n_splits = n_splits
    
        def split(self, X, y, groups=None):
            for rx, tx in StratifiedKFold(n_splits=self.n_splits).split(X,y):
                nix = np.where(y[rx]==0)[0]
                pix = np.where(y[rx]==1)[0]
                pixu = np.random.choice(pix, size=nix.shape[0], replace=True)
                ix = np.append(nix, pixu)
                rxm = rx[ix]
                yield rxm, tx
    
        def get_n_splits(self, X, y, groups=None):
            return self.n_splits
    

    这个上采样(有替换)的少数类为 balancer 的 (k-1) -折叠训练集,但是让测试集不 balancer . 这似乎与sklearn.model_selection.GridSearchCV以及需要CV生成器的其他类似类一起使用 .

  • 5
    class own_custom_CrossValidator:#like those in source sklearn/model_selection/_split.py 
        def init(self):#coordinates,meter 
            pass # self.coordinates = coordinates # self.meter = meter 
        def split(self,X,y=None,groups=None):
        #for compatibility with #cross_val_predict,cross_val_score 
            for i in range(0,len(X)): yield tuple((np.array(list(range(0,len(X))))
    

相关问题