Risposte:
Se vuoi dividere il set di dati una volta in due metà, puoi usare numpy.random.shuffle
, o numpy.random.permutation
se devi tenere traccia degli indici:
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
numpy.random.shuffle(x)
training, test = x[:80,:], x[80:,:]
o
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
indices = numpy.random.permutation(x.shape[0])
training_idx, test_idx = indices[:80], indices[80:]
training, test = x[training_idx,:], x[test_idx,:]
Esistono molti modi per partizionare ripetutamente lo stesso set di dati per la convalida incrociata . Una strategia consiste nel ricampionare dal set di dati, con la ripetizione:
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
training_idx = numpy.random.randint(x.shape[0], size=80)
test_idx = numpy.random.randint(x.shape[0], size=20)
training, test = x[training_idx,:], x[test_idx,:]
Infine, sklearn contiene diversi metodi di convalida incrociata (k-fold, leave-n-out, ...). Include anche metodi più avanzati di "campionamento stratificato" che creano una partizione dei dati bilanciata rispetto ad alcune caratteristiche, ad esempio per assicurarsi che ci sia la stessa proporzione di esempi positivi e negativi nel set di addestramento e test.
C'è un'altra opzione che implica solo l'uso di scikit-learn. Come descrive il wiki di scikit , puoi semplicemente usare le seguenti istruzioni:
from sklearn.model_selection import train_test_split
data, labels = np.arange(10).reshape((5, 2)), range(5)
data_train, data_test, labels_train, labels_test = train_test_split(data, labels, test_size=0.20, random_state=42)
In questo modo puoi mantenere sincronizzate le etichette per i dati che stai cercando di suddividere in addestramento e test.
Solo una nota. Nel caso in cui desideri addestrare, testare E set di convalida, puoi farlo:
from sklearn.cross_validation import train_test_split
X = get_my_X()
y = get_my_y()
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
x_test, x_val, y_test, y_val = train_test_split(x_test, y_test, test_size=0.5)
Questi parametri daranno il 70% all'addestramento e il 15% ciascuno ai set di test e val. Spero che questo ti aiuti.
from sklearn.cross_validation import train_test_split
per chiarire quale modulo stai usando
a=0.7
, b=0.15
, c=0.15
, e d = dataset
, N=len(dataset)
quindi x_train = dataset[0:int(a*N)]
, x_test = dataset[int(a*N):int((a+b)*N)]
e x_val = dataset[int((a+b)*N):]
.
from sklearn.model_selection import train_test_split
Poiché il sklearn.cross_validation
modulo è stato deprecato, puoi utilizzare:
import numpy as np
from sklearn.model_selection import train_test_split
X, y = np.arange(10).reshape((5, 2)), range(5)
X_trn, X_tst, y_trn, y_tst = train_test_split(X, y, test_size=0.2, random_state=42)
Puoi anche considerare la divisione stratificata in set di addestramento e test. La divisione startificata genera anche training e test set casualmente, ma in modo tale da preservare le proporzioni originali della classe. In questo modo i set di addestramento e test riflettono meglio le proprietà del set di dati originale.
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
testing 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]
Questo codice restituisce:
[1 2 3]
[1 2 3]
value_inds
sono veramente indici, ma l'output non sono indici, solo maschere.
Ho scritto una funzione per il mio progetto per farlo (non usa numpy, però):
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
Se vuoi che i blocchi siano randomizzati, rimescola l'elenco prima di passarlo.
Ecco un codice per suddividere i dati in n = 5 pieghe in modo stratificato
% 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]
Grazie Pberkes per la tua risposta. L'ho appena modificato per evitare (1) la sostituzione durante il campionamento (2) di istanze duplicate sia nell'addestramento che nel 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)
Dopo aver letto un po 'e tenendo conto dei (molti ..) diversi modi di suddividere i dati da allenare e testare, ho deciso di timeit!
Ho usato 4 metodi diversi (nessuno dei quali utilizza la libreria sklearn, che sono sicuro darà i migliori risultati, dato che è un codice ben progettato e testato):
il metodo 3 ha vinto di gran lunga con il tempo più breve, dopo quel metodo 1, e il metodo 2 e 4 si sono rivelati davvero inefficienti.
Il codice per i 4 diversi metodi che ho cronometrato:
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)
E per i tempi, il tempo minimo per eseguire su 3 ripetizioni di 1000 loop è:
Spero sia utile!
Probabilmente non sarà solo necessario suddividere in training e test, ma anche una convalida incrociata per assicurarsi che il modello sia generalizzato. Qui presumo il 70% di dati di addestramento, il 20% di convalida e il 10% di dati di controllo / test.
Se indices_or_sections è un array 1-D di numeri interi ordinati, le voci indicano il punto in cui l'array è suddiviso lungo l'asse. Ad esempio, [2, 3], per asse = 0, restituirebbe
ary [: 2] ary [2: 3] ary [3:]
t, v, h = np.split(df.sample(frac=1, random_state=1), [int(0.7*len(df)), int(0.9*len(df))])
Diviso in test del treno e valido
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)