কীভাবে কোনও ডেটাসেটকে বিভাগে ভাগ করা / বিভাগ করার জন্য উদাহরণস্বরূপ, ক্রস বৈধকরণের জন্য ডেটাसेटকে প্রশিক্ষণ এবং টেস্ট করা যায়?


101

কোনও NumPy অ্যারে এলোমেলোভাবে প্রশিক্ষণ এবং পরীক্ষার / বৈধকরণ ডেটাসেটে বিভক্ত করার ভাল উপায় কী? মতলব cvpartitionবা crossvalindফাংশনের অনুরূপ কিছু ।

উত্তর:


128

আপনি যদি ডেটা সেটটিকে একবারে দুটি ভাগে ভাগ করতে চান তবে আপনি ব্যবহার করতে পারেন 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-ভাঁজ, ছুটি-এন-আউট, ...)। এটিতে আরও উন্নত "স্ট্রেইটেড স্যাম্পলিং" পদ্ধতি অন্তর্ভুক্ত রয়েছে যা কিছু বৈশিষ্ট্যের সাথে সম্মতিযুক্ত ভারসাম্যপূর্ণ এমন ডেটার একটি বিভাজন তৈরি করে, উদাহরণস্বরূপ, প্রশিক্ষণ এবং পরীক্ষার সেটে ইতিবাচক এবং নেতিবাচক উদাহরণগুলির একই অনুপাত রয়েছে কিনা তা নিশ্চিত করা।


14
এই সমাধানের জন্য ধন্যবাদ। তবে, শেষ পদ্ধতিটি, র‌্যান্ডিন্ট ব্যবহার করে, পরীক্ষা এবং প্রশিক্ষণ উভয়ই সেটগুলির জন্য একই সূচক দেওয়ার ভাল সুযোগ পায় না?
ggauravr

4
দ্বিতীয় সমাধানটি একটি বৈধ উত্তর যখন প্রথম এবং তৃতীয়টি নয়। 1 ম সমাধানের জন্য, ডেটাসেট পরিবর্তন করা সর্বদা একটি বিকল্প নয়, এমন অনেকগুলি ক্ষেত্রে রয়েছে যেখানে আপনাকে ডেটা ইনপুটগুলির ক্রম রাখতে হয়। এবং তৃতীয়টি পরীক্ষামূলকভাবে এবং প্রশিক্ষণের জন্য একই সূচকগুলি খুব ভালভাবে তৈরি করতে পারে (@ggauravr দ্বারা নির্দেশিত)।
পেডরাম বাশিরি

আপনার ক্রস বৈধকরণ সেটটির জন্য পুনরায় নমুনা করা উচিত নয় । পুরো ধারণাটি হল সিভি সেটটি আগে কখনও আপনার অ্যালগো দ্বারা দেখা যায় নি। প্রশিক্ষণের জন্য এবং পরীক্ষার সেটগুলি ডেটা মাপসই করার জন্য ব্যবহৃত হয়, তাই আপনি যদি আপনার সিভি সেটে অন্তর্ভুক্ত করেন তবে অবশ্যই ভাল ফলাফল পাবেন। আমি এই উত্তরটি আপভোট করতে চাই কারণ ২ য় সমাধানটি আমার যা প্রয়োজন তা হল, তবে এই উত্তরটিতে সমস্যা রয়েছে।
রাবারডাক

55

এখানে আরও একটি বিকল্প রয়েছে যা কেবল সাইকিট-লার্ন ব্যবহার করে অন্তর্ভুক্ত থাকে। হিসাবে scikit এর উইকি বর্ণনা , আপনি শুধু নিম্নলিখিত নির্দেশাবলী ব্যবহার করতে পারেন:

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)

আপনি প্রশিক্ষণ এবং পরীক্ষায় বিভক্ত করার চেষ্টা করছেন এমন ডেটাগুলির জন্য আপনি লেবেলগুলি সিঙ্ক এ রাখতে পারেন।


4
ট্রেনের সেট এবং লেবেল উভয়েরই বাস্তবসম্মত পরিচালনার কারণে এটি একটি খুব ব্যবহারিক উত্তর।
চিনিচিনচিন

এটি একটি তালিকা দেয়, অ্যারে নয়।
এনগ্রি স্টুডেন্ট

38

শুধু একটি নোট. আপনি যদি ট্রেন, পরীক্ষা এবং বৈধতা সেটগুলি চান তবে আপনি এটি করতে পারেন:

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% পরীক্ষার এবং ভাল সেটগুলিতে দেবে। আশাকরি এটা সাহায্য করবে.


4
সম্ভবত আপনার কোডে from sklearn.cross_validation import train_test_splitএটি যুক্ত করা উচিত: আপনি কোন মডিউলটি ব্যবহার করছেন তা পরিষ্কার করতে
Radix

এটি কি এলোমেলো হতে হবে?
লিয়াং

অর্থাৎ, এক্স এবং ওয়াইয়ের প্রদত্ত আদেশ অনুসারে বিভাজন করা কি সম্ভব?
লিয়াং

4
@Liang না এটি এলোমেলো হতে হবে না। আপনি কেবল বলতে পারেন ট্রেন, পরীক্ষা, এবং বৈধতা সেট মাপগুলি মোট ডেটাসেটের আকারের a, b এবং c শতাংশ হবে। এর কথা বলা যাক 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):]
অফভাইটেলোটাস

4
থামানো হয়েছে: stackoverflow.com/a/34844352/4237080 , ব্যবহারfrom sklearn.model_selection import train_test_split
briennakh

14

হিসাবে 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)

5

আপনি স্তরিত বিভাগকে প্রশিক্ষণ এবং পরীক্ষার সেট হিসাবেও বিবেচনা করতে পারেন। স্টার্টিফায়েড বিভাগ এলোমেলোভাবে প্রশিক্ষণ ও পরীক্ষার সেট জেনারেট করে তবে এমনভাবে যাতে মূল শ্রেণীর অনুপাত সংরক্ষণ করা হয়। এটি প্রশিক্ষণ এবং পরীক্ষার সেটগুলি মূল ডেটাসেটের বৈশিষ্ট্যগুলিকে আরও ভালভাবে প্রতিবিম্বিত করে।

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সত্যিকারের সূচকগুলি হয় তবে আউটপুট সূচকগুলি হয় না, কেবল মুখোশ হয়।
গ্রিনল্ডম্যান

1

এটি করার জন্য আমি আমার নিজের প্রকল্পের জন্য একটি ফাংশন লিখেছি (এটি নাম্বার ব্যবহার করে না, যদিও):

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

আপনি যদি খণ্ডগুলি এলোমেলোভাবে তৈরি করতে চান তবে তালিকাটি প্রবেশের আগে কেবল এটিকে শাফল করুন।


0

স্ট্র্যাফাইড পদ্ধতিতে ডেটা 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]

0

আপনার উত্তরের জন্য ধন্যবাদ 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)

0

কিছু পঠন করার পরে এবং প্রশিক্ষণের জন্য এবং পরীক্ষার জন্য ডেটা বিভক্ত করার বিভিন্ন উপায় (অনেক ..) গ্রহণের পরে, আমি সময় নির্ধারণ করার সিদ্ধান্ত নিয়েছি!

আমি ৪ টি পৃথক পদ্ধতি ব্যবহার করেছি (এর মধ্যে না লাইব্রেরির স্ক্লার্ন ব্যবহার করছে, যা আমি নিশ্চিত যে সেরা ফলাফল দেবে, এটি প্রদান করে যে এটি ভালভাবে ডিজাইন করা এবং পরীক্ষিত কোড দেওয়া হয়েছে):

  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.7157016959999964 সেকেন্ড
  • পদ্ধতি 3: 1.7876616719995582 সেকেন্ড
  • পদ্ধতি 4: 0.07562861499991413 সেকেন্ড

আমি আশা করি এটি সহায়ক!


0

সম্ভবত আপনাকে কেবল ট্রেন এবং পরীক্ষায় বিভক্ত করতে হবে না, তবে আপনার মডেলটি সাধারণীকরণ করেছে তা নিশ্চিত করার জন্য আপনার বৈধতাও অতিক্রম করতে হবে। এখানে আমি 70% প্রশিক্ষণ ডেটা, 20% বৈধতা এবং 10% হোল্ডআউট / পরীক্ষার ডেটা ধরে নিচ্ছি।

পরীক্ষা করে দেখুন np.split :

যদি সূচকগুলি_অর_সেকশনগুলি সাজানো পূর্ণসংখ্যার 1-ডি অ্যারে হয় তবে এন্ট্রিগুলি নির্দেশ করে যে অক্ষের পাশাপাশি অ্যারেটি বিভক্ত হয়। উদাহরণস্বরূপ, [2, 3] অক্ষ = 0 এর জন্য হবে

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))]) 

0

ট্রেন পরীক্ষায় বিভক্ত এবং বৈধ

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)

0

আমি জানি যে আমার সমাধানটি সর্বোত্তম নয়, তবে আপনি যখন সরলভাবে ডেটা বিভক্ত করতে চান, বিশেষত যখন নবাবিদের কাছে ডেটা বিজ্ঞান পড়ানোর সময় এটি কার্যকর হয়!

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 4

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.