Repro
import joblib
from evalml.demos import load_fraud
from evalml.preprocessing.data_splitters import BalancedClassificationDataCVSplit
splitter = BalancedClassificationDataCVSplit(n_splits=3, random_seed=0, shuffle=True)
X, y = load_fraud(5000)
X = X.to_dataframe()
y = y.to_series().astype("int")
for train, test in splitter.split(X, y):
print((joblib.hash(train), joblib.hash(test)))
# Output
('75f1b95d7ce307ac6c793055330969aa', '8c89fe1a592c50a700b6d5cbb02dba8b')
('f8c849bbfbed37c13f66c5c742e237cb', '9c4879fb550fded8be9ac03e95a1bf95')
('cdc21f0d6bbf45459c9695258f7f04dc', '5b575765bbe176e732b8eb4dc1bf2822')
for train, test in splitter.split(X, y):
print((joblib.hash(train), joblib.hash(test)))
# Output
('bf462b82af243c552ac48acad2dfd748', '8c89fe1a592c50a700b6d5cbb02dba8b')
('b8341b536c63c7957c099b05e315f49c', '9c4879fb550fded8be9ac03e95a1bf95')
('780e74673b601790037fc0b17dde56fe', '5b575765bbe176e732b8eb4dc1bf2822')
for train, test in splitter.split(X, y):
print((joblib.hash(train), joblib.hash(test)
# Output
('385f6c538568ad3a33cf84f61d94144c', '8c89fe1a592c50a700b6d5cbb02dba8b')
('8db65d0a3bdf87ae0f135b9766a260dd', '9c4879fb550fded8be9ac03e95a1bf95')
('2a7293fc1308b8a572091d7c76d20205', '5b575765bbe176e732b8eb4dc1bf2822')
Dies unterscheidet sich vom Verhalten des Sklearn-Splitters:
from sklearn.model_selection import StratifiedKFold
kfold = StratifiedKFold(n_splits=3, random_state=0, shuffle=True)
for train, test in kfold.split(X, y):
print((joblib.hash(train), joblib.hash(test)))
#Output
('6c30ee6a11803927024354405389506a', '8c89fe1a592c50a700b6d5cbb02dba8b')
('df0a70e2e6ca783f12461e8c82a26ad4', '9c4879fb550fded8be9ac03e95a1bf95')
('2898e4b3d3621b436641016499f4aafb', '5b575765bbe176e732b8eb4dc1bf2822')
for train, test in kfold.split(X, y):
print((joblib.hash(train), joblib.hash(test)))
# Output
('6c30ee6a11803927024354405389506a', '8c89fe1a592c50a700b6d5cbb02dba8b')
('df0a70e2e6ca783f12461e8c82a26ad4', '9c4879fb550fded8be9ac03e95a1bf95')
('2898e4b3d3621b436641016499f4aafb', '5b575765bbe176e732b8eb4dc1bf2822')
Das halte ich aus zwei Gründen für problematisch:
split
den Zustand des Datensplitters ändert, bedeutet dies, dass wir unterschiedliche Ergebnisse zwischen den sequentiellen und parallelen Engines haben.Danke für den Hinweis.
Mich persönlich stört dieses Verhalten nicht. Solange wir jedes Mal, wenn wir mit einem bestimmten Seed initialisieren, nach diesem Punkt die gleiche Ausgabesequenz erhalten, sind wir gut. Ich würde mir Sorgen machen, wenn wir die zufällige Saat nicht respektieren würden; aber das ist nicht das, was dieses Problem verfolgt.
Meine Empfehlung: Nichts tun. Als solche schließen.
@freddyaboulton wenn du mit diesem Verhalten nicht einverstanden bist, lass es uns ausreden, ich meine reden
@dsherry Ich denke, es lohnt sich aus zwei Gründen, dies zu ändern:
Es ist schlecht für die parallele Automl-Suche
Lassen Sie mich auf 2 eingehen. Beim aktuellen Verhalten wird erwartet, dass die sequentielle Engine den Zustand des Datensplitters während der Suche ändert. In der parallelen evalml picken wir den Datensplitter und senden ihn an die Arbeiter, um die Aufteilung zu berechnen. Da die Arbeiter eine Kopie des Splitters erhalten, ändern sie den Zustand des ursprünglichen Datensplitters nicht.
Dies führt zu einem Unterschied im Verhalten zwischen den sequentiellen und parallelen Engines, da die Aufteilungen abhängig von der Reihenfolge, in der die Pipeline ausgewertet wird, nicht übereinstimmen würden! Dies bedeutet, dass dieselbe Pipeline/Parameter-Kombination in der sequentiellen Engine und der parallelen Engine unterschiedliche Ergebnisse erzielen würde, und ich denke, das ist unerwünscht.
Punkt 1 ist meiner Meinung nach Grund genug, dies zu beheben, denn alle unsere Pipelines sollten mit den gleichen Daten bewertet werden, wenn wir sie sinnvoll vergleichen wollen. Aber wenn wir uns auf parallele evalml zubewegen, denke ich, dass es wichtig ist, dass wir sicherstellen, dass das Ändern des globalen Zustands nicht Teil unseres erwarteten Verhaltens ist.
Der Plan geht weiter:
BalancedClassificationDataCVSplit
Danke für die Diskussion an alle!