Відповіді:
Якщо ви хочете розділити набір даних один раз на дві половини, ви можете використовувати numpy.random.shuffle
або, numpy.random.permutation
якщо вам потрібно відслідковувати показники:
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
numpy.random.shuffle(x)
training, test = x[:80,:], x[80:,:]
або
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
indices = numpy.random.permutation(x.shape[0])
training_idx, test_idx = indices[:80], indices[80:]
training, test = x[training_idx,:], x[test_idx,:]
Є багато способів багаторазово розділити один і той же набір даних для перехресної перевірки . Однією із стратегій є повторна вибірка з набору даних з повторенням:
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
training_idx = numpy.random.randint(x.shape[0], size=80)
test_idx = numpy.random.randint(x.shape[0], size=20)
training, test = x[training_idx,:], x[test_idx,:]
Нарешті, sklearn містить кілька методів перехресної перевірки (k-fold , left -n-out, ...). Він також включає більш досконалі методи "стратифікованої вибірки", які створюють розділ даних, збалансований щодо деяких особливостей, наприклад, щоб переконатися, що однакова частка позитивних і негативних прикладів у навчальному та тестовому наборах.
Є ще один варіант, який просто тягне за собою використання scikit-learn. Як описано у wiki wiki , ви можете просто скористатись такими інструкціями:
from sklearn.model_selection import train_test_split
data, labels = np.arange(10).reshape((5, 2)), range(5)
data_train, data_test, labels_train, labels_test = train_test_split(data, labels, test_size=0.20, random_state=42)
Таким чином ви можете синхронізувати мітки для даних, які ви намагаєтесь розділити на тренування та тестування.
Просто записка. Якщо ви хочете набори поїздів, тестів та валідацій, ви можете зробити це:
from sklearn.cross_validation import train_test_split
X = get_my_X()
y = get_my_y()
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
x_test, x_val, y_test, y_val = train_test_split(x_test, y_test, test_size=0.5)
Ці параметри дадуть 70% навчанню, а 15% - тестуванню та встановленню наборів. Сподіваюся, це допомагає.
from sklearn.cross_validation import train_test_split
щоб було зрозуміло, який модуль ви використовуєте
a=0.7
, b=0.15
, c=0.15
, і d = dataset
, N=len(dataset)
, а потім x_train = dataset[0:int(a*N)]
, x_test = dataset[int(a*N):int((a+b)*N)]
і x_val = dataset[int((a+b)*N):]
.
from sklearn.model_selection import train_test_split
Ви також можете розглянути стратифікований поділ на навчальний і випробувальний набір. Посвідчений підрозділ також генерує випадкові набори та тестування, але таким чином, що зберігаються оригінальні пропорції класу. Це робить навчальні та тестувальні набори краще відображають властивості вихідного набору даних.
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
y = np.array([1,1,2,2,3,3])
train_inds,test_inds = get_train_test_inds(y,train_proportion=0.5)
print y[train_inds]
print y[test_inds]
Цей код виводить:
[1 2 3]
[1 2 3]
value_inds
це справді індекси, але результат не є індексами, а лише масками.
Я написав функцію для власного проекту, яка робить це (хоча в ньому не використовується numpy):
def partition(seq, chunks):
"""Splits the sequence into equal sized chunks and them as a list"""
result = []
for i in range(chunks):
chunk = []
for element in seq[i:len(seq):chunks]:
chunk.append(element)
result.append(chunk)
return result
Якщо ви хочете, щоб фрагменти були рандомізовані, просто перемішайте список, перш ніж передавати його.
Ось код для розділення даних на n = 5 складок стратифікованим способом
% X = data array
% y = Class_label
from sklearn.cross_validation import StratifiedKFold
skf = StratifiedKFold(y, n_folds=5)
for train_index, test_index in skf:
print("TRAIN:", train_index, "TEST:", test_index)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
Дякую pberkes за вашу відповідь. Я просто модифікував його, щоб уникнути (1) заміни, коли вибірки (2) повторюваних випадків відбувалися як під час навчання, так і під час тестування:
training_idx = np.random.choice(X.shape[0], int(np.round(X.shape[0] * 0.8)),replace=False)
training_idx = np.random.permutation(np.arange(X.shape[0]))[:np.round(X.shape[0] * 0.8)]
test_idx = np.setdiff1d( np.arange(0,X.shape[0]), training_idx)
Почитавши та взявши до уваги (багато ..) різні способи розподілу даних для тренування та тестування, я вирішив зробити це!
Я використав 4 різні методи (жоден з них не використовує бібліотеку sklearn, що, я впевнений, дасть найкращі результати, даючи добре розроблений і перевірений код):
метод 3 переміг далеко за найкоротший час, після цього метод 1, а методи 2 і 4 виявились насправді неефективними.
Код для 4-х різних методів, які я приуротив:
import numpy as np
arr = np.random.rand(100, 3)
X = arr[:,:2]
Y = arr[:,2]
spl = 0.7
N = len(arr)
sample = int(spl*N)
#%% Method 1: shuffle the whole matrix arr and then split
np.random.shuffle(arr)
x_train, x_test, y_train, y_test = X[:sample,:], X[sample:, :], Y[:sample, ], Y[sample:,]
#%% Method 2: shuffle the indecies and then shuffle and apply to X and Y
train_idx = np.random.choice(N, sample)
Xtrain = X[train_idx]
Ytrain = Y[train_idx]
test_idx = [idx for idx in range(N) if idx not in train_idx]
Xtest = X[test_idx]
Ytest = Y[test_idx]
#%% Method 3: shuffle indicies without a for loop
idx = np.random.permutation(arr.shape[0]) # can also use random.shuffle
train_idx, test_idx = idx[:sample], idx[sample:]
x_train, x_test, y_train, y_test = X[train_idx,:], X[test_idx,:], Y[train_idx,], Y[test_idx,]
#%% Method 4: using pandas dataframe to split
import pandas as pd
df = pd.read_csv(file_path, header=None) # Some csv file (I used some file with 3 columns)
train = df.sample(frac=0.7, random_state=200)
test = df.drop(train.index)
І час, мінімальний час для виконання 3-х повторів з 1000 циклів:
Я сподіваюся, що це корисно!
Ймовірно, вам не потрібно буде тільки розділити на поїзд та тестування, але й перехрестити перевірку, щоб переконатися, що модель узагальнена. Тут я припускаю 70% даних тренувань, 20% перевірки та 10% даних про проведення випробувань.
Перевірте np.split :
Якщо index_or_sections - це одновимірний масив відсортованих цілих чисел, записи вказують, де вздовж осі масив розділений. Наприклад, [2, 3] для осі = 0 призведе до
арі [: 2] арі [2: 3] арі [3:]
t, v, h = np.split(df.sample(frac=1, random_state=1), [int(0.7*len(df)), int(0.9*len(df))])
Розділити на тест на поїзд і дійсний
x =np.expand_dims(np.arange(100), -1)
print(x)
indices = np.random.permutation(x.shape[0])
training_idx, test_idx, val_idx = indices[:int(x.shape[0]*.9)], indices[int(x.shape[0]*.9):int(x.shape[0]*.95)], indices[int(x.shape[0]*.9):int(x.shape[0]*.95)]
training, test, val = x[training_idx,:], x[test_idx,:], x[val_idx,:]
print(training, test, val)