Odpowiedzi:
Po prostu użyłbym 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]
I tylko po to, aby zobaczyć, jak to działa:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
do < 0.8
sensu, ponieważ zwraca liczb losowych równomiernie rozłożone pomiędzy 0 a 1.
in[12]
, in[13]
, in[14]
? Chcę zrozumieć sam kod python tutaj
np.random.rand(len(df))
to tablica wielkości len(df)
z losowo i równomiernie rozmieszczonymi wartościami zmiennoprzecinkowymi w zakresie [0, 1]. < 0.8
Stosuje porównanie elementem mądry i zapisuje wynik w miejscu. Zatem wartości <0,8 stają się True
i wartość> = 0,8 stają sięFalse
scikit learn'strain_test_split
jest dobry.
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]
pełny przykład tutaj: quantstart.com/articles/…
from sklearn.model_selection import train_test_split
zamiast tego.
from sklearn.cross_validation import train_test_split
Działa również losowa próbka pand
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
robi arg?
test
pożądany jest zestaw losowy, jak wskazano tutaj stackoverflow.com/questions/29576430/shuffle-dataframe-rows . test=df.drop(train.index).sample(frac=1.0)
Korzystałbym z własnego Training_test_split scikit-learn i generowałem go z indeksu
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
Moduł jest teraz przestarzała: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.
Istnieje wiele sposobów tworzenia pociągu / testu, a nawet próbek walidacyjnych.
Przypadek 1: klasyczny sposób train_test_split
bez żadnych opcji:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Przypadek 2: przypadek bardzo małych zestawów danych (<500 wierszy): w celu uzyskania wyników dla wszystkich linii z tą weryfikacją krzyżową. Na koniec będziesz mieć jedną prognozę dla każdej linii dostępnego zestawu treningowego.
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)
Przypadek 3a: Niezrównoważone zestawy danych do celów klasyfikacji. Zgodnie z przypadkiem 1, oto równoważne rozwiązanie:
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)
Przypadek 3b: Niezrównoważone zestawy danych do celów klasyfikacji. Zgodnie z przypadkiem 2, oto równoważne rozwiązanie:
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)
Przypadek 4: musisz stworzyć zestawy pociągów / testów / walidacji na dużych danych, aby dostroić hiperparametry (60% pociągu, 20% testu i 20% wartości).
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)
Możesz użyć poniższego kodu, aby utworzyć próbki testowe i szkolić:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
Rozmiar testu może się różnić w zależności od odsetka danych, które chcesz umieścić w zestawie danych testu i pociągu.
Istnieje wiele poprawnych odpowiedzi. Dodanie jeszcze jednego do grona. ze 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)]
Możesz także rozważyć podział warstwowy na zestaw szkoleniowy i testowy. Podział startowy generuje również zestaw treningów i testów losowo, ale w taki sposób, aby zachować oryginalne proporcje klas. Dzięki temu zestawy szkoleniowe i testowe lepiej odzwierciedlają właściwości oryginalnego zestawu danych.
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] i df [test_inds] zapewniają zestawy szkoleniowe i testowe oryginalnej DataFrame df.
Jeśli chcesz podzielić dane w odniesieniu do kolumny lables w zestawie danych, możesz użyć tego:
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
i użyj go:
train, test = split_to_train_test(data, 'class', 0.7)
możesz także przekazać parametr random_state, jeśli chcesz kontrolować losowość podzieloną lub użyć globalnego źródła losowego.
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)
Możesz użyć ~ (operator tyldy), aby wykluczyć wiersze próbkowane za pomocą df.sample (), pozwalając pandom samodzielnie obsługiwać próbkowanie i filtrowanie indeksów, aby uzyskać dwa zestawy.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
To właśnie napisałem, gdy potrzebowałem podzielić ramkę danych. Zastanawiałem się nad zastosowaniem powyższego podejścia Andy'ego, ale nie podobało mi się, że nie mogłem dokładnie kontrolować wielkości zbiorów danych (tj. Czasami byłoby to 79, a czasem 81 itd.).
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()
Wystarczy wybrać wiersz zakresu z df w ten sposób
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
fragment kodu jest (lub powinien być) tasowany, poprawi to odpowiedź.
Istnieje wiele świetnych odpowiedzi powyżej, więc chcę tylko dodać jeszcze jeden przykład w przypadku, gdy chcesz określić dokładną liczbę próbek dla pociągu i zestawów testowych, używając tylko numpy
biblioteki.
# 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]
Aby podzielić na więcej niż dwie klasy, takie jak szkolenie, test i walidacja, można:
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]
W ten sposób około 70% danych będzie szkolonych, 15% w teście, a 15% w walidacji.
musisz przekonwertować ramkę danych pandy na tablicę numpy, a następnie przekonwertować tablicę numpy z powrotem na ramkę danych
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)
Jeśli chcesz mieć jedną ramkę danych i dwie ramki danych (nie tablic numpy), powinno to załatwić sprawę:
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
Nieco bardziej eleganckie według mnie jest utworzenie losowej kolumny, a następnie podzielenie przez nią, w ten sposób możemy uzyskać podział, który będzie odpowiadał naszym potrzebom i będzie losowy.
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
Co powiesz na to? df jest moją ramką danych
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)
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]
msk
jest dtypebool
,df[msk]
,df.iloc[msk]
idf.loc[msk]
zawsze zwraca ten sam wynik.