Respuestas:
Solo usaría numpy's randn
:
In [11]: df = pd.DataFrame(np.random.randn(100, 2))
In [12]: msk = np.random.rand(len(df)) < 0.8
In [13]: train = df[msk]
In [14]: test = df[~msk]
Y solo para ver esto ha funcionado:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
para < 0.8
dar sentido porque devuelve uniformemente distribuida números aleatorios entre 0 y 1.
in[12]
, in[13]
, in[14]
? Quiero entender el código de Python en sí mismo
np.random.rand(len(df))
es una matriz de tamaño len(df)
con valores flotantes distribuidos aleatoria y uniformemente en el rango [0, 1]. El < 0.8
aplica la comparación elemento a elemento y almacena el resultado en su lugar. Por lo tanto, los valores <0.8 se convierten True
y el valor> = 0.8 se conviertenFalse
scikit learn'strain_test_split
es bueno.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
kf = KFold(n, n_folds=folds) for train_index, test_index in kf: X_train, X_test = X.ix[train_index], X.ix[test_index]
vea el ejemplo completo aquí: quantstart.com/articles/…
from sklearn.model_selection import train_test_split
lugar.
from sklearn.cross_validation import train_test_split
La muestra aleatoria de pandas también funcionará
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
haciendo arg?
test
se desea un conjunto aleatorio como se indica aquí stackoverflow.com/questions/29576430/shuffle-dataframe-rows . test=df.drop(train.index).sample(frac=1.0)
Usaría el propio training_test_split de scikit-learn y lo generaría a partir del índice
from sklearn.model_selection import train_test_split
y = df.pop('output')
X = df
X_train,X_test,y_train,y_test = train_test_split(X.index,y,test_size=0.2)
X.iloc[X_train] # return dataframe train
cross_validation
módulo ahora está en desuso:DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
Hay muchas formas de crear un tren / prueba e incluso muestras de validación.
Caso 1: forma clásica train_test_split
sin ninguna opción:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Caso 2: caso de un conjunto de datos muy pequeño (<500 filas): para obtener resultados para todas sus líneas con esta validación cruzada. Al final, tendrá una predicción para cada línea de su conjunto de entrenamiento disponible.
from sklearn.model_selection import KFold
kf = KFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
reg = RandomForestRegressor(n_estimators=50, random_state=0)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
clf = reg.fit(X_train, y_train)
y_hat = clf.predict(X_test)
y_hat_all.append(y_hat)
Caso 3a: conjuntos de datos no balanceados para fines de clasificación. Siguiendo el caso 1, aquí está la solución equivalente:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.3)
Caso 3b: conjuntos de datos no balanceados para fines de clasificación. Siguiendo el caso 2, aquí está la solución equivalente:
from sklearn.model_selection import StratifiedKFold
kf = StratifiedKFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
reg = RandomForestRegressor(n_estimators=50, random_state=0)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
clf = reg.fit(X_train, y_train)
y_hat = clf.predict(X_test)
y_hat_all.append(y_hat)
Caso 4: necesita crear un conjunto de tren / prueba / validación en big data para sintonizar hiperparámetros (60% tren, 20% prueba y 20% val).
from sklearn.model_selection import train_test_split
X_train, X_test_val, y_train, y_test_val = train_test_split(X, y, test_size=0.6)
X_test, X_val, y_test, y_val = train_test_split(X_test_val, y_test_val, stratify=y, test_size=0.5)
Puede usar el siguiente código para crear muestras de prueba y entrenamiento:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
El tamaño de la prueba puede variar según el porcentaje de datos que desea incluir en su conjunto de datos de prueba y entrenamiento.
Hay muchas respuestas válidas. Agregando uno más al grupo. de sklearn.cross_validation import train_test_split
#gets a random 80% of the entire set
X_train = X.sample(frac=0.8, random_state=1)
#gets the left out portion of the dataset
X_test = X.loc[~df_model.index.isin(X_train.index)]
También puede considerar la división estratificada en conjunto de entrenamiento y prueba. La división Startified también genera un conjunto de entrenamiento y pruebas al azar, pero de tal manera que se preservan las proporciones originales de clase 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
df [train_inds] y df [test_inds] le brindan los conjuntos de entrenamiento y prueba de su DataFrame df original.
Si necesita dividir sus datos con respecto a la columna de etiquetas en su conjunto de datos, puede usar esto:
def split_to_train_test(df, label_column, train_frac=0.8):
train_df, test_df = pd.DataFrame(), pd.DataFrame()
labels = df[label_column].unique()
for lbl in labels:
lbl_df = df[df[label_column] == lbl]
lbl_train_df = lbl_df.sample(frac=train_frac)
lbl_test_df = lbl_df.drop(lbl_train_df.index)
print '\n%s:\n---------\ntotal:%d\ntrain_df:%d\ntest_df:%d' % (lbl, len(lbl_df), len(lbl_train_df), len(lbl_test_df))
train_df = train_df.append(lbl_train_df)
test_df = test_df.append(lbl_test_df)
return train_df, test_df
y úsalo:
train, test = split_to_train_test(data, 'class', 0.7)
También puede pasar random_state si desea controlar la aleatoriedad dividida o utilizar alguna semilla aleatoria global.
import pandas as pd
from sklearn.model_selection import train_test_split
datafile_name = 'path_to_data_file'
data = pd.read_csv(datafile_name)
target_attribute = data['column_name']
X_train, X_test, y_train, y_test = train_test_split(data, target_attribute, test_size=0.8)
Puede usar ~ (operador de tilde) para excluir las filas muestreadas usando df.sample (), dejando que solo los pandas manejen el muestreo y el filtrado de índices, para obtener dos conjuntos.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Esto es lo que escribí cuando necesitaba dividir un DataFrame. Pensé en usar el enfoque de Andy anterior, pero no me gustó que no pudiera controlar el tamaño de los conjuntos de datos exactamente (es decir, a veces sería 79, a veces 81, etc.).
def make_sets(data_df, test_portion):
import random as rnd
tot_ix = range(len(data_df))
test_ix = sort(rnd.sample(tot_ix, int(test_portion * len(data_df))))
train_ix = list(set(tot_ix) ^ set(test_ix))
test_df = data_df.ix[test_ix]
train_df = data_df.ix[train_ix]
return train_df, test_df
train_df, test_df = make_sets(data_df, 0.2)
test_df.head()
Simplemente seleccione la fila de rango de df como este
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
en su fragmento de código se baraja (o debería), mejorará la respuesta.
Hay muchas respuestas excelentes arriba, así que solo quiero agregar un ejemplo más en el caso de que desee especificar el número exacto de muestras para el tren y los conjuntos de prueba utilizando solo la numpy
biblioteca.
# set the random seed for the reproducibility
np.random.seed(17)
# e.g. number of samples for the training set is 1000
n_train = 1000
# shuffle the indexes
shuffled_indexes = np.arange(len(data_df))
np.random.shuffle(shuffled_indexes)
# use 'n_train' samples for training and the rest for testing
train_ids = shuffled_indexes[:n_train]
test_ids = shuffled_indexes[n_train:]
train_data = data_df.iloc[train_ids]
train_labels = labels_df.iloc[train_ids]
test_data = data_df.iloc[test_ids]
test_labels = data_df.iloc[test_ids]
Para dividirse en más de dos clases, tales como entrenamiento, prueba y validación, uno puede hacer:
probs = np.random.rand(len(df))
training_mask = probs < 0.7
test_mask = (probs>=0.7) & (probs < 0.85)
validatoin_mask = probs >= 0.85
df_training = df[training_mask]
df_test = df[test_mask]
df_validation = df[validatoin_mask]
Esto colocará aproximadamente el 70% de los datos en capacitación, el 15% en pruebas y el 15% en validación.
necesita convertir el marco de datos de pandas en una matriz numpy y luego volver a convertir la matriz numpy en un marco de datos
import pandas as pd
df=pd.read_csv('/content/drive/My Drive/snippet.csv', sep='\t')
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
train1=pd.DataFrame(train)
test1=pd.DataFrame(test)
train1.to_csv('/content/drive/My Drive/train.csv',sep="\t",header=None, encoding='utf-8', index = False)
test1.to_csv('/content/drive/My Drive/test.csv',sep="\t",header=None, encoding='utf-8', index = False)
Si su deseo es tener un marco de datos entrante y dos marcos de datos fuera (no matrices numpy), esto debería ser el truco:
def split_data(df, train_perc = 0.8):
df['train'] = np.random.rand(len(df)) < train_perc
train = df[df.train == 1]
test = df[df.train == 0]
split_data ={'train': train, 'test': test}
return split_data
Un poco más elegante para mi gusto es crear una columna aleatoria y luego dividirla, de esta manera podemos obtener una división que se adapte a nuestras necesidades y será aleatoria.
def split_df(df, p=[0.8, 0.2]):
import numpy as np
df["rand"]=np.random.choice(len(p), len(df), p=p)
r = [df[df["rand"]==val] for val in df["rand"].unique()]
return r
shuffle = np.random.permutation(len(df))
test_size = int(len(df) * 0.2)
test_aux = shuffle[:test_size]
train_aux = shuffle[test_size:]
TRAIN_DF =df.iloc[train_aux]
TEST_DF = df.iloc[test_aux]
No es necesario convertir a numpy. Simplemente use un pandas df para hacer la división y devolverá un pandas df.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
Y si quieres dividir x de y
X_train, X_test, y_train, y_test = train_test_split(df[list_of_x_cols], df[y_col],test_size=0.2)
¿Qué tal esto? df es mi marco de datos
total_size=len(df)
train_size=math.floor(0.66*total_size) (2/3 part of my dataset)
#training dataset
train=df.head(train_size)
#test dataset
test=df.tail(len(df) -train_size)
msk
es de dtypebool
,df[msk]
,df.iloc[msk]
ydf.loc[msk]
siempre devuelven el mismo resultado.