Risposte:
Vorrei solo usare numpy 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]
E solo per vedere che ha funzionato:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
per < 0.8
avere un senso perché restituisce numeri casuali distribuiti uniformemente tra 0 e 1.
in[12]
, in[13]
, in[14]
? Voglio capire il codice python stesso qui
np.random.rand(len(df))
è un array di dimensioni len(df)
con valori float distribuiti in modo casuale e uniforme nell'intervallo [0, 1]. L' < 0.8
vale il confronto elemento-saggio e memorizza il risultato in luogo. Quindi i valori <0,8 diventano True
e valore> = 0,8 diventanoFalse
scikit learn'strain_test_split
è buono.
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]
guarda l'esempio completo qui: quantstart.com/articles/…
from sklearn.model_selection import train_test_split
invece.
from sklearn.cross_validation import train_test_split
Anche il campione casuale di Panda funzionerà
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
facendo arg?
test
si desidera un set mischiato come indicato qui stackoverflow.com/questions/29576430/shuffle-dataframe-rows . test=df.drop(train.index).sample(frac=1.0)
Vorrei usare il training_test_split di scikit-learn e generarlo dall'indice
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
modulo è ora obsoleto: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.
Esistono molti modi per creare un treno / test e persino campioni di validazione.
Caso 1: modo classico train_test_split
senza opzioni:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Caso 2: caso di set di dati molto piccoli (<500 righe): per ottenere risultati per tutte le linee con questa convalida incrociata. Alla fine, avrai una previsione per ogni linea del tuo set di allenamento disponibile.
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: set di dati non bilanciati ai fini della classificazione. Di seguito al caso 1, ecco la soluzione 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: set di dati non bilanciati ai fini della classificazione. Di seguito al caso 2, ecco la soluzione 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: è necessario creare un treno / test / set di validazione su big data per ottimizzare gli iperparametri (60% di treno, 20% di test e 20% di 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)
È possibile utilizzare il codice seguente per creare campioni di prova e di addestramento:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
Le dimensioni del test possono variare in base alla percentuale di dati che si desidera inserire nel set di dati del test e del training.
Ci sono molte risposte valide. Aggiungerne uno in più al gruppo. da 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)]
Puoi anche considerare la divisione stratificata in set di addestramento e test. La divisione Starificata genera anche addestramento e test impostati casualmente ma in modo tale da preservare le proporzioni di classe originali. In questo modo i set di training 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
df [train_inds] e df [test_inds] offrono i set di addestramento e test del DataFrame df originale.
Se hai bisogno di dividere i tuoi dati rispetto alla colonna lables nel tuo set di dati puoi usare questo:
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
e usalo:
train, test = split_to_train_test(data, 'class', 0.7)
puoi anche passare random_state se vuoi controllare la casualità divisa o usare un seme casuale globale.
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)
Puoi usare ~ (operatore tilde) per escludere le righe campionate usando df.sample (), lasciando che solo i panda gestiscano il campionamento e il filtraggio degli indici, per ottenere due set.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Questo è quello che ho scritto quando avevo bisogno di dividere un DataFrame. Ho preso in considerazione l'utilizzo dell'approccio di Andy sopra, ma non mi è piaciuto non poter controllare esattamente la dimensione dei set di dati (cioè, a volte sarebbe 79, a volte 81, ecc.).
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()
Basta selezionare la riga di intervallo da df in questo modo
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
snippet di codice è (o dovrebbe essere) mischiato, migliorerà la risposta.
Ci sono molte ottime risposte sopra, quindi voglio solo aggiungere un altro esempio nel caso in cui si desideri specificare il numero esatto di campioni per il treno e i set di test utilizzando solo la numpy
libreria.
# 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]
Per dividere in più di due classi come treno, test e validazione, si può fare:
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]
Questo metterà circa il 70% dei dati in formazione, il 15% in prova e il 15% in validazione.
è necessario convertire i frame di dati Panda in array numpy e quindi convertire l'array numpy in frame di dati
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)
Se il tuo desiderio è quello di avere un frame di dati in entrata e due di frame di dati in uscita (non array intorpiditi), questo dovrebbe fare il trucco:
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 po 'più elegante per i miei gusti è quello di creare una colonna casuale e quindi dividerla, in questo modo possiamo ottenere una divisione che soddisfi le nostre esigenze e sarà casuale.
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]
Non è necessario convertire in numpy. Basta usare un panda df per fare la divisione e restituirà un panda df.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
E se vuoi dividere x da y
X_train, X_test, y_train, y_test = train_test_split(df[list_of_x_cols], df[y_col],test_size=0.2)
Cosa ne pensi di questo? df è il mio frame di dati
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
è di DTYPEbool
,df[msk]
,df.iloc[msk]
edf.loc[msk]
tornare sempre lo stesso risultato.