Antworten:
Ich würde nur Numpys verwenden 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]
Und nur um zu sehen, hat das funktioniert:
In [15]: len(test)
Out[15]: 21
In [16]: len(train)
Out[16]: 79
rand
, < 0.8
um Sinn zu machen, weil es gleichmäßig verteilte Zufallszahlen zwischen 0 und 1 zurückgibt.
in[12]
, in[13]
, in[14]
? Ich möchte den Python-Code selbst hier verstehen
np.random.rand(len(df))
ist ein Größenarray len(df)
mit zufällig und gleichmäßig verteilten Float-Werten im Bereich [0, 1]. Das < 0.8
wendet den Vergleich elementweise an und speichert das Ergebnis an Ort und Stelle. So werden Werte <0,8 True
und Wert> = 0,8False
scikit learn'strain_test_split
ist gut.
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]
Das vollständige Beispiel finden Sie hier: quantstart.com/articles/…
from sklearn.model_selection import train_test_split
stattdessen als .
from sklearn.cross_validation import train_test_split
Pandas Zufallsstichprobe wird auch funktionieren
train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)
random_state
Arg?
test
Satz gewünscht wird, wie hier gezeigt . stackoverflow.com/questions/29576430/shuffle-dataframe-rows . test=df.drop(train.index).sample(frac=1.0)
Ich würde scikit-learns eigenen training_test_split verwenden und ihn aus dem Index generieren
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
Modul ist jetzt veraltet: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.
Es gibt viele Möglichkeiten, einen 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 mit dieser Kreuzvalidierung Ergebnisse für alle Ihre Zeilen 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: Unausgeglichene Datensätze zu Klassifizierungszwecken. 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: Unausgeglichene Datensätze zu Klassifizierungszwecken. 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 Hyperparameter abzustimmen (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 den folgenden Code verwenden, um Test- und Trainingsmuster 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 Prozentsatz der Daten variieren, die Sie in Ihren Test- und Zugdatensatz aufnehmen möchten.
Es gibt viele gültige Antworten. Hinzufügen eines weiteren zum Haufen. 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 geschichtete Unterteilung in Trainings- und Testgruppen in Betracht ziehen. Die gestartete Aufteilung generiert auch zufällig Trainings- und Testsätze, jedoch so, dass die ursprünglichen Klassenanteile erhalten bleiben. Dadurch spiegeln Trainings- und Testsätze die Eigenschaften des Originaldatensatzes besser wider.
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] und df [test_inds] geben Ihnen die Trainings- und Testsätze Ihres ursprünglichen DataFrame df.
Wenn Sie Ihre Daten in Bezug auf die Spalte "Etiketten" 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 geteilte Zufälligkeit steuern oder einen globalen zufälligen Startwert verwenden möchten.
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)
Sie können ~ (Tilde-Operator) verwenden, um die mit df.sample () abgetasteten Zeilen auszuschließen, sodass Pandas allein das Abtasten und Filtern von Indizes durchführen können, um zwei Sätze zu erhalten.
train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Dies habe ich geschrieben, als ich einen DataFrame teilen musste. Ich habe überlegt, den obigen Ansatz von Andy zu verwenden, aber es hat mir nicht gefallen, dass ich die Größe der Datensätze nicht genau steuern konnte (dh manchmal 79, manchmal 81 usw.).
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()
Wählen Sie einfach die Bereichszeile von df wie folgt aus
row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
df
in Ihrem Code-Snippet gemischt wird (oder werden sollte), wird die Antwort verbessert.
Es gibt oben viele gute Antworten, daher möchte ich nur ein weiteres Beispiel hinzufügen, falls Sie die genaue Anzahl der Proben für den Zug und die Testsätze nur mithilfe der numpy
Bibliothek angeben möchten .
# 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]
Um sich in mehr als zwei Klassen wie Zug, Test und Validierung aufzuteilen, 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]
Dadurch werden ungefähr 70% der Daten in das Training, 15% in den Test und 15% in die Validierung einbezogen.
Sie müssen den Pandas-Datenrahmen in ein Numpy-Array konvertieren und dann das Numpy-Array wieder in einen Datenrahmen konvertieren
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)
Wenn Sie einen Datenrahmen ein- und zwei Datenrahmen aus haben möchten (keine numpy Arrays), sollte dies den Trick 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
Ein bisschen eleganter für meinen Geschmack ist es, eine zufällige Spalte zu erstellen und diese dann aufzuteilen. Auf diese Weise können wir eine Aufteilung erhalten, die 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
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)
msk
der dtype istbool
,df[msk]
,df.iloc[msk]
unddf.loc[msk]
immer das gleiche Ergebnis zurück.