2013-05-08 3 views
6

シャッフルされた層別k倍クロスバリデーションをscikit-learnで実行する組み込み方法はありますか?これは最も一般的なCVメソッドの1つであり、私はこれを行うための組み込みメソッドが見つからないことに驚いています。scikit-learnでランダム化された層別k倍クロスバリデーション?

私はcross_validation.KFold()がシャッフルフラグを持っていることを見たが、それは成層ではありません。残念なことにcross_validation.StratifiedKFold()にはこのようなオプションはありません。cross_validation.StratifiedShuffleSplit()は分解された折り目を生成しません。

何か不足していますか?これは計画されていますか?

(明らかに私は自分自身でこれを実装することができます)

答えて

-3

私の知る限りでは、これは実際に学ぶscikitに実装されています。

「」」 成層ShuffleSplitクロスバリデーションイテレータ

列車試験セット内のデータを分割するために列車/テスト指標を提供する。

このクロスバリデーションオブジェクトはStratifiedKFoldのマージであり ShuffleSplitは、層別ランダム化された折り返しを返します。 は、各クラスのサンプルの割合を保存することによって作成されます。

注:ShuffleSplit戦略のように、層別ランダム分割 は、すべてのフォールドが異なることを保証するものではありませんが、これは依然としてかなり大きいデータセットに対しては です。 「」」

+0

私は私の質問、StratifiedShuffleSplit(に書いたように)行っていませんStratifiedKFold()のシャッフル版、つまりStratifiedKFold()より前のシャッフル版です。これはあなたの答えの最後の文でも言及されています。 KFold CVは、折り畳みの間に交差がなく、その結合がデータセット全体であることを要求します。 – Bitwise

+0

ああ、はい、折り畳みが分離を保証されていません。あなたの質問の最後に読まないで申し訳ありません。 – rd108

+0

あなたはあなたの答えを削除する必要があります!お願いします... – Merlin

2

私は私はそれが他の誰にも便利な場合に私の解決策を投稿するだろうと思った

from collections import defaultdict 
import random 
def strat_map(y): 
    """ 
    Returns permuted indices that maintain class 
    """ 
    smap = defaultdict(list) 
    for i,v in enumerate(y): 
     smap[v].append(i) 
    for values in smap.values(): 
     random.shuffle(values) 
    y_map = np.zeros_like(y) 
    for i,v in enumerate(y): 
     y_map[i] = smap[v].pop() 
    return y_map 

########## 
#Example Use 
########## 
skf = StratifiedKFold(y, nfolds) 
sm = strat_map(y) 
for test, train in skf: 
    test,train = sm[test], sm[train] 
    #then cv as usual 


####### 
#tests# 
####### 
import numpy.random as rnd 
for _ in range(100): 
    y = np.array([0]*10 + [1]*20 + [3] * 10) 
    rnd.shuffle(y) 
    sm = strat_map(y) 
    shuffled = y[sm] 
    assert (sm != range(len(y))).any() , "did not shuffle" 
    assert (shuffled == y).all(), "classes not in right position" 
    assert (set(sm) == set(range(len(y)))), "missing indices" 


for _ in range(100): 
    nfolds = 10 
    skf = StratifiedKFold(y, nfolds) 
    sm = strat_map(y) 
    for test, train in skf: 
     assert (sm[test] != test).any(), "did not shuffle" 
     assert (y[sm[test]] == y[test]).all(), "classes not in right position" 
1

トレーニングとテストセットに成層シャッフル分割の私の実装です:

import numpy as np 

def get_train_test_inds(y,train_proportion=0.7): 
    '''Generates indices, making random stratified split into training set and testing sets 
    with proportions train_proportion and (1-train_proportion) of initial sample. 
    y is any iterable indicating classes of each observation in the sample. 
    Initial proportions of classes inside training and 
    test sets are preserved (stratified sampling). 
    ''' 

    y=np.array(y) 
    train_inds = np.zeros(len(y),dtype=bool) 
    test_inds = np.zeros(len(y),dtype=bool) 
    values = np.unique(y) 
    for value in values: 
     value_inds = np.nonzero(y==value)[0] 
     np.random.shuffle(value_inds) 
     n = int(train_proportion*len(value_inds)) 

     train_inds[value_inds[:n]]=True 
     test_inds[value_inds[n:]]=True 

    return train_inds,test_inds 


y = np.array([1,1,2,2,3,3]) 
train_inds,test_inds = get_train_test_inds(y,train_proportion=0.5) 
print y[train_inds] 
print y[test_inds] 

このコードの出力は:

[1 2 3] 
[1 2 3] 
関連する問題