Відповіді:
Я просто використовую 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]
А щоб побачити це спрацювало:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
щоб < 0.8
мати сенс , оскільки вона повертає рівномірно розподілені випадкові числа в діапазоні від 0 до 1.
in[12]
, in[13]
, in[14]
? Я хочу зрозуміти тут сам код пітона
np.random.rand(len(df))
- це масив розмірів len(df)
з випадковими і рівномірно розподіленими значеннями поплавків у діапазоні [0, 1]. < 0.8
Застосовується порівняння поелементно і зберігає результат на місці. Таким чином, значення <0,8 стають, True
а значення> = 0,8 стаютьFalse
scikit learn'strain_test_split
- хороший.
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]
дивіться повний приклад тут: Quantstart.com/articles/…
from sklearn.model_selection import train_test_split
натомість.
from sklearn.cross_validation import train_test_split
Випадкова вибірка панди також буде працювати
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
аргумент?
test
набір, як зазначено тут stackoverflow.com/questions/29576430/shuffle-dataframe-row . test=df.drop(train.index).sample(frac=1.0)
Я би використовував scikit-learn власний training_test_split і генерував його з індексу
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
модуль застарілий: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.
Існує багато способів створити зразки поїздів / тестів і навіть перевірку валідації.
Випадок 1: класичний спосіб train_test_split
без будь-яких варіантів:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Випадок 2: випадок дуже малих наборів даних (<500 рядків): щоб отримати результати для всіх ваших рядків із цією перехресною валідацією. Зрештою, у вас буде один прогноз для кожного рядка вашого доступного навчального набору.
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)
Випадок 3a: Неврівноважені набори даних для цілей класифікації. Виходячи із випадку 1, ось рівнозначне рішення:
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)
Випадок 3b: Неврівноважені набори даних для цілей класифікації. Виходячи із випадку 2, ось рівнозначне рішення:
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)
Випадок 4: Вам потрібно створити набори поїздів / тестів / валідації на великих даних для налаштування гіперпараметрів (60% поїздів, 20% тесту та 20% валу).
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)
Ви можете використовувати код нижче для створення тестових та тренувальних зразків:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
Розмір тесту може змінюватись залежно від відсотка даних, які ви хочете ввести у свій набір даних тестів та поїздів.
Ви також можете розглянути стратифікований поділ на навчальний і тестовий набір. Запропонований поділ також генерує навчальний і тестовий набір випадковим чином, але таким чином, щоб збереглися початкові пропорції класу. Це робить набори для навчання та тестування краще відображати властивості вихідного набору даних.
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] та df [test_inds] надають вам навчальні та тестові набори вашого оригінального DataFrame df.
Якщо вам потрібно розділити свої дані стосовно стовпця міток у вашому наборі даних, ви можете скористатися цим:
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
і використовуйте його:
train, test = split_to_train_test(data, 'class', 0.7)
Ви також можете передавати random_state, якщо ви хочете контролювати випадкову поділку або використовувати деяке глобальне випадкове насіння.
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)
Ви можете використовувати ~ (tilde operator), щоб виключити рядки, відібрані за допомогою df.sample (), дозволяючи пандам самостійно обробляти вибірки та фільтрувати індекси, щоб отримати два набори.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Це я написав, коли мені потрібно було розділити DataFrame. Я розглядав можливість використання підходу Енді вище, але мені не сподобалося, що я не міг точно контролювати розмір наборів даних (тобто, це було б іноді 79, іноді 81 і т.д.).
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()
Просто виберіть рядок діапазону з df, як це
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
у вашому фрагменті коду перетасовано (або має бути), це відповідь покращить.
Вище є багато чудових відповідей, тому я просто хочу додати ще один приклад у випадку, якщо ви хочете вказати точну кількість зразків для поїздів і тестових наборів, використовуючи лише numpy
бібліотеку.
# 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]
Для поділу на більш ніж два класи, такі як поїзд, тест та перевірка, можна зробити:
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]
Це дасть приблизно 70% даних у навчанні, 15% у тесті та 15% у валідації.
вам потрібно перетворити фрейм даних панд в numpy масив, а потім перетворити numpy масив назад в кадр даних
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)
Якщо ви бажаєте мати один кадр даних та два фрейми даних (а не нумерові масиви), це має зробити:
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
На мій смак трохи елегантніше - створити випадковий стовпчик, а потім розділити його, таким чином ми можемо отримати розкол, який буде відповідати нашим потребам і буде випадковим.
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
Як щодо цього? df - мій кадр даних
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
має DTYPEbool
,df[msk]
,df.iloc[msk]
іdf.loc[msk]
завжди повертають один і той же результат.