Persiapan Data MinDiff

pengantar

Saat menerapkan MinDiff, Anda perlu membuat keputusan yang rumit saat Anda memilih dan membentuk masukan Anda sebelum meneruskannya ke model. Keputusan ini akan sangat menentukan perilaku MinDiff dalam model Anda.

Panduan ini akan mencakup aspek teknis dari proses ini, tetapi tidak akan membahas bagaimana mengevaluasi model untuk keadilan, atau bagaimana mengidentifikasi irisan dan metrik tertentu untuk evaluasi. Silakan lihat pedoman Keadilan Indikator untuk rincian tentang ini.

Untuk menunjukkan MinDiff, panduan ini menggunakan dataset pendapatan UCI . Tugas model adalah untuk memprediksi apakah seseorang memiliki pendapatan melebihi $50k, berdasarkan berbagai atribut pribadi. Panduan ini mengasumsikan ada kesenjangan bermasalah di FNR (tingkat negatif palsu) antara "Male" dan "Female" iris dan pemilik model (Anda) telah memutuskan untuk menerapkan MinDiff untuk mengatasi masalah ini. Untuk informasi lebih lanjut tentang skenario di mana yang mungkin memilih untuk menerapkan MinDiff, lihat halaman persyaratan .

MinDiff bekerja dengan menghukum perbedaan skor distribusi antara contoh dalam dua set data. Panduan ini akan mendemonstrasikan bagaimana memilih dan menyusun set MinDiff tambahan ini serta bagaimana mengemas semuanya bersama-sama sehingga dapat diteruskan ke model untuk pelatihan.

Mempersiapkan

pip install -q --upgrade tensorflow-model-remediation
import tensorflow as tf
from tensorflow_model_remediation import min_diff
from tensorflow_model_remediation.tools.tutorials_utils import uci as tutorials_utils

Data Asli

Untuk tujuan demonstrasi dan untuk mengurangi waktu proses, panduan ini hanya menggunakan sebagian kecil sampel dari kumpulan data UCI Income. Dalam pengaturan produksi nyata, dataset lengkap akan digunakan.

# Sampled at 0.3 for reduced runtimes.
train = tutorials_utils.get_uci_data(split='train', sample=0.3)

print(len(train), 'train examples')
9768 train examples

Konversi ke tf.data.Dataset

MinDiffModel mengharuskan input menjadi tf.data.Dataset . Jika Anda menggunakan format input yang berbeda sebelum mengintegrasikan MinDiff, Anda harus mengonversi data input Anda.

Gunakan tf.data.Dataset.from_tensor_slices untuk mengkonversi ke tf.data.Dataset .

dataset = tf.data.Dataset.from_tensor_slices((x, y, weights))
dataset.shuffle(...)  # Optional.
dataset.batch(batch_size)

Lihat Model.fit dokumentasi untuk rincian tentang ekuivalensi antara dua metode input.

Dalam panduan ini, input diunduh sebagai Pandas DataFrame dan oleh karena itu, memerlukan konversi ini.

# Function to convert a DataFrame into a tf.data.Dataset.
def df_to_dataset(dataframe, shuffle=True):
  dataframe = dataframe.copy()
  labels = dataframe.pop('target')
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=5000)  # Reasonable but arbitrary buffer_size.
  return ds

# Convert the train DataFrame into a Dataset.
original_train_ds = df_to_dataset(train)

Membuat data MinDiff

Selama pelatihan, MinDiff akan mendorong model untuk mengurangi perbedaan prediksi antara dua set data tambahan (yang mungkin termasuk contoh dari set data asli). Pemilihan dua set data ini adalah keputusan utama yang akan menentukan efek MinDiff pada model.

Kedua set data harus dipilih sedemikian rupa sehingga perbedaan kinerja yang Anda coba perbaiki terlihat jelas dan terwakili dengan baik. Karena tujuannya adalah untuk mengurangi kesenjangan di FNR antara "Male" dan "Female" iris, berarti ini menciptakan satu dataset dengan hanya berlabel positif "Male" contoh dan lain dengan hanya berlabel positif "Female" contoh; ini akan menjadi kumpulan data MinDiff.

Pertama, periksa data yang ada.

female_pos = train[(train['sex'] == ' Female') & (train['target'] == 1)]
male_pos = train[(train['sex'] == ' Male') & (train['target'] == 1)]
print(len(female_pos), 'positively labeled female examples')
print(len(male_pos), 'positively labeled male examples')
385 positively labeled female examples
2063 positively labeled male examples

Sangat dapat diterima untuk membuat kumpulan data MinDiff dari himpunan bagian dari kumpulan data asli.

Sementara tidak ada 5.000 atau lebih positif "Male" contoh seperti yang direkomendasikan dalam pedoman persyaratan , ada lebih dari 2.000 dan masuk akal untuk mencoba dengan banyak sebelum mengumpulkan lebih banyak data.

min_diff_male_ds = df_to_dataset(male_pos)

Positif "Female" contoh, bagaimanapun, adalah jauh langka di 385. Ini mungkin terlalu kecil untuk kinerja yang baik dan akan memerlukan menarik dalam contoh tambahan.

full_uci_train = tutorials_utils.get_uci_data(split='train')
augmented_female_pos = full_uci_train[((full_uci_train['sex'] == ' Female') &
                                       (full_uci_train['target'] == 1))]
print(len(augmented_female_pos), 'positively labeled female examples')
1179 positively labeled female examples

Menggunakan dataset lengkap memiliki lebih dari tiga kali lipat jumlah contoh yang dapat digunakan untuk MinDiff. Masih rendah tapi cukup untuk dicoba sebagai first pass.

min_diff_female_ds = df_to_dataset(augmented_female_pos)

Kedua set data MinDiff secara signifikan lebih kecil dari 5.000 contoh atau lebih yang direkomendasikan. Meskipun masuk akal untuk mencoba menerapkan MinDiff dengan data saat ini, Anda mungkin perlu mempertimbangkan untuk mengumpulkan data tambahan jika Anda mengamati kinerja yang buruk atau overfitting selama pelatihan.

menggunakan tf.data.Dataset.filter

Atau, Anda dapat membuat dua dataset MinDiff langsung dari dikonversi asli Dataset .

# Male
def male_predicate(x, y):
  return tf.equal(x['sex'], b' Male') and tf.equal(y, 0)

alternate_min_diff_male_ds = original_train_ds.filter(male_predicate).cache()

# Female
def female_predicate(x, y):
  return tf.equal(x['sex'], b' Female') and tf.equal(y, 0)

full_uci_train_ds = df_to_dataset(full_uci_train)
alternate_min_diff_female_ds = full_uci_train_ds.filter(female_predicate).cache()

Yang dihasilkan alternate_min_diff_male_ds dan alternate_min_diff_female_ds akan setara dalam output untuk min_diff_male_ds dan min_diff_female_ds masing-masing.

Membangun Dataset Pelatihan Anda

Sebagai langkah terakhir, tiga set data (dua yang baru dibuat dan yang asli) perlu digabungkan menjadi satu set data yang dapat diteruskan ke model.

Mengelompokkan kumpulan data

Sebelum menggabungkan, kumpulan data perlu di-batch.

  • Dataset asli dapat menggunakan batching yang sama yang digunakan sebelum mengintegrasikan MinDiff.
  • Kumpulan data MinDiff tidak perlu memiliki ukuran kumpulan yang sama dengan kumpulan data asli. Kemungkinan besar, yang lebih kecil akan berkinerja sama baiknya. Meskipun mereka bahkan tidak perlu memiliki ukuran batch yang sama satu sama lain, disarankan untuk melakukannya untuk kinerja terbaik.

Meskipun tidak benar-benar diperlukan, dianjurkan untuk menggunakan drop_remainder=True untuk dua dataset MinDiff karena ini akan memastikan bahwa mereka memiliki ukuran batch yang konsisten.

original_train_ds = original_train_ds.batch(128)  # Same as before MinDiff.

# The MinDiff datasets can have a different batch_size from original_train_ds
min_diff_female_ds = min_diff_female_ds.batch(32, drop_remainder=True)
# Ideally we use the same batch size for both MinDiff datasets.
min_diff_male_ds = min_diff_male_ds.batch(32, drop_remainder=True)

Kemasan Datasets dengan pack_min_diff_data

Setelah kumpulan data disiapkan, kemas menjadi satu kumpulan data yang kemudian akan diteruskan ke model. Satu kumpulan dari kumpulan data yang dihasilkan akan berisi satu kumpulan dari masing-masing dari tiga kumpulan data yang Anda siapkan sebelumnya.

Anda dapat melakukan ini dengan menggunakan disediakan utils fungsi dalam tensorflow_model_remediation paket:

train_with_min_diff_ds = min_diff.keras.utils.pack_min_diff_data(
    original_dataset=original_train_ds,
    sensitive_group_dataset=min_diff_female_ds,
    nonsensitive_group_dataset=min_diff_male_ds)

Dan itu saja! Anda akan dapat menggunakan lain util fungsi dalam paket untuk batch individu membongkar jika diperlukan.

for inputs, original_labels in train_with_min_diff_ds.take(1):
  # Unpacking min_diff_data
  min_diff_data = min_diff.keras.utils.unpack_min_diff_data(inputs)
  min_diff_examples, min_diff_membership = min_diff_data
  # Unpacking original data
  original_inputs = min_diff.keras.utils.unpack_original_inputs(inputs)

Dengan data Anda yang baru terbentuk, Anda sekarang siap untuk menerapkan MinDiff dalam model Anda! Untuk mempelajari bagaimana hal ini dilakukan, silakan lihat di panduan lain dimulai dengan Mengintegrasikan MinDiff dengan MinDiffModel .

Menggunakan Format Kemasan Kustom (opsional)

Anda dapat memutuskan untuk mengemas ketiga kumpulan data tersebut bersama-sama dengan cara apa pun yang Anda pilih. Satu-satunya persyaratan adalah Anda perlu memastikan model tahu bagaimana menafsirkan data. Implementasi standar dari MinDiffModel mengasumsikan bahwa data dikemas menggunakan min_diff.keras.utils.pack_min_diff_data .

Salah satu cara mudah untuk memformat masukan Anda seperti yang Anda inginkan adalah untuk mengubah data sebagai langkah akhir setelah Anda memiliki bekas min_diff.keras.utils.pack_min_diff_data .

# Reformat input to be a dict.
def _reformat_input(inputs, original_labels):
  unpacked_min_diff_data = min_diff.keras.utils.unpack_min_diff_data(inputs)
  unpacked_original_inputs = min_diff.keras.utils.unpack_original_inputs(inputs)

  return {
      'min_diff_data': unpacked_min_diff_data,
      'original_data': (unpacked_original_inputs, original_labels)}

customized_train_with_min_diff_ds = train_with_min_diff_ds.map(_reformat_input)

Model Anda akan perlu mengetahui cara membaca masukan disesuaikan ini sebagaimana tercantum dalam Menyesuaikan MinDiffModel panduan .

for batch in customized_train_with_min_diff_ds.take(1):
  # Customized unpacking of min_diff_data
  min_diff_data = batch['min_diff_data']
  # Customized unpacking of original_data
  original_data = batch['original_data']

Sumber daya tambahan

Panduan ini menguraikan proses dan pengambilan keputusan yang dapat Anda ikuti setiap kali menerapkan MinDiff. Panduan lainnya membangun kerangka kerja ini. Untuk membuatnya lebih mudah, logika yang ditemukan dalam panduan ini telah diperhitungkan ke dalam fungsi pembantu:

  • get_uci_data : Fungsi ini sudah digunakan dalam panduan ini. Ia mengembalikan DataFrame yang berisi UCI Data pendapatan dari perpecahan ditunjukkan sampel pada tingkat apa pun yang ditunjukkan (100% jika tidak ditentukan).
  • df_to_dataset : Fungsi ini mengubah DataFrame menjadi tf.data.Dataset seperti yang dijelaskan dalam panduan ini dengan fungsi tambahan untuk dapat melewati batch_size sebagai parameter.
  • get_uci_with_min_diff_dataset : kembali fungsi ini sebuah tf.data.Dataset mengandung data asli dan data MinDiff dikemas bersama-sama menggunakan Model Remediasi Perpustakaan util fungsi seperti yang dijelaskan dalam panduan ini.

Panduan lainnya akan dibangun dari ini untuk menunjukkan bagaimana menggunakan bagian lain dari perpustakaan.