Evalml: BalancedClassificationDataCVSplit menghasilkan pemisahan yang berbeda setiap kali dipanggil

Dibuat pada 16 Mar 2021  ·  3Komentar  ·  Sumber: alteryx/evalml

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

Ini berbeda dari perilaku splitter sklearn:

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

Saya pikir ini bermasalah karena dua alasan:

  1. Karena BalancedClassificationDataCVSplit adalah splitter default di automl, itu berarti pipeline kami dievaluasi pada split yang berbeda
  2. Karena split mengubah status pembagi data, ini berarti kita akan mendapatkan hasil yang berbeda antara mesin sekuensial dan paralel.
bug

Semua 3 komentar

Terima kasih telah menunjukkan ini.

Secara pribadi, perilaku ini tidak mengganggu saya. Selama setiap kali kita menginisialisasi dengan benih tertentu, kita mendapatkan urutan output yang sama setelah titik itu, kita baik-baik saja. Saya akan khawatir jika kita tidak menghormati benih acak; tapi bukan itu yang dilacak oleh masalah ini.

Rekomendasi saya: jangan lakukan apa pun. Dengan demikian, penutupan.

@freddyaboulton jika Anda tidak setuju tentang perilaku ini, mari kita adu, maksud saya bicara

@dsherry saya pikir ini layak diubah karena dua alasan:

  1. Ini memperkenalkan varians ke pencarian automl karena saluran pipa yang berbeda dievaluasi pada data yang berbeda. Ini membuat tabel peringkat sedikit menyesatkan karena skor tidak dihitung pada data yang sama.
  2. Ini buruk untuk pencarian automl paralel

    Biarkan saya menguraikan 2. Dengan perilaku saat ini, mesin sekuensial diharapkan untuk mengubah keadaan pembagi data selama pencarian. Dalam evalml paralel, kami mengaduk pemisah data dan mengirimkannya ke pekerja untuk menghitung pemisahan. Karena pekerja mendapatkan salinan pembagi, mereka tidak mengubah status pembagi data asli.

Ini memperkenalkan perbedaan perilaku di antara mesin sekuensial dan paralel karena pemisahan tidak akan cocok tergantung pada urutan pipa dievaluasi! Ini berarti bahwa kombo pipa/parameter yang sama akan mendapatkan hasil yang berbeda di mesin sekuensial dan mesin paralel dan saya pikir itu tidak diinginkan.

Menurut pendapat saya, poin 1 adalah alasan yang cukup untuk memperbaikinya karena semua pipeline kita harus dievaluasi pada data yang sama jika kita ingin dapat membandingkannya secara bermakna. Tetapi saat kita bergerak menuju evalml paralel, saya pikir penting bagi kita untuk memastikan bahwa memodifikasi keadaan global bukan bagian dari perilaku yang kita harapkan.

Rencana ke depan:

  1. Perbaiki masalah ini dengan memodifikasi BalancedClassificationDataCVSplit
  2. Dalam jangka panjang, kami ingin menulis pengujian yang memverifikasi bahwa kami tidak memasukkan pemisahan yang berbeda ke saluran pipa yang berbeda dalam pencarian automl.

Terima kasih atas diskusi semuanya!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat