2010-09-09 44 views

Respuesta

71

Si desea dividir el conjunto de datos una vez en dos mitades, puede utilizar numpy.random.shuffle o numpy.random.permutation si necesita hacer un seguimiento de los índices:

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,:] 

Hay hay muchas formas de repeatedly partition the same data set for cross validation. Una estrategia es volver a muestrear a partir del conjunto de datos, con la repetición:

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,:] 

Por último, sklearn contiene several cross validation methods (k veces, deje-N-Out, ...). También incluye métodos más avanzados "stratified sampling" que crean una partición de los datos que está equilibrada con respecto a algunas características, por ejemplo para asegurarse de que haya la misma proporción de ejemplos positivos y negativos en el conjunto de entrenamiento y prueba.

+7

gracias por estos soluciones. Pero, ¿no es cierto que el último método, usando randint, tiene buenas posibilidades de proporcionar los mismos índices para los conjuntos de prueba y entrenamiento? – ggauravr

0

escribí una función para mi propio proyecto para hacer esto (que no utiliza numpy, sin embargo):

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 desea que los trozos que se asignaron al azar, simplemente barajar la lista antes de pasarla en

24

Hay otra opción que solo implica el uso de scikit-learn. Como scikit's wiki describes, sólo puede utilizar las siguientes instrucciones:

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) 

esta manera se puede mantener en sincronía las etiquetas para los datos que está tratando de dividir a la formación y la prueba.

4

También puede considerar la división estratificada en un conjunto de entrenamiento y prueba. La división iniciada también genera un conjunto de entrenamiento y prueba al azar, pero de tal manera que se conservan las proporciones de clase originales. Esto hace que los conjuntos de entrenamiento y prueba reflejen mejor las propiedades del conjunto de datos original.

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] 

Este código salidas:

[1 2 3] 
[1 2 3] 
+0

¡Gracias! La denominación es algo engañosa, 'value_inds' son realmente índices, pero los resultados no son índices, solo máscaras. – greenoldman

18

sólo una nota. En caso de que quiera tren, probar y conjuntos de validación, usted puede hacer esto:

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) 

Estos parámetros darán 70% a la formación, y el 15% cada uno para probar y conjuntos val. Espero que esto ayude.

+4

probablemente debería agregar esto a su código: 'from sklearn.cross_validation import train_test_split' para dejar en claro qué módulo está usando – Radix

+0

¿Tiene que ser aleatorio? – liang

+0

Es decir, ¿es posible dividir según el orden dado por X e y? – liang

0

Aquí es un código para dividir los datos en n = 5 pliegues de forma estratificada

% 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] 
0

, gracias pberkes por su respuesta.Yo sólo lo modificó para evitar (1) reemplazo mientras prueba (2) casos duplicados se produjeron tanto en la formación y las pruebas:

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) 
6

Como está desfasada sklearn.cross_validation módulo, se pueden utilizar:

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) 
Cuestiones relacionadas