Come dividere i dati in 3 set (treno, validazione e test)?

Ho un dataframe panda e desidero dividerlo in 3 set separati. So che usando train_test_split da sklearn.cross_validation , si possono dividere i dati in due set (treno e test). Tuttavia, non sono riuscito a trovare alcuna soluzione sulla suddivisione dei dati in tre set. Preferibilmente, mi piacerebbe avere gli indici dei dati originali.

So che una soluzione alternativa sarebbe usare train_test_split due volte e in qualche modo regolare gli indici. Ma c’è un modo più standard / built-in per dividere i dati in 3 set anziché in 2?

Soluzione di Numpy. Divideremo il nostro set di dati nelle seguenti parti:

  • 60% – set di treni,
  • 20% – set di convalida,
  • 20% – set di test

 In [305]: train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))]) In [306]: train Out[306]: ABCDE 0 0.046919 0.792216 0.206294 0.440346 0.038960 2 0.301010 0.625697 0.604724 0.936968 0.870064 1 0.642237 0.690403 0.813658 0.525379 0.396053 9 0.488484 0.389640 0.599637 0.122919 0.106505 8 0.842717 0.793315 0.554084 0.100361 0.367465 7 0.185214 0.603661 0.217677 0.281780 0.938540 In [307]: validate Out[307]: ABCDE 5 0.806176 0.008896 0.362878 0.058903 0.026328 6 0.145777 0.485765 0.589272 0.806329 0.703479 In [308]: test Out[308]: ABCDE 4 0.521640 0.332210 0.370177 0.859169 0.401087 3 0.333348 0.964011 0.083498 0.670386 0.169619 

[int(.6*len(df)), int(.8*len(df))] – è un array indices_or_sections per numpy.split () .

Ecco una piccola demo per l’ np.split() di np.split() – dividiamo l’array di 20 elementi nelle seguenti parti: 90%, 10%, 10%:

 In [45]: a = np.arange(1, 21) In [46]: a Out[46]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) In [47]: np.split(a, [int(.8 * len(a)), int(.9 * len(a))]) Out[47]: [array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), array([17, 18]), array([19, 20])] 

Nota:

La funzione è stata scritta per gestire il seeding della creazione di set randomizzati. Non dovresti fare affidamento sul set splitting che non randomizza i set.

 import numpy as np import pandas as pd def train_validate_test_split(df, train_percent=.6, validate_percent=.2, seed=None): np.random.seed(seed) perm = np.random.permutation(df.index) m = len(df.index) train_end = int(train_percent * m) validate_end = int(validate_percent * m) + train_end train = df.ix[perm[:train_end]] validate = df.ix[perm[train_end:validate_end]] test = df.ix[perm[validate_end:]] return train, validate, test 

Dimostrazione

 np.random.seed([3,1415]) df = pd.DataFrame(np.random.rand(10, 5), columns=list('ABCDE')) df 

inserisci la descrizione dell'immagine qui

 train, validate, test = train_validate_test_split(df) train 

inserisci la descrizione dell'immagine qui

 validate 

inserisci la descrizione dell'immagine qui

 test 

inserisci la descrizione dell'immagine qui

Tuttavia, un approccio per dividere il set di dati in train , test , cv con 0.6 , 0.2 , 0.2 sarebbe utilizzare il metodo train_test_split due volte.

 x, x_test, y, y_test = train_test_split(xtrain,labels,test_size=0.2,train_size=0.8) x_train, x_cv, y_train, y_cv = train_test_split(x,y,test_size = 0.25,train_size =0.75) 

Utilizza la funzione train_test_split due volte.

 from sklearn.cross_validation import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1) X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=1)