Ответы:
Я бы просто использовал 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]
И просто чтобы увидеть это сработало:
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]
? Я хочу понять сам код Python здесь
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-rows . test=df.drop(train.index).sample(frac=1.0)
Я бы использовал собственный обучающий тест scikit-learn и сгенерировал бы его из индекса
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)
Размер теста может варьироваться в зависимости от процента данных, которые вы хотите поместить в свой набор данных теста и обучения.
Есть много действительных ответов. Добавляем еще один в кучу. из 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)]
Вы также можете рассмотреть разделение на учебно-испытательный комплекс. Подразделение Startered также генерирует наборы для обучения и тестирования случайным образом, но таким образом, что сохраняются исходные пропорции классов. Это позволяет обучающим и тестовым наборам лучше отражать свойства исходного набора данных.
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] дают вам наборы для обучения и тестирования вашего оригинального 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)
Вы можете использовать ~ (оператор тильды), чтобы исключить строки, выбранные с помощью 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% для проверки.
вам нужно преобразовать pandas dataframe в массив 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
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]
Не нужно конвертировать в NumPy. Просто используйте pandas df для разделения, и он вернет pandas df.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
И если вы хотите разделить х от у
X_train, X_test, y_train, y_test = train_test_split(df[list_of_x_cols], df[y_col],test_size=0.2)
Я думаю, вам также нужно получить копию, а не фрагмент данных, если вы хотите добавить столбцы позже.
msk = np.random.rand(len(df)) < 0.8
train, test = df[msk].copy(deep = True), df[~msk].copy(deep = True)
Как насчет этого? 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)
msk
имеет DTYPEbool
,df[msk]
,df.iloc[msk]
иdf.loc[msk]
всегда возвращают один и тот же результат.