126 votes

Comment diviser/partitionner un ensemble de données en ensembles de données de formation et de test pour, par exemple, la validation croisée ?

Quelle est la bonne façon de diviser un tableau NumPy de façon aléatoire en deux ensembles de données : formation et test/validation ? Quelque chose de similaire à la méthode cvpartition o crossvalind dans Matlab.

2voto

rotem Points 29

Après avoir lu quelques articles et pris en compte les (nombreuses ) différentes façons de diviser les données pour former et tester, j'ai décidé d'utiliser le timeit !

J'ai utilisé 4 méthodes différentes (aucune d'entre elles n'utilise la bibliothèque sklearn, qui, j'en suis sûr, donnera les meilleurs résultats, étant donné que le code est bien conçu et testé) :

  1. mélanger la matrice entière et ensuite diviser les données pour former et tester.
  2. mélanger les indices et ensuite leur attribuer x et y pour diviser les données
  3. même méthode que la méthode 2, mais d'une manière plus efficace de le faire
  4. utiliser le dataframe de pandas pour diviser

La méthode 3 l'a emporté de loin avec le temps le plus court, suivie de la méthode 1, et les méthodes 2 et 4 se sont révélées vraiment inefficaces.

Le code pour les 4 différentes méthodes que j'ai chronométrées :

import numpy as np
arr = np.random.rand(100, 3)
X = arr[:,:2]
Y = arr[:,2]
spl = 0.7
N = len(arr)
sample = int(spl*N)

#%% Method 1:  shuffle the whole matrix arr and then split
np.random.shuffle(arr)
x_train, x_test, y_train, y_test = X[:sample,:], X[sample:, :], Y[:sample, ], Y[sample:,]

#%% Method 2: shuffle the indecies and then shuffle and apply to X and Y
train_idx = np.random.choice(N, sample)
Xtrain = X[train_idx]
Ytrain = Y[train_idx]

test_idx = [idx for idx in range(N) if idx not in train_idx]
Xtest = X[test_idx]
Ytest = Y[test_idx]

#%% Method 3: shuffle indicies without a for loop
idx = np.random.permutation(arr.shape[0])  # can also use random.shuffle
train_idx, test_idx = idx[:sample], idx[sample:]
x_train, x_test, y_train, y_test = X[train_idx,:], X[test_idx,:], Y[train_idx,], Y[test_idx,]

#%% Method 4: using pandas dataframe to split
import pandas as pd
df = pd.read_csv(file_path, header=None) # Some csv file (I used some file with 3 columns)

train = df.sample(frac=0.7, random_state=200)
test = df.drop(train.index)

Et pour les temps, le temps minimum à exécuter sur 3 répétitions de 1000 boucles est :

  • Méthode 1 : 0,35883826200006297 secondes
  • Méthode 2 : 1,7157016959999964 secondes
  • Méthode 3 : 1,7876616719995582 secondes
  • Méthode 4 : 0,07562861499991413 secondes

J'espère que c'est utile !

1voto

Colin Points 2197

J'ai écrit une fonction pour mon propre projet pour faire cela (il n'utilise pas numpy, cependant) :

def partition(seq, chunks):
    """Splits the sequence into equal sized chunks and them as a list"""
    result = []
    for i in range(chunks):
        chunk = []
        for element in seq[i:len(seq):chunks]:
            chunk.append(element)
        result.append(chunk)
    return result

Si vous voulez que les morceaux soient aléatoires, il suffit de mélanger la liste avant de la transmettre.

1voto

Divisé en test de train et valide

x =np.expand_dims(np.arange(100), -1)

print(x)

indices = np.random.permutation(x.shape[0])

training_idx, test_idx, val_idx = indices[:int(x.shape[0]*.9)], indices[int(x.shape[0]*.9):int(x.shape[0]*.95)],  indices[int(x.shape[0]*.9):int(x.shape[0]*.95)]

training, test, val = x[training_idx,:], x[test_idx,:], x[val_idx,:]

print(training, test, val)

0voto

prashanth Points 1453

Voici un code pour diviser les données en n=5 plis de manière stratifiée

% X = data array
% y = Class_label
from sklearn.cross_validation import StratifiedKFold
skf = StratifiedKFold(y, n_folds=5)
for train_index, test_index in skf:
    print("TRAIN:", train_index, "TEST:", test_index)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

0voto

Zahran Points 381

Merci pberkes pour votre réponse. Je l'ai juste modifié pour éviter (1) le remplacement pendant l'échantillonnage (2) les instances dupliquées qui se sont produites à la fois dans la formation et le test :

training_idx = np.random.choice(X.shape[0], int(np.round(X.shape[0] * 0.8)),replace=False)
training_idx = np.random.permutation(np.arange(X.shape[0]))[:np.round(X.shape[0] * 0.8)]
    test_idx = np.setdiff1d( np.arange(0,X.shape[0]), training_idx)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X