Teknik Cross-Validation Yang Tersedia Dan Penggunaan Yang Tepat - CRUDPRO

Teknik Cross-Validation Yang Tersedia Dan Penggunaan Yang Tepat

Mengapa Cross-Validation?

Anda harus mempromosikan ide utama Anda sampai Anda mulai menjual produk terkait. Aku pergi ke sini.

Bayangkan sebuah dunia di mana Anda tidak tahu apa itu prosedur Cross-Validation. Di dunia yang gila itu, ia dengan jelas membagi data menjadi satu rangkaian kereta dan pengujian. Model belajar dari data pelatihan dan menguji kinerjanya dengan memprediksi apa yang disebut data tak terlihat, yang merupakan kumpulan pengujian. Jika Anda tidak puas dengan skor Anda, gunakan set yang sama untuk menyetel model Anda hingga GridSearch (atau Optuna) berteriak "Cukup!".

Berikut adalah dua dari banyak cara proses ini bisa gagal:

  1. Himpunan tersebut tidak mewakili seluruh populasi dengan baik. Sebagai contoh ekstrim, dari tiga baris kategori (a, b, c), semua kategori a dan b dapat dimasukkan dalam set pelatihan sementara semua cs berada di set pengujian. Atau, variabel numerik dipisah sehingga nilai di kiri dan kanan ambang tidak terdistribusi dengan benar antara rangkaian dan rangkaian. Atau situasi di mana distribusi variabel baru di kedua set sangat berbeda dari distribusi asli sehingga model belajar dari informasi yang salah.
  2. Saat menyesuaikan hyperparameter, itu membocorkan pengetahuan tentang set tes ke model. Ketika pencarian selesai, kerangka kerja akan mengeluarkan parameter terbaik untuk set pengujian tertentu. Saya menggunakan kata tertentu, jadi Anda seharusnya sudah mulai berpikir tentang overfitting. Itu karena itu terjadi ketika Anda terus menguji set yang sama berulang kali. Kerangka kerja pencarian hanya memberikan hasil yang memuaskan untuk set tes tertentu.

Oleh karena itu, ketika CV kembali ke dunia yang dicintai dan digunakan secara luas oleh para insinyur di seluruh dunia, semua masalah ini akan teratasi. Seperti yang ditunjukkan dalam Panduan Pengguna Sklearn (lisensi BSD), keajaiban CV adalah:

Di atas adalah contoh proses cross-validation 5 kali lipat, yang membutuhkan 5 iterasi untuk diselesaikan. Model baru dilatih dalam empat lipatan pada setiap iterasi dan diuji pada lipatan terakhir. Dengan cara ini, model dilatih dan diuji dengan semua data tanpa membuangnya.

Skor rata-rata kemudian dilaporkan sebagai interval kepercayaan dengan standar deviasi. Hanya dengan demikian parameter yang dipilih dapat digunakan untuk benar-benar menentukan kinerja model. Ini karena skor rata-rata yang diperoleh mewakili potensi sebenarnya dari model untuk belajar secara efektif dari data dan secara akurat memprediksi sampel yang tidak terlihat.

1. KFold

Sekarang mari kita bicara tentang berbagai cara untuk melakukan prosedur CV. Seperti yang Anda lihat pada gambar di atas, yang paling sederhana adalah KFold. Ini diimplementasikan dengan nama yang sama di Sklearn. Di sini kita menulis fungsi cepat untuk memvisualisasikan indeks split dari CV splitter.

def visualize_cv(cv, X, y):
    fig, ax = plt.subplots(figsize=(10, 5))

    for ii, (tr, tt) in enumerate(cv.split(X, y)):
        p1 = ax.scatter(tr, [ii] * len(tr), c="#221f1f", marker="_", lw=8)
        p2 = ax.scatter(tt, [ii] * len(tt), c="#b20710", marker="_", lw=8)
        ax.set(
            title=cv.__class__.__name__,
            xlabel="Data Index",
            ylabel="CV Iteration",
            ylim=[cv.n_splits, -1],
        )
        ax.legend([p1, p2], ["Training", "Validation"])

    plt.show()

Kemudian berikan splitter KFold dengan 7 split ke fungsi ini.


from sklearn.datasets import make_regression
from sklearn.model_selection import KFold

X, y = make_regression(n_samples=100)

# Init the splitter
cv = KFold(n_splits=7)

visualize_cv(cv, X, y)

Seperti inilah tampilan Vanilla KFold.

Versi lain mengacak data sebelum pemisahan dilakukan. Ini mengganggu urutan asli sampel, selanjutnya meminimalkan risiko overfitting.

cv = KFold(n_splits=7, shuffle=True)

visualize_cv(cv, X, y)

Seperti yang Anda lihat, indeks sampel validasi dipilih secara acak. Namun, kami menjalankan 7x CV, sehingga jumlah sampel tetap 1/7 dari total data.

KFold adalah splitter CV yang paling umum digunakan. Mudah dipahami dan berakibat fatal. Namun, tergantung pada karakteristik kumpulan data Anda, Anda mungkin perlu mempertimbangkan dengan cermat prosedur CV yang Anda gunakan. Sekarang mari kita bicara tentang alternatif.

2. KFold bertingkat

Versi lain dari KFold yang secara eksplisit dirancang untuk masalah klasifikasi adalah StratifiedKFold.

Klasifikasi harus mempertahankan distribusi target bahkan setelah data dipecah menjadi beberapa set. Lebih khusus lagi, target biner dengan rasio kelas 30-70 harus mempertahankan rasio yang sama di set pelatihan dan set pengujian.

Vanilla KFold melanggar aturan karena tidak peduli dengan rasio kelas atau mengacak data sebelum membelah. Solusinya adalah dengan menggunakan kelas splitter Sklearn lain, StratifiedKFold.

from sklearn.datasets import make_classification
from sklearn.model_selection import StratifiedKFold

X, y = make_classification(n_samples=100, n_classes=2)

cv = StratifiedKFold(n_splits=7, shuffle=True, random_state=1121218)

visualize_cv(cv, X, y)

Terlihat mirip dengan KFold, tetapi rasio kelas sekarang dipertahankan di semua lipatan dan iterasi.

3.LeavePOut

Dalam beberapa kasus, data sangat terbatas sehingga Anda bahkan tidak mampu membaginya menjadi set pelatihan dan pengujian. Dalam hal ini, Anda dapat menjalankan CV yang hanya mencadangkan beberapa baris data untuk setiap iterasi. Hal ini dikenal dengan CLeavePOut CV. Di mana "p" adalah parameter yang Anda pilih untuk menentukan jumlah baris di setiap set ketidaksepakatan.

Kasus paling ekstrem adalah splitter LeaveOneOut, yang hanya menggunakan satu baris sebagai set pengujian dan jumlah iterasi sama dengan jumlah baris data lengkap. Membangun 100 model untuk dataset 100 baris kecil ada bersama Anda jika tampaknya berdekatan.

Bahkan dengan jumlah ps yang besar, jumlah iterasi meningkat secara eksponensial seiring dengan bertambahnya ukuran kumpulan data. Bayangkan jumlah model yang dibangun ketika p adalah 5 dan hanya ada 50 baris data (petunjuk gunakan rumus kolom maju).

Oleh karena itu, hal ini jarang terlihat dalam praktik, tetapi cukup sering terjadi bagi Sklearn untuk menerapkan prosedur ini sebagai kelas yang terpisah.

from sklearn.model_selection import LeaveOneOut, LeavePOut

4.ShuffleSplit

Bagaimana kalau mengul sang proses training/test split beberapa kali tanpa melakukan CV apapun? Nah, itu cara lain Anda bisa menggoda dengan ide cross-validation, tapi tetap saja tidak.

Logikanya, menghasilkan beberapa rangkaian kereta/pengujian dengan benih acak yang berbeda harus menyerupai proses CV yang kuat jika dijalankan dengan iterasi yang cukup. Oleh karena itu, ada splitter yang melakukan proses ini di Sklearn:

from sklearn.model_selection import ShuffleSplit

cv = ShuffleSplit(n_splits=7, train_size=0.75, test_size=0.25)

visualize_cv(cv, X, y)

Keuntungan ShuffleSplit adalah Anda memiliki kontrol penuh atas ukuran kereta dan set setiap lipatan. Ukuran himpunan tidak harus berbanding terbalik dengan jumlah split.

Namun, tidak seperti splitter lainnya, tidak ada jaminan bahwa random split akan menghasilkan fold yang berbeda pada setiap iterasi. Karena itu, gunakan kelas ini dengan hati-hati.

btw, ada juga versi Shuffle Split berlapis untuk klasifikasi.

from sklearn.model_selection import StratifiedShuffleSplit

cv = StratifiedShuffleSplit(n_splits=7, test_size=0.5)

visualize_cv(cv, X, y)

5. TimeSeriesSplit

Akhirnya, ada kasus khusus data deret waktu di mana urutan sampel penting.

Kelas CV tradisional tidak dapat digunakan karena dapat menyebabkan bencana. Anda lebih mungkin untuk melatih sampel masa depan dan memprediksi sampel masa lalu.

Untuk mengatasi ini, Sklearn menawarkan splitter lain — TimeSeriesSplit untuk memastikan bahwa hal di atas tidak terjadi:

from sklearn.model_selection import TimeSeriesSplit

cv = TimeSeriesSplit(n_splits=7)

visualize_cv(cv, X, y)

Bagus dan rapi!

Splitters CV lainnya untuk data non-IID

Sejauh ini, kami telah berurusan dengan data IID (terdistribusi secara independen dan serupa). Artinya, proses yang menghasilkan data tidak memiliki memori untuk sampel masa lalu.

Namun, datanya mungkin bukan IID. Artinya, beberapa kelompok sampel mungkin saling bergantung. Misalnya, kontes Tekanan Ventilator Otak Google di Kaggle mengharuskan peserta untuk menggunakan data non-IID.

Data merekam ribuan napas (masuk, keluar) yang diambil oleh prostesis dan mencatat tekanan udara setiap napas pada interval beberapa milidetik. Akibatnya, data berisi sekitar 80 baris per napas, dan baris ini bergantung padanya.

Di sini, splitter CV tradisional tidak berfungsi seperti yang diharapkan, karena pasti ada kemungkinan perpecahan "di tengah nafas". Berikut adalah contoh lain dari Panduan Pengguna Sklearn:

Pengelompokan data tersebut bersifat spesifik domain. Contohnya mungkin data medis yang dikumpulkan dari beberapa pasien, dengan beberapa sampel yang diambil dari setiap pasien. Dan data tersebut dapat bergantung pada kelompok individu. Dalam contoh ini, ID pasien untuk setiap sampel adalah pengidentifikasi grupnya.

Ini juga menjelaskan solusi segera setelah itu.

Dalam hal ini, saya ingin tahu apakah model yang dilatih dengan kumpulan grup tertentu berhasil digeneralisasi ke grup tak terlihat. Untuk mengukur ini, Anda perlu memastikan bahwa semua sampel dalam lipatan validasi berasal dari kelompok yang tidak terwakili sama sekali dalam lipatan pelatihan pasangan.

Sklearn kemudian membuat daftar lima kelas berbeda yang dapat menangani data yang dikelompokkan. Jika Anda memahami gagasan di bagian sebelumnya dan memahami apa itu data non-IID, Anda akan baik-baik saja:

  1. GroupKFold
  2. StratifiedGroupKFold
  3. LeaveOneGroupOut
  4. LeavePGroupsOut
  5. GroupShuffleSplit

Masing-masing pembagi ini memiliki argumen grup yang harus Anda sampaikan di kolom yang berisi ID grup. Ini memberitahu kelas bagaimana membedakan setiap kelompok.

Ringkasan

Akhirnya, debu telah mereda dan kami di sini.

Salah satu pertanyaan yang mungkin tidak saya jawab adalah "Haruskah saya selalu menggunakan validasi bersama?" Jawabannya tentatif ya. Jika dataset cukup besar, random split sangat mirip dengan data asli di kedua set. Dalam hal ini, CV bukanlah persyaratan yang ketat.

Namun, ahli statistik yang jauh lebih berpengalaman dan orang-orang di Stack Exchange mengatakan bahwa mereka perlu melakukan setidaknya dua atau tiga kali validasi silang terlepas dari ukuran data. Anda tidak pernah bisa berhati-hati.

Terima kasih telah membaca!