ฉันมีชุดข้อมูลที่มีขนาดใหญ่พอสมควรในรูปแบบของ dataframe และฉันสงสัยว่าฉันจะสามารถแยก dataframe ออกเป็นสองตัวอย่างแบบสุ่ม (80% และ 20%) สำหรับการฝึกอบรมและการทดสอบได้อย่างไร
ขอบคุณ!
ฉันมีชุดข้อมูลที่มีขนาดใหญ่พอสมควรในรูปแบบของ dataframe และฉันสงสัยว่าฉันจะสามารถแยก dataframe ออกเป็นสองตัวอย่างแบบสุ่ม (80% และ 20%) สำหรับการฝึกอบรมและการทดสอบได้อย่างไร
ขอบคุณ!
คำตอบ:
ฉันแค่จะใช้ของ numpy 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]
? ฉันต้องการเข้าใจโค้ดไพ ธ อนเองที่นี่
np.random.rand(len(df))
เป็นอาร์เรย์ขนาดที่len(df)
มีค่าทศนิยมแบบสุ่มและกระจายแบบสม่ำเสมอในช่วง [0, 1] < 0.8
ใช้การเปรียบเทียบองค์ประกอบที่ชาญฉลาดและร้านค้าผลในสถานที่ ดังนั้นค่า <0.8 กลายเป็นTrue
และค่า> = 0.8 กลายเป็นFalse
scikit learntrain_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)
ฉันจะใช้ training_test_split ของ 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 นำเข้า 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)]
คุณอาจพิจารณาการแบ่งชั้นเป็นชุดฝึกอบรมและทดสอบ แผนกที่เริ่มต้นแล้วยังสร้างการฝึกอบรมและการทดสอบแบบสุ่ม แต่ในลักษณะที่สัดส่วนชั้นเรียนดั้งเดิมจะคงไว้ สิ่งนี้ทำให้ชุดการฝึกอบรมและการทดสอบสะท้อนถึงคุณสมบัติของชุดข้อมูลดั้งเดิมได้ดีขึ้น
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] ให้ชุดฝึกอบรมและทดสอบของ DataFrame ต้นฉบับของคุณ df
หากคุณต้องการแบ่งข้อมูลของคุณตามคอลัมน์ lables ในชุดข้อมูลของคุณคุณสามารถใช้สิ่งนี้:
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)
คุณสามารถใช้ ~ (โอเปอเรเตอร์ tilde) เพื่อยกเว้นแถวที่สุ่มตัวอย่างโดยใช้ df.sample () เพื่อให้หมีแพนด้าจัดการการสุ่มตัวอย่างและการกรองดัชนีเพียงอย่างเดียวเพื่อรับสองชุด
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
นี่คือสิ่งที่ฉันเขียนเมื่อฉันต้องการแยก DataFrame ฉันพิจารณาว่าใช้วิธีของ Andy ด้านบน แต่ไม่ชอบว่าฉันไม่สามารถควบคุมขนาดของชุดข้อมูลได้อย่างแน่นอน (เช่นบางครั้งอาจเป็น 79, 81 หรือ 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% ในการตรวจสอบ
คุณต้องแปลง p ดาสดาต้าฟารมเป็นอาเรย์นันตี้แล้วแปลงอาร์มินัมกลับสู่ดาตาแฟรม
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)
หากความปรารถนาของคุณคือมีหนึ่งดาต้าไฟล์ในและสองดาต้าเฟรมออกมา (ไม่ใช่อาร์เรย์ numpy) สิ่งนี้ควรทำเคล็ดลับ:
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
คุณสามารถใช้ประโยชน์จากฟังก์ชั่น df.as_matrix () และสร้าง Numpy-array และส่งผ่านมันได้
Y = df.pop()
X = df.as_matrix()
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size = 0.2)
model.fit(x_train, y_train)
model.test(x_test)
อีกเล็กน้อยที่หรูหราสำหรับรสนิยมของฉันคือการสร้างคอลัมน์แบบสุ่มแล้วแยกตามมันด้วยวิธีนี้เราจะได้รับการแบ่งที่จะเหมาะกับความต้องการของเราและจะสุ่ม
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
ไม่จำเป็นต้องเปลี่ยนเป็นคนอ้วน เพียงใช้ pandas df ทำการแยกและมันจะคืน pandas df
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, 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 คือ dataframe ของฉัน
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)
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]
msk
เป็นของ dtypebool
,df[msk]
,df.iloc[msk]
และdf.loc[msk]
มักจะกลับผลเดียวกัน