Ich habe einen ziemlich großen Datensatz in Form eines Datenrahmens und ich habe mich gefragt, wie ich den Datenrahmen in zwei Stichproben (80% und 20%) für das Training und Testen aufteilen könnte.
Vielen Dank!
Ich würde nur Numpys randn
verwenden:
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]
Und nur zu sehen, dass dies funktioniert hat:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
scikit lernens train_test_split
ist ein guter.
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2)
Pandas Zufallsstichprobe funktioniert auch
train=df.sample(frac=0.8,random_state=200)
test=df.drop(train.index)
Ich würde scikit-learns eigenes training_test_split verwenden und es aus dem Index generieren
from sklearn.cross_validation 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
Sie können den folgenden Code verwenden, um Test- und Trainingsbeispiele zu erstellen:
from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
Die Testgröße kann je nach dem Prozentsatz der Daten variieren, die Sie in Ihr Test- und Trainings-Dataset einfügen möchten.
Es gibt viele gültige Antworten. Hinzufügen eines weiteren zum Bündel . Aus sklearn.cross_validation import 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)]
Sie können auch eine stratifizierte Einteilung in Schulungs- und Testset in Betracht ziehen. Startified Division generiert auch Trainings- und Test-Sets nach dem Zufallsprinzip, jedoch so, dass die ursprünglichen Klassenverhältnisse erhalten bleiben. Dadurch können Schulungs- und Testsätze die Eigenschaften des ursprünglichen Datensatzes besser widerspiegeln.
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
mit df [train_inds] und df [test_inds] erhalten Sie die Schulungs- und Testsätze Ihres ursprünglichen DataFrame-df.
Wenn Sie Ihre Daten in Bezug auf die Spalte "Lables" in Ihrem Datensatz aufteilen müssen, können Sie Folgendes verwenden:
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
und benutze es:
train, test = split_to_train_test(data, 'class', 0.7)
sie können auch random_state übergeben, wenn Sie die Split-Zufälligkeit steuern oder einen globalen Zufallsstart verwenden möchten.
Das habe ich geschrieben, als ich einen DataFrame aufteilen musste. Ich habe darüber nachgedacht, den Ansatz von Andys zu verwenden, aber mir gefiel es nicht, dass ich die Größe der Datensätze nicht genau kontrollieren konnte (d. H. Es würde manchmal 79, manchmal 81 usw. sein).
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()
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)
Um in mehr als zwei Klassen aufzuteilen, wie Zug, Test und Validierung, kann man Folgendes tun:
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]
Dies bedeutet, dass 70% der Daten im Training, 15% im Test und 15% in der Validierung enthalten sind.
Wählen Sie einfach die Bereichszeile aus df aus
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
Es gibt viele Möglichkeiten, Zug-/Test- und sogar Validierungsmuster zu erstellen.
Fall 1: klassischer Weg train_test_split
ohne Optionen:
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Fall 2: Fall eines sehr kleinen Datensatzes (<500 Zeilen): um Ergebnisse für alle Ihre Zeilen mit dieser Kreuzvalidierung zu erhalten. Am Ende haben Sie eine Vorhersage für jede Zeile Ihres verfügbaren Trainingssatzes.
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)
Fall 3a: Unsymmetrische Datensätze zur Klassifizierung. Nach dem Fall 1 ist hier die äquivalente Lösung:
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)
Fall 3b: Unsymmetrische Datensätze für Klassifizierungszwecke. Nach dem Fall 2 ist hier die äquivalente Lösung:
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)
Fall 4: Sie müssen einen Zug/Test/Validierungssatz für Big Data erstellen, um die Hyperparameter zu optimieren (60% Zug, 20% Test und 20% Wert).
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)
Sie können die Funktion df.as_matrix () verwenden und ein Numpy-Array erstellen und übergeben.
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)
Ich denke, Sie müssen auch eine Kopie erhalten, nicht ein Stück Dataframe, wenn Sie später Spalten hinzufügen möchten.
msk = np.random.Rand(len(df)) < 0.8
train, test = df[msk].copy(deep = True), df[~msk].copy(deep = True)
Wie wäre es damit? Df ist mein Datenrahmen
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)
Wenn Sie einen Datenrahmen und zwei Datenrahmen (keine numpy-Arrays) wünschen, sollten Sie dies tun:
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
Etwas eleganter für meinen Geschmack ist es, eine zufällige Kolumne zu erstellen und diese danach aufzuteilen. Auf diese Weise können wir einen Split erhalten, der unseren Bedürfnissen entspricht und zufällig ist.
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