programing

교차 검증 등을 위해 데이터 세트를 교육 및 테스트 데이터 세트로 분할/분할하는 방법은 무엇입니까?

codeshow 2023. 8. 10. 21:44
반응형

교차 검증 등을 위해 데이터 세트를 교육 및 테스트 데이터 세트로 분할/분할하는 방법은 무엇입니까?

NumPy 어레이를 교육 및 테스트/검증 데이터셋으로 임의로 분할하는 좋은 방법은 무엇입니까?그것과 비슷한 것.cvpartition또는crossvalind함수를 사용할 수 있습니다.

데이터 세트를 두 부분으로 한 번 분할하려면 다음을 사용할 수 있습니다.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,:]

교차 검증을 위해 동일한 데이터 세트를 반복적으로 분할하는 다른 방법은 여러 가지가 있습니다.sklearn 라이브러리(k-fold, leave-n-out, ...)에서 사용할 수 있는 많은 것들이 있다. sklearn은 또한 일부 기능과 관련하여 균형 잡힌 데이터의 파티션을 만드는 더 발전된 "계층화된 샘플링" 방법을 포함한다. 예를 들어, 훈련 및 테스트 세트에 긍정적인 예제와 부정적인 예제의 비율이 동일한지 확인하는 것이다.

scikit-learn을 사용해야 하는 또 다른 옵션이 있습니다.scikit's wikit에서 설명한 대로 다음 지침을 사용할 수 있습니다.

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.model_selection 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%를 제공합니다.이게 도움이 되길 바랍니다.

~하듯이sklearn.cross_validation모듈이 더 이상 사용되지 않습니다. 다음을 사용할 수 있습니다.

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)

교육 및 테스트 세트로 계층화된 분할도 고려할 수 있습니다.또한 시작된 분할은 교육 및 테스트 세트를 무작위로 생성하지만 원래 클래스 비율이 보존되는 방식으로 생성합니다.이를 통해 교육 및 테스트 세트가 원래 데이터 세트의 속성을 더 잘 반영할 수 있습니다.

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]

약간의 독서를 하고 고려한 후에 (많은..) 교육 및 테스트를 위해 데이터를 분할하는 다양한 방법으로 시간을 결정했습니다!

저는 4가지 다른 방법을 사용했습니다(그 중에는 sklearn 라이브러리를 사용하는 방법이 없습니다. sklearn은 잘 설계되고 테스트된 코드라는 점에서 최고의 결과를 제공할 것이라고 확신합니다).

  1. 전체 행렬 배열을 섞고 데이터를 분할하여 교육 및 테스트
  2. 인덱스를 섞고 x와 y를 지정하여 데이터를 분할합니다.
  3. 방법 2와 동일하지만, 그것을 하는 더 효율적인 방법으로.
  4. 판다 데이터 프레임을 사용하여 분할

방법 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)

또한 시간의 경우, 1000번의 루프 중 3번의 반복 중 최소 실행 시간은 다음과 같습니다.

  • 방법 1: 0.35883826200006297초
  • 방법 2: 1.71570169599999964초
  • 방법 3: 1.7876616719995582초
  • 방법 4: 0.075628614991413초

그게 도움이 되길 바랍니다!

나는 이것을 하기 위해 나만의 프로젝트를 위한 함수를 작성했습니다(그러나 그것은 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

청크를 랜덤화하려면 목록을 넘겨주기 전에 순서대로 섞기만 하면 됩니다.

열차 테스트로 분할하여 유효

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)

다음은 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에게 감사합니다.교육과 테스트 모두에서 중복된 인스턴스(2)를 샘플링하는 동안 (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)

모형이 일반화되는지 확인하려면 여러 개의 열차와 테스트로 분할해야 할 뿐만 아니라 교차 검증도 필요할 수 있습니다.여기서는 70%의 교육 데이터, 20%의 검증 데이터 및 10%의 홀드아웃/테스트 데이터를 가정합니다.

np.split을 확인합니다.

index_or_sections가 정렬된 정수의 1-D 배열인 경우 항목은 배열이 긴 축으로 분할된 위치를 나타냅니다.예를 들어, [2, 3]은 축=0에 대해 다음과 같이 됩니다.

배열[:2] 배열[2:3] 배열[3:3]

t, v, h = np.split(df.sample(frac=1, random_state=1), [int(0.7*len(df)), int(0.9*len(df))]) 

제 솔루션이 최상의 솔루션이 아니라는 것은 알고 있지만, 데이터를 단순한 방식으로 분할하고 싶을 때, 특히 초보자에게 데이터 과학을 가르칠 때 유용합니다!

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

이 코드에 따라 데이터는 테스트 파트의 1/4, 검증 파트의 1/4, 교육 세트의 2/4 등 세 부분으로 분할됩니다.

그러나 데이터 세트를 분할하는 또 다른 순수한 바보 같은 방법입니다.이 솔루션은 다음을 기반으로 합니다.numpy.split이것은 이미 전에 언급되었지만 참고를 위해 여기에 이것을 추가합니다.

# Dataset
dataset = np.load(...)                      # Dataset of shape N x (d1 ... dM)

# Splitting and shuffling with indexes
idx = np.arange(len(dataset))               # Vector of dataset samples idx
id_train = int(len(idx) * 0.8)              # Train 80%
id_valid = int(len(idx) * (0.8 + 0.05))     # Valid 5%, Test 15%
train, valid, test = np.split(idx, (id_train, id_valid))

# Indexing dataset subsets
dataset_train = dataset[train]              # Train set
dataset_valid = dataset[valid]              # Valid set
dataset_test = dataset[test]                # Test set

다음은 데이터 집합을 분할하는 또 다른 방법입니다.np.rand() 함수를 사용하여 마스크를 생성하여 랜덤 행을 선택할 수 있습니다.

msk = np.random.rand(len(df)) < 0.8

train = cdf[msk]
test = cdf[~msk]

언급URL : https://stackoverflow.com/questions/3674409/how-to-split-partition-a-dataset-into-training-and-test-datasets-for-e-g-cros

반응형