2013-05-08 10 views
6

Czy jest jakiś wbudowany sposób, aby nauczyć się scikit, aby wykonać przetasowaną, warstwową k-krotność sprawdzania krzyżowego? Jest to jedna z najpopularniejszych metod CV i jestem zaskoczony, że nie mogłem znaleźć wbudowanej metody, aby to zrobić.Randomizowane rozwarstwione sprawdzanie krzyżowe k-krotności w nauce scikit?

Zobaczyłem, że cross_validation.KFold() ma flagę przetasowania, ale nie jest podzielona na straty. Niestety, cross_validation.StratifiedKFold() nie ma takiej opcji, a cross_validation.StratifiedShuffleSplit() nie wytwarza rozłącznych fałd.

Czy brakuje mi czegoś? Czy to jest planowane?

(oczywiście mogę realizować ten sam)

Odpowiedz

-3

O ile mi wiadomo, to jest rzeczywiście realizowany w scikit-learn.

""” Warstwowy ShuffleSplit walidację krzyżową iterator

Zapewnia indeksy pociąg/test podzielić dane w zestawach testowych kolejowych.

Ten obiekt cross-walidacja jest scalanie z StratifiedKFold i ShuffleSplit, który zwraca losowo podzielone fałdy warstwowe: fałdy są tworzone przez zachowanie procentu próbek dla każdej klasy.Uwaga: podobnie jak strategia ShuffleSplit, stratyfikowane losowe podziały nie gwarantują, że wszystkie fałdy będą się różnić, chociaż jest to bardzo prawdopodobne w przypadku sporego zestawu danych. „””

+0

Jak napisałem w moim pytaniu StratifiedShuffleSplit() nie robi przetasowaną wersję StratifiedKFold(), tj. przetasowanie przed StratifiedKFold(). Jest to nawet wspomniane w ostatnim zdaniu odpowiedzi. KFold CV wymaga, aby nie było przecięcia między fałdami, a ich związek jest całym zbiorem danych. – Bitwise

+0

Ah, tak, fałdy nie są gwarantowane odłączyć. Przepraszam, że nie przeczytałem do końca pytania. – rd108

+0

Powinieneś usunąć swoją odpowiedź! Proszę... – Merlin

2

Myślałam, że będę pisać moje rozwiązanie w przypadku jest przydatna nikomu

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

Oto moja realizacja warstwowej losowym podziale na szkolenia i testowania zestawu:

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] 

Ten kod wyjścia:

[1 2 3] 
[1 2 3] 
Powiązane problemy