Respostas:
Eu usaria apenas 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]
E só para ver isso funcionou:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
para < 0.8
fazer sentido porque ele retorna uniformemente distribuído números aleatórios entre 0 e 1.
in[12]
, in[13]
, in[14]
? Eu quero entender o próprio código python aqui
np.random.rand(len(df))
é uma matriz de tamanho len(df)
com valores flutuantes distribuídos aleatoriamente e uniformemente no intervalo [0, 1]. O < 0.8
aplica a comparação elemento a elemento e armazena o resultado no local. Assim valores <0,8 tornou True
eo valor> = 0,8 tornarFalse
o scikit learn'strain_test_split
é bom.
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]
veja exemplo completo aqui: quantstart.com/articles/…
from sklearn.model_selection import train_test_split
alternativa.
from sklearn.cross_validation import train_test_split
A amostra aleatória do Pandas também funcionará
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
arg está fazendo?
test
conjunto aleatório for desejado, como indicado aqui stackoverflow.com/questions/29576430/shuffle-dataframe-rows . test=df.drop(train.index).sample(frac=1.0)
Eu usaria o training_test_split do scikit-learn e o geraria a partir do í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 agora está 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.
Existem várias maneiras de criar um trem / teste e até amostras de validação.
Caso 1: maneira clássica, train_test_split
sem opções:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Caso 2: caso de conjuntos de dados muito pequenos (<500 linhas): para obter resultados para todas as suas linhas com essa validação cruzada. No final, você terá uma previsão para cada linha do seu conjunto de treinamento disponível.
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 dados desequilibrados para fins de classificação. Seguindo o caso 1, aqui está a solução 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 dados desequilibrados para fins de classificação. Seguindo o caso 2, aqui está a solução 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: você precisa criar um conjunto de treinamento / teste / validação no big data para ajustar os hiperparâmetros (60% de treinamento, 20% de teste e 20% de 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)
Você pode usar o código abaixo para criar amostras de teste e treinamento:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
O tamanho do teste pode variar dependendo da porcentagem de dados que você deseja colocar no seu teste e treinar o conjunto de dados.
Existem muitas respostas válidas. Adicionando mais um ao 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)]
Você também pode considerar a divisão estratificada em conjunto de treinamento e teste. A divisão iniciada também gera um conjunto de treinamento e teste aleatoriamente, mas de maneira que as proporções originais da classe sejam preservadas. Isso faz com que os conjuntos de treinamento e teste reflitam melhor as propriedades do conjunto de dados 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] e df [test_inds] fornecem os conjuntos de treinamento e teste do seu DataFrame df original.
Se você precisar dividir seus dados com relação à coluna lables no seu conjunto de dados, poderá usar este:
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 use-o:
train, test = split_to_train_test(data, 'class', 0.7)
você também pode passar random_state se desejar controlar a aleatoriedade de divisão ou usar alguma semente aleatória 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)
Você pode usar ~ (operador til) para excluir as linhas amostradas usando df.sample (), permitindo que os pandas gerenciem sozinho a amostragem e a filtragem de índices para obter dois conjuntos.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Foi o que escrevi quando precisei dividir um DataFrame. Eu considerei usar a abordagem de Andy acima, mas não gostei de não poder controlar exatamente o tamanho dos conjuntos de dados (ou seja, às vezes seria 79, às vezes 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()
Basta selecionar a linha do intervalo de df assim
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
no seu snippet de código é (ou deveria ser) embaralhado, a resposta será melhorada.
Há muitas ótimas respostas acima, então só quero adicionar mais um exemplo, caso você queira especificar o número exato de amostras para os conjuntos de trem e teste usando apenas a 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 dividir em mais de duas classes, como treinamento, teste e validação, é possível:
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]
Isso colocará aproximadamente 70% dos dados em treinamento, 15% em teste e 15% em validação.
você precisa converter o quadro de dados do pandas em matriz numpy e, em seguida, converter a matriz numpy novamente em quadro de dados
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 seu desejo é ter um quadro de dados dentro e dois quadros de dados fora (não matrizes numpy), isso deve fazer o truque:
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
Um pouco mais elegante para o meu gosto é criar uma coluna aleatória e depois dividi-la, dessa forma, podemos obter uma divisão que atenda às nossas necessidades e que seja aleatória.
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]
Não há necessidade de converter para numpy. Basta usar um pandas df para fazer a divisão e ele retornará um pandas df.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
E se você quiser 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)
Que tal agora? df é meu dataframe
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
é de dtipobool
,df[msk]
,df.iloc[msk]
edf.loc[msk]
sempre retornam o mesmo resultado.