Lihat di TensorFlow.org | Jalankan di Google Colab | Lihat sumber di GitHub | Unduh buku catatan |
Tutorial ini menunjukkan cara mengklasifikasikan data terstruktur, seperti data tabular, menggunakan versi sederhana dari kumpulan data PetFinder dari kompetisi Kaggle yang disimpan dalam file CSV.
Anda akan menggunakan Keras untuk mendefinisikan model, dan lapisan prapemrosesan Keras sebagai jembatan untuk memetakan dari kolom dalam file CSV ke fitur yang digunakan untuk melatih model. Tujuannya adalah untuk memprediksi apakah hewan peliharaan akan diadopsi.
Tutorial ini berisi kode lengkap untuk:
- Memuat file CSV ke dalam DataFrame menggunakan pandas .
- Membangun pipa input untuk mengelompokkan dan mengacak baris menggunakan
tf.data
. (Kunjungi tf.data: Membangun pipeline input TensorFlow untuk detail selengkapnya.) - Pemetaan dari kolom dalam file CSV ke fitur yang digunakan untuk melatih model dengan lapisan prapemrosesan Keras.
- Membangun, melatih, dan mengevaluasi model menggunakan metode bawaan Keras.
Kumpulan data mini PetFinder.my
Ada beberapa ribu baris dalam file dataset CSV PetFinder.my mini, di mana setiap baris menggambarkan hewan peliharaan (anjing atau kucing) dan setiap kolom menggambarkan atribut, seperti usia, jenis, warna, dan sebagainya.
Dalam ringkasan dataset di bawah ini, perhatikan sebagian besar kolom numerik dan kategoris. Dalam tutorial ini, Anda hanya akan berurusan dengan dua jenis fitur tersebut, menjatuhkan Description
(fitur teks gratis) dan AdoptionSpeed
(fitur klasifikasi) selama prapemrosesan data.
Kolom | Deskripsi hewan peliharaan | Jenis fitur | Tipe data |
---|---|---|---|
Type | Jenis hewan ( Dog , Cat ) | kategoris | Rangkaian |
Age | Usia | numerik | Bilangan bulat |
Breed1 | Trah primer | kategoris | Rangkaian |
Color1 | Warna 1 | kategoris | Rangkaian |
Color2 | Warna 2 | kategoris | Rangkaian |
MaturitySize | Ukuran saat jatuh tempo | kategoris | Rangkaian |
FurLength | panjang bulu | kategoris | Rangkaian |
Vaccinated | Hewan peliharaan telah divaksinasi | kategoris | Rangkaian |
Sterilized | Hewan peliharaan telah disterilkan | kategoris | Rangkaian |
Health | Kondisi kesehatan | kategoris | Rangkaian |
Fee | Biaya adopsi | numerik | Bilangan bulat |
Description | penulisan profil | Teks | Rangkaian |
PhotoAmt | Jumlah foto yang diunggah | numerik | Bilangan bulat |
AdoptionSpeed | Kecepatan adopsi kategoris | Klasifikasi | Bilangan bulat |
Impor TensorFlow dan perpustakaan lainnya
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
tf.__version__
'2.8.0-rc1'
Muat dataset dan baca ke dalam pandas DataFrame
pandas adalah pustaka Python dengan banyak utilitas bermanfaat untuk memuat dan bekerja dengan data terstruktur. Gunakan tf.keras.utils.get_file
untuk mengunduh dan mengekstrak file CSV dengan dataset mini PetFinder.my, dan memuatnya ke dalam DataFrame dengan pandas.read_csv
:
dataset_url = 'http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip'
csv_file = 'datasets/petfinder-mini/petfinder-mini.csv'
tf.keras.utils.get_file('petfinder_mini.zip', dataset_url,
extract=True, cache_dir='.')
dataframe = pd.read_csv(csv_file)
Downloading data from http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip 1671168/1668792 [==============================] - 0s 0us/step 1679360/1668792 [==============================] - 0s 0us/step
Periksa kumpulan data dengan memeriksa lima baris pertama DataFrame:
dataframe.head()
Buat variabel target
Tugas awal dalam kompetisi Prediksi Adopsi PetFinder.my Kaggle adalah memprediksi kecepatan adopsi hewan peliharaan (misalnya di minggu pertama, bulan pertama, tiga bulan pertama, dan seterusnya).
Dalam tutorial ini, Anda akan menyederhanakan tugas dengan mengubahnya menjadi masalah klasifikasi biner, di mana Anda hanya perlu memprediksi apakah hewan peliharaan diadopsi atau tidak.
Setelah memodifikasi kolom AdoptionSpeed
, 0
akan menunjukkan hewan peliharaan tidak diadopsi, dan 1
akan menunjukkan itu.
# In the original dataset, `'AdoptionSpeed'` of `4` indicates
# a pet was not adopted.
dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1)
# Drop unused features.
dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])
Pisahkan DataFrame menjadi set pelatihan, validasi, dan pengujian
Dataset ada dalam satu DataFrame panda. Bagi menjadi pelatihan, validasi, dan set pengujian menggunakan, misalnya, rasio 80:10:10, masing-masing:
train, val, test = np.split(dataframe.sample(frac=1), [int(0.8*len(dataframe)), int(0.9*len(dataframe))])
print(len(train), 'training examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
9229 training examples 1154 validation examples 1154 test examples
Buat saluran input menggunakan tf.data
Selanjutnya, buat fungsi utilitas yang mengubah setiap pelatihan, validasi, dan kumpulan uji DataFrame menjadi tf.data.Dataset
, lalu mengacak dan mengelompokkan data.
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
df = dataframe.copy()
labels = df.pop('target')
df = {key: value[:,tf.newaxis] for key, value in dataframe.items()}
ds = tf.data.Dataset.from_tensor_slices((dict(df), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
ds = ds.prefetch(batch_size)
return ds
Sekarang, gunakan fungsi yang baru dibuat ( df_to_dataset
) untuk memeriksa format data yang dikembalikan oleh fungsi pembantu pipa input dengan memanggilnya pada data pelatihan, dan gunakan ukuran batch kecil agar output tetap dapat dibaca:
batch_size = 5
train_ds = df_to_dataset(train, batch_size=batch_size)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:4: FutureWarning: Support for multi-dimensional indexing (e.g. `obj[:, None]`) is deprecated and will be removed in a future version. Convert to a numpy array before indexing instead. after removing the cwd from sys.path.
[(train_features, label_batch)] = train_ds.take(1)
print('Every feature:', list(train_features.keys()))
print('A batch of ages:', train_features['Age'])
print('A batch of targets:', label_batch )
Every feature: ['Type', 'Age', 'Breed1', 'Gender', 'Color1', 'Color2', 'MaturitySize', 'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Fee', 'PhotoAmt', 'target'] A batch of ages: tf.Tensor( [[84] [ 1] [ 5] [ 1] [12]], shape=(5, 1), dtype=int64) A batch of targets: tf.Tensor([1 1 0 1 0], shape=(5,), dtype=int64)
Seperti yang ditunjukkan oleh output, set pelatihan mengembalikan kamus nama kolom (dari DataFrame) yang memetakan ke nilai kolom dari baris.
Terapkan lapisan pra-pemrosesan Keras
Lapisan prapemrosesan Keras memungkinkan Anda membangun saluran pemrosesan input asli Keras, yang dapat digunakan sebagai kode prapemrosesan independen dalam alur kerja non-Keras, digabungkan langsung dengan model Keras, dan diekspor sebagai bagian dari Keras SavedModel.
Dalam tutorial ini, Anda akan menggunakan empat lapisan prapemrosesan berikut untuk mendemonstrasikan cara melakukan prapemrosesan, penyandian data terstruktur, dan rekayasa fitur:
-
tf.keras.layers.Normalization
: Melakukan normalisasi fitur dari fitur input. -
tf.keras.layers.CategoryEncoding
: Mengubah fitur kategorikal integer menjadi representasi padat satu-panas, multi-panas, atau tf-idf . -
tf.keras.layers.StringLookup
: Mengubah nilai kategorikal string menjadi indeks integer. -
tf.keras.layers.IntegerLookup
: Mengubah nilai kategorikal integer menjadi indeks integer.
Anda dapat mempelajari lebih lanjut tentang lapisan yang tersedia di panduan Bekerja dengan lapisan prapemrosesan .
- Untuk fitur numerik dari dataset mini PetFinder.my, Anda akan menggunakan lapisan
tf.keras.layers.Normalization
untuk menstandardisasi distribusi data. - Untuk fitur kategoris , seperti pet
Type
s ( StringDog
danCat
), Anda akan mengubahnya menjadi tensor yang disandikan multi-panas dengantf.keras.layers.CategoryEncoding
.
Kolom numerik
Untuk setiap fitur numerik di dataset mini PetFinder.my, Anda akan menggunakan lapisan tf.keras.layers.Normalization
untuk menstandardisasi distribusi data.
Tentukan fungsi utilitas baru yang mengembalikan lapisan yang menerapkan normalisasi fitur ke fitur numerik menggunakan lapisan prapemrosesan Keras itu:
def get_normalization_layer(name, dataset):
# Create a Normalization layer for the feature.
normalizer = layers.Normalization(axis=None)
# Prepare a Dataset that only yields the feature.
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the statistics of the data.
normalizer.adapt(feature_ds)
return normalizer
Selanjutnya, uji fungsi baru dengan memanggilnya pada total fitur foto hewan peliharaan yang diunggah untuk menormalkan 'PhotoAmt'
:
photo_count_col = train_features['PhotoAmt']
layer = get_normalization_layer('PhotoAmt', train_ds)
layer(photo_count_col)
<tf.Tensor: shape=(5, 1), dtype=float32, numpy= array([[-0.8272058 ], [-0.19125296], [ 1.3986291 ], [-0.19125296], [-0.50922936]], dtype=float32)>
Kolom kategoris
Pet Type
s dalam dataset direpresentasikan sebagai string— Dog
s dan Cat
s—yang perlu di-encode multi-hot sebelum dimasukkan ke dalam model. Fitur Age
Tetapkan fungsi utilitas baru lainnya yang mengembalikan lapisan yang memetakan nilai dari kosakata ke indeks bilangan bulat dan mengkodekan fitur multi-hot menggunakan tf.keras.layers.StringLookup
, tf.keras.layers.IntegerLookup
, dan tf.keras.CategoryEncoding
prapemrosesan lapisan:
def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
# Create a layer that turns strings into integer indices.
if dtype == 'string':
index = layers.StringLookup(max_tokens=max_tokens)
# Otherwise, create a layer that turns integer values into integer indices.
else:
index = layers.IntegerLookup(max_tokens=max_tokens)
# Prepare a `tf.data.Dataset` that only yields the feature.
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the set of possible values and assign them a fixed integer index.
index.adapt(feature_ds)
# Encode the integer indices.
encoder = layers.CategoryEncoding(num_tokens=index.vocabulary_size())
# Apply multi-hot encoding to the indices. The lambda function captures the
# layer, so you can use them, or include them in the Keras Functional model later.
return lambda feature: encoder(index(feature))
Uji fungsi get_category_encoding_layer
dengan memanggilnya pada fitur pet 'Type'
untuk mengubahnya menjadi tensor yang disandikan multi-panas:
test_type_col = train_features['Type']
test_type_layer = get_category_encoding_layer(name='Type',
dataset=train_ds,
dtype='string')
test_type_layer(test_type_col)
<tf.Tensor: shape=(5, 3), dtype=float32, numpy= array([[0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.]], dtype=float32)>
Ulangi proses pada fitur 'Age'
hewan peliharaan:
test_age_col = train_features['Age']
test_age_layer = get_category_encoding_layer(name='Age',
dataset=train_ds,
dtype='int64',
max_tokens=5)
test_age_layer(test_age_col)
<tf.Tensor: shape=(5, 5), dtype=float32, numpy= array([[1., 0., 0., 0., 0.], [0., 0., 0., 1., 0.], [1., 0., 0., 0., 0.], [0., 0., 0., 1., 0.], [1., 0., 0., 0., 0.]], dtype=float32)>
Praproses fitur yang dipilih untuk melatih model pada
Anda telah mempelajari cara menggunakan beberapa jenis lapisan prapemrosesan Keras. Selanjutnya, Anda akan:
- Terapkan fungsi utilitas prapemrosesan yang ditentukan sebelumnya pada 13 fitur numerik dan kategoris dari kumpulan data mini PetFinder.my.
- Tambahkan semua input fitur ke daftar.
Seperti yang disebutkan di awal, untuk melatih model, Anda akan menggunakan dataset mini PetFinder.my numerik ( 'PhotoAmt'
, 'Fee'
) dan categorical ( 'Age'
, 'Type'
, 'Color1'
, 'Color2'
, 'Gender'
, 'Ukuran 'MaturitySize'
, 'FurLength'
, 'Vaccinated'
, 'Disterilkan 'Sterilized'
, 'Health'
, 'Breed1'
) fitur.
Sebelumnya, Anda menggunakan ukuran batch kecil untuk mendemonstrasikan saluran input. Sekarang mari kita buat pipeline input baru dengan ukuran batch 256 yang lebih besar:
batch_size = 256
train_ds = df_to_dataset(train, batch_size=batch_size)
val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:4: FutureWarning: Support for multi-dimensional indexing (e.g. `obj[:, None]`) is deprecated and will be removed in a future version. Convert to a numpy array before indexing instead. after removing the cwd from sys.path.
Normalisasi fitur numerik (jumlah foto hewan peliharaan dan biaya adopsi), dan tambahkan ke satu daftar input yang disebut encoded_features
:
all_inputs = []
encoded_features = []
# Numerical features.
for header in ['PhotoAmt', 'Fee']:
numeric_col = tf.keras.Input(shape=(1,), name=header)
normalization_layer = get_normalization_layer(header, train_ds)
encoded_numeric_col = normalization_layer(numeric_col)
all_inputs.append(numeric_col)
encoded_features.append(encoded_numeric_col)
Ubah nilai kategorikal bilangan bulat dari kumpulan data (usia hewan peliharaan) menjadi indeks bilangan bulat, lakukan penyandian multi-panas, dan tambahkan input fitur yang dihasilkan ke encoded_features
:
age_col = tf.keras.Input(shape=(1,), name='Age', dtype='int64')
encoding_layer = get_category_encoding_layer(name='Age',
dataset=train_ds,
dtype='int64',
max_tokens=5)
encoded_age_col = encoding_layer(age_col)
all_inputs.append(age_col)
encoded_features.append(encoded_age_col)
Ulangi langkah yang sama untuk nilai kategorikal string:
categorical_cols = ['Type', 'Color1', 'Color2', 'Gender', 'MaturitySize',
'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Breed1']
for header in categorical_cols:
categorical_col = tf.keras.Input(shape=(1,), name=header, dtype='string')
encoding_layer = get_category_encoding_layer(name=header,
dataset=train_ds,
dtype='string',
max_tokens=5)
encoded_categorical_col = encoding_layer(categorical_col)
all_inputs.append(categorical_col)
encoded_features.append(encoded_categorical_col)
Buat, kompilasi, dan latih model
Langkah selanjutnya adalah membuat model menggunakan Keras Functional API . Untuk lapisan pertama dalam model Anda, gabungkan daftar input fitur— encoded_features
—ke dalam satu vektor melalui penggabungan dengan tf.keras.layers.concatenate
.
all_features = tf.keras.layers.concatenate(encoded_features)
x = tf.keras.layers.Dense(32, activation="relu")(all_features)
x = tf.keras.layers.Dropout(0.5)(x)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(all_inputs, output)
Konfigurasi model dengan Keras Model.compile
:
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=["accuracy"])
Mari kita visualisasikan grafik konektivitas:
# Use `rankdir='LR'` to make the graph horizontal.
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")
Selanjutnya, latih dan uji model:
model.fit(train_ds, epochs=10, validation_data=val_ds)
Epoch 1/10 /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/engine/functional.py:559: UserWarning: Input dict contained keys ['target'] which did not match any model input. They will be ignored by the model. inputs = self._flatten_to_reference_inputs(inputs) 37/37 [==============================] - 2s 19ms/step - loss: 0.6524 - accuracy: 0.5034 - val_loss: 0.5887 - val_accuracy: 0.6941 Epoch 2/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5906 - accuracy: 0.6648 - val_loss: 0.5627 - val_accuracy: 0.7218 Epoch 3/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5697 - accuracy: 0.6924 - val_loss: 0.5463 - val_accuracy: 0.7504 Epoch 4/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5558 - accuracy: 0.6978 - val_loss: 0.5346 - val_accuracy: 0.7504 Epoch 5/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5502 - accuracy: 0.7105 - val_loss: 0.5272 - val_accuracy: 0.7487 Epoch 6/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5415 - accuracy: 0.7123 - val_loss: 0.5210 - val_accuracy: 0.7608 Epoch 7/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5354 - accuracy: 0.7171 - val_loss: 0.5152 - val_accuracy: 0.7435 Epoch 8/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5301 - accuracy: 0.7214 - val_loss: 0.5113 - val_accuracy: 0.7513 Epoch 9/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5286 - accuracy: 0.7189 - val_loss: 0.5087 - val_accuracy: 0.7574 Epoch 10/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5252 - accuracy: 0.7260 - val_loss: 0.5058 - val_accuracy: 0.7539 <keras.callbacks.History at 0x7f5f9fa91c50>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
5/5 [==============================] - 0s 6ms/step - loss: 0.5012 - accuracy: 0.7626 Accuracy 0.762565016746521
Lakukan inferensi
Model yang telah Anda kembangkan sekarang dapat mengklasifikasikan baris dari file CSV secara langsung setelah Anda menyertakan lapisan prapemrosesan di dalam model itu sendiri.
Anda sekarang dapat menyimpan dan memuat ulang model Keras dengan Model.save
dan Model.load_model
sebelum melakukan inferensi pada data baru:
model.save('my_pet_classifier')
reloaded_model = tf.keras.models.load_model('my_pet_classifier')
2022-01-26 06:20:08.013613: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. WARNING:absl:Function `_wrapped_model` contains input name(s) PhotoAmt, Fee, Age, Type, Color1, Color2, Gender, MaturitySize, FurLength, Vaccinated, Sterilized, Health, Breed1 with unsupported characters which will be renamed to photoamt, fee, age, type, color1, color2, gender, maturitysize, furlength, vaccinated, sterilized, health, breed1 in the SavedModel. INFO:tensorflow:Assets written to: my_pet_classifier/assets INFO:tensorflow:Assets written to: my_pet_classifier/assets
Untuk mendapatkan prediksi sampel baru, Anda cukup memanggil metode Keras Model.predict
. Hanya ada dua hal yang perlu Anda lakukan:
- Bungkus skalar ke dalam daftar sehingga memiliki dimensi batch (
Model
hanya memproses kumpulan data, bukan sampel tunggal). - Panggil
tf.convert_to_tensor
pada setiap fitur.
sample = {
'Type': 'Cat',
'Age': 3,
'Breed1': 'Tabby',
'Gender': 'Male',
'Color1': 'Black',
'Color2': 'White',
'MaturitySize': 'Small',
'FurLength': 'Short',
'Vaccinated': 'No',
'Sterilized': 'No',
'Health': 'Healthy',
'Fee': 100,
'PhotoAmt': 2,
}
input_dict = {name: tf.convert_to_tensor([value]) for name, value in sample.items()}
predictions = reloaded_model.predict(input_dict)
prob = tf.nn.sigmoid(predictions[0])
print(
"This particular pet had a %.1f percent probability "
"of getting adopted." % (100 * prob)
)
This particular pet had a 77.7 percent probability of getting adopted.
Langkah selanjutnya
Untuk mempelajari lebih lanjut tentang mengklasifikasikan data terstruktur, coba gunakan set data lain. Untuk meningkatkan akurasi selama pelatihan dan pengujian model Anda, pikirkan baik-baik fitur mana yang akan disertakan dalam model Anda dan bagaimana fitur tersebut harus ditampilkan.
Di bawah ini adalah beberapa saran untuk kumpulan data:
- TensorFlow Datasets: MovieLens : Kumpulan peringkat film dari layanan rekomendasi film.
- Kumpulan Data TensorFlow: Kualitas Anggur : Dua kumpulan data yang terkait dengan varian merah dan putih dari anggur "Vinho Verde" Portugis. Anda juga dapat menemukan kumpulan data Kualitas Anggur Merah di Kaggle .
- Kaggle: arXiv Dataset : Kumpulan 1,7 juta artikel ilmiah dari arXiv, meliputi fisika, ilmu komputer, matematika, statistik, teknik elektro, biologi kuantitatif, dan ekonomi.