NumPy dizisini rastgele olarak eğitim ve test / doğrulama veri kümesine bölmenin iyi bir yolu nedir? Matlab'daki cvpartition
veya crossvalind
işlevlerine benzer bir şey .
Yanıtlar:
Veri kümesini ikiye bölmek isterseniz, kullanabilirsiniz numpy.random.shuffle
veya numpy.random.permutation
endeksleri takip etmeniz gerekiyorsa:
import numpy
# x is your dataset
x = numpy.random.rand(100, 5)
numpy.random.shuffle(x)
training, test = x[:80,:], x[80:,:]
veya
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,:]
Çapraz doğrulama için aynı veri kümesini tekrar tekrar bölümlemenin birçok yolu vardır . Bir strateji, veri kümesinden tekrar ederek yeniden örneklemektir:
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,:]
Son olarak, sklearn birkaç çapraz doğrulama yöntemi içerir (k-katlama, dışarıda bırakma, ...). Aynı zamanda, örneğin eğitim ve test setinde aynı oranda olumlu ve olumsuz örneklerin bulunduğundan emin olmak için, verilerin bazı özelliklere göre dengelenmiş bir bölümünü oluşturan daha gelişmiş "tabakalı örnekleme" yöntemlerini içerir.
Scikit-learn'ü kullanmayı gerektiren başka bir seçenek daha var. As scikit wiki anlatılmaktadır , sadece aşağıdaki yönergeler kullanabilirsiniz:
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)
Bu şekilde, eğitime ve teste ayırmaya çalıştığınız verilerin etiketlerini senkronize tutabilirsiniz.
Sadece bir not. Eğitim, test VE doğrulama kümeleri istiyorsanız, bunu yapabilirsiniz:
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)
Bu parametreler eğitime% 70 ve test ve değer setlerine% 15 verecektir. Bu yardımcı olur umarım.
from sklearn.cross_validation import train_test_split
hangi modülü kullandığınızı netleştirmek için
a=0.7
, b=0.15
, c=0.15
, ve d = dataset
, N=len(dataset)
daha sonra x_train = dataset[0:int(a*N)]
, x_test = dataset[int(a*N):int((a+b)*N)]
ve x_val = dataset[int((a+b)*N):]
.
from sklearn.model_selection import train_test_split
Gibi sklearn.cross_validation
modül kaldırıldı, şunları kullanabilirsiniz:
import numpy as np
from sklearn.model_selection import train_test_split
X, y = np.arange(10).reshape((5, 2)), range(5)
X_trn, X_tst, y_trn, y_tst = train_test_split(X, y, test_size=0.2, random_state=42)
Ayrıca, eğitim ve test seti olarak kademeli bölünmeyi de düşünebilirsiniz. Başlatılan bölüm aynı zamanda rastgele eğitim ve test seti oluşturur, ancak orijinal sınıf oranları korunacak şekilde. Bu, eğitim ve test setlerinin orijinal veri setinin özelliklerini daha iyi yansıtmasını sağlar.
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]
Bu kodun çıktısı:
[1 2 3]
[1 2 3]
value_inds
gerçekten indekslerdir, ancak çıktılar indeksler değildir, sadece maskelerdir.
Bunu yapmak için kendi projem için bir işlev yazdım (yine de numpy kullanmıyor):
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
Parçaların rastgele hale getirilmesini istiyorsanız, listeyi iletmeden önce karıştırın.
Verileri tabakalı bir şekilde n = 5 kata bölmek için bir kod.
% 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]
Cevabınız için teşekkürler pberkes. Hem eğitimde hem de testte (2) yinelenen örnekleme sırasında (1) değiştirmeyi önlemek için değiştirdim:
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)
Biraz okuma yaptıktan ve eğitmek ve test etmek için verileri bölmenin (birçok ..) farklı yolunu hesaba kattıktan sonra, zaman ayırmaya karar verdim!
4 farklı yöntem kullandım (bunların hiçbiri en iyi sonuçları vereceğinden emin olduğum kütüphane sklearn'ı kullanmıyor, iyi tasarlanmış ve test edilmiş bir kod olduğu için):
Yöntem 3, en kısa sürede açık farkla kazandı, bundan sonra yöntem 1 ve yöntem 2 ve 4'ün gerçekten verimsiz olduğu keşfedildi.
Zamanladığım 4 farklı yöntemin kodu:
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)
Ve zamanlar için, 1000 döngünün 3 tekrardan gerçekleştirilmesi için minimum süre:
Umarım yardımcı olur!
Muhtemelen sadece eğitim ve teste ayrılmanız gerekmeyecek, aynı zamanda modelinizin genelleştiğinden emin olmak için çapraz doğrulamaya da ihtiyaç duyacaksınız. Burada% 70 eğitim verisi,% 20 doğrulama ve% 10 erteleme / test verisi varsayıyorum.
Check out np.split :
İndices_or_sections, sıralı tam sayılardan oluşan 1 boyutlu bir diziyse, girişler, dizinin eksen boyunca nerede bölündüğünü belirtir. Örneğin, [2, 3], eksen = 0 için sonuçlanır
ary [: 2] ary [2: 3] ary [3:]
t, v, h = np.split(df.sample(frac=1, random_state=1), [int(0.7*len(df)), int(0.9*len(df))])
Tren testine bölün ve geçerli
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)
Çözümümün en iyisi olmadığının farkındayım, ancak verileri basit bir şekilde bölmek istediğinizde, özellikle de yeni başlayanlara veri bilimini öğretirken işe yarıyor!
def simple_split(descriptors, targets):
testX_indices = [i for i in range(descriptors.shape[0]) if i % 4 == 0]
validX_indices = [i for i in range(descriptors.shape[0]) if i % 4 == 1]
trainX_indices = [i for i in range(descriptors.shape[0]) if i % 4 >= 2]
TrainX = descriptors[trainX_indices, :]
ValidX = descriptors[validX_indices, :]
TestX = descriptors[testX_indices, :]
TrainY = targets[trainX_indices]
ValidY = targets[validX_indices]
TestY = targets[testX_indices]
return TrainX, ValidX, TestX, TrainY, ValidY, TestY
Bu koda göre, veriler üç bölüme ayrılacaktır - test bölümü için 1/4, doğrulama bölümü için başka bir 1/4 ve eğitim seti için 2/4.