Keras ön işleme katmanlarını kullanarak yapılandırılmış verileri sınıflandırın

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Bu öğretici, bir CSV dosyasında depolanan bir Kaggle yarışmasından PetFinder veri kümesinin basitleştirilmiş bir sürümünü kullanarak tablo verileri gibi yapılandırılmış verilerin nasıl sınıflandırılacağını gösterir.

Modeli tanımlamak için Keras'ı ve bir CSV dosyasındaki sütunlardan modeli eğitmek için kullanılan özelliklere eşlemek için bir köprü olarak Keras ön işleme katmanlarını kullanacaksınız. Amaç, bir evcil hayvanın kabul edilip edilmeyeceğini tahmin etmektir.

Bu eğitici, aşağıdakiler için tam kod içerir:

  • Pandas kullanarak bir DataFrame'e CSV dosyası yükleme .
  • tf.data kullanarak satırları gruplamak ve karıştırmak için bir girdi ardışık düzeni oluşturma. (Daha fazla ayrıntı için tf.data adresini ziyaret edin : TensorFlow giriş ardışık düzenleri oluşturun .)
  • CSV dosyasındaki sütunlardan, modeli Keras ön işleme katmanlarıyla eğitmek için kullanılan özelliklerle eşleme.
  • Keras yerleşik yöntemlerini kullanarak bir model oluşturma, eğitme ve değerlendirme.

PetFinder.my mini veri seti

PetFinder.my mini'nin CSV veri kümesi dosyasında, her satırın bir evcil hayvanı (bir köpek veya bir kedi) tanımladığı ve her sütunun yaş, cins, renk vb. gibi bir özelliği tanımladığı birkaç bin satır vardır.

Aşağıdaki veri kümesinin özetinde, çoğunlukla sayısal ve kategorik sütunlar olduğuna dikkat edin. Bu öğreticide, veri ön işleme sırasında Description (bir serbest metin özelliği) ve AdoptionSpeed (bir sınıflandırma özelliği) bırakarak yalnızca bu iki özellik türüyle ilgileneceksiniz.

Kolon Evcil hayvan açıklaması Özellik türü Veri tipi
Type Hayvan türü ( Dog , Cat ) Kategorik Sicim
Age Yaş Sayısal tamsayı
Breed1 Birincil cins Kategorik Sicim
Color1 renk 1 Kategorik Sicim
Color2 renk 2 Kategorik Sicim
MaturitySize Olgunluktaki boyut Kategorik Sicim
FurLength kürk uzunluğu Kategorik Sicim
Vaccinated Evcil hayvan aşılandı Kategorik Sicim
Sterilized Evcil hayvan sterilize edildi Kategorik Sicim
Health Sağlık durumu Kategorik Sicim
Fee evlat edinme ücreti Sayısal tamsayı
Description Profil yazma Metin Sicim
PhotoAmt Toplam yüklenen fotoğraf Sayısal tamsayı
AdoptionSpeed Kategorik benimseme hızı sınıflandırma tamsayı

TensorFlow ve diğer kitaplıkları içe aktarın

import numpy as np
import pandas as pd
import tensorflow as tf

from tensorflow.keras import layers
tf.__version__
-yer tutucu2 l10n-yer
'2.8.0-rc1'

Veri kümesini yükleyin ve bir panda DataFrame'e okuyun

pandas , yapılandırılmış verileri yüklemek ve bunlarla çalışmak için birçok yararlı yardımcı program içeren bir Python kitaplığıdır. PetFinder.my mini veri kümesiyle CSV dosyasını indirip ayıklamak için tf.keras.utils.get_file kullanın ve onu pandas.read_csv ile bir 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)
tutucu4 l10n-yer
Downloading data from http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip
1671168/1668792 [==============================] - 0s 0us/step
1679360/1668792 [==============================] - 0s 0us/step

DataFrame'in ilk beş satırını kontrol ederek veri kümesini inceleyin:

dataframe.head()

Bir hedef değişken oluşturun

Kaggle'ın PetFinder.my Evlat Edinme Tahmini yarışmasındaki asıl görev, bir evcil hayvanın sahiplenilme hızını tahmin etmekti (örneğin, ilk hafta, ilk ay, ilk üç ay, vb.).

Bu öğreticide, bir evcil hayvanın sahiplenilip alınmadığını tahmin etmeniz gereken ikili sınıflandırma problemine dönüştürerek görevi basitleştireceksiniz.

AdoptionSpeed sütununu değiştirdikten sonra 0 , evcil hayvanın sahiplenilmediğini, 1 ise kabul edildiğini gösterecektir.

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

DataFrame'i eğitim, doğrulama ve test kümelerine ayırın

Veri kümesi tek bir panda DataFrame'dedir. Sırasıyla örneğin 80:10:10 oranını kullanarak eğitim, doğrulama ve test kümelerine ayırın:

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')
-yer tutucu9 l10n-yer
9229 training examples
1154 validation examples
1154 test examples

tf.data kullanarak bir girdi işlem hattı oluşturun

Ardından, her eğitim, doğrulama ve test kümesi DataFrame'i bir tf.data.Dataset 'e dönüştüren, ardından verileri karıştıran ve gruplandıran bir yardımcı program işlevi oluşturun.

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

Şimdi, yeni oluşturulan işlevi ( df_to_dataset ) giriş işlem hattı yardımcı işlevinin eğitim verilerinde çağırarak döndürdüğü verilerin biçimini kontrol etmek için kullanın ve çıktıyı okunabilir kılmak için küçük bir toplu iş boyutu kullanın:

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.
yer tutucu13 l10n-yer
[(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)

Çıktının gösterdiği gibi, eğitim seti, satırlardan sütun değerlerine eşlenen (DataFrame'den) bir sütun adları sözlüğü döndürür.

Keras ön işleme katmanlarını uygulayın

Keras ön işleme katmanları, Keras dışı iş akışlarında bağımsız ön işleme kodu olarak kullanılabilen, doğrudan Keras modelleriyle birleştirilen ve Keras SavedModel'in bir parçası olarak dışa aktarılan Keras'a özgü girdi işleme boru hatları oluşturmanıza olanak tanır.

Bu öğreticide, ön işleme, yapılandırılmış veri kodlama ve özellik mühendisliğinin nasıl gerçekleştirileceğini göstermek için aşağıdaki dört ön işleme katmanını kullanacaksınız:

Kullanılabilir katmanlar hakkında daha fazla bilgiyi Ön işleme katmanlarıyla çalışma kılavuzunda bulabilirsiniz.

  • PetFinder.my mini veri kümesinin sayısal özellikleri için, verilerin dağılımını standartlaştırmak için bir tf.keras.layers.Normalization katmanı kullanacaksınız.
  • Pet Type s ( Dog ve Cat dizeleri) gibi kategorik özellikler için, bunları tf.keras.layers.CategoryEncoding ile çok sıcak kodlanmış tensörlere dönüştüreceksiniz.

sayısal sütunlar

PetFinder.my mini veri setindeki her sayısal özellik için, verilerin dağılımını standartlaştırmak için bir tf.keras.layers.Normalization katmanı kullanacaksınız.

Bu Keras ön işleme katmanını kullanarak sayısal özelliklere özellik bazında normalleştirme uygulayan bir katman döndüren yeni bir yardımcı işlev tanımlayın:

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

Ardından, 'PhotoAmt' normalleştirmek için yüklenen toplam evcil hayvan fotoğrafı özelliklerinde çağırarak yeni işlevi test edin:

photo_count_col = train_features['PhotoAmt']
layer = get_normalization_layer('PhotoAmt', train_ds)
layer(photo_count_col)
tutucu17 l10n-yer
<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
array([[-0.8272058 ],
       [-0.19125296],
       [ 1.3986291 ],
       [-0.19125296],
       [-0.50922936]], dtype=float32)>

kategorik sütunlar

Veri kümesindeki Pet Type , modele beslenmeden önce multi-hot olarak kodlanması gereken, Dog s ve Cat s dizileri olarak temsil edilir. Age özelliği

Değerleri bir sözlükten tamsayı endekslerine eşleyen ve multi-hot özellikleri tf.keras.layers.StringLookup , tf.keras.layers.IntegerLookup ve tf.keras.CategoryEncoding ön işlemeyi kullanarak kodlayan bir katman döndüren başka bir yeni yardımcı işlev tanımlayın katmanlar:

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

get_category_encoding_layer işlevini, onları çok sıcak kodlanmış tensörlere dönüştürmek için pet 'Type' özelliklerinde çağırarak test edin:

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)
tutucu20 l10n-yer
<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)>

Evcil hayvan 'Age' özellikleri için işlemi tekrarlayın:

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)
tutucu22 l10n-yer
<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)>

Modeli eğitmek için seçilen özellikleri önceden işleme

Birkaç tür Keras ön işleme katmanının nasıl kullanılacağını öğrendiniz. Ardından, şunları yapacaksınız:

  • PetFinder.my mini veri setindeki 13 sayısal ve kategorik özellik üzerinde daha önce tanımlanan ön işleme yardımcı fonksiyonlarını uygulayın.
  • Tüm özellik girişlerini bir listeye ekleyin.

Başlangıçta belirtildiği gibi, modeli eğitmek için PetFinder.my mini veri setinin sayısal ( 'PhotoAmt' , 'Fee' ) ve kategorik ( 'Age' , 'Type' , 'Color1' , 'Color2' , 'Gender' , 'MaturitySize' , 'FurLength' , 'Aşılı', 'Sterilized' , 'Health' , 'Vaccinated' 'Breed1' ) özellikleri.

Daha önce, girdi işlem hattını göstermek için küçük bir toplu iş boyutu kullandınız. Şimdi daha büyük bir parti boyutu 256 olan yeni bir girdi ardışık düzeni oluşturalım:

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)
tutucu24 l10n-yer
/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.

Sayısal özellikleri (evcil hayvan fotoğraflarının sayısı ve evlat edinme ücreti) normalleştirin ve bunları encoded_features adlı bir girdi listesine ekleyin:

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)

Veri kümesindeki (evcil hayvan yaşı) tamsayı kategorik değerlerini tamsayı endekslerine dönüştürün, çok sıcak kodlama gerçekleştirin ve elde edilen özellik girişlerini encoded_features öğesine ekleyin:

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)

Dize kategorik değerleri için aynı adımı tekrarlayın:

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)

Modeli oluşturun, derleyin ve eğitin

Sonraki adım, Keras İşlevsel API'sini kullanarak bir model oluşturmaktır. Modelinizdeki ilk katman için, özellik girdileri listesini — tf.keras.layers.concatenateencoded_features ile birleştirme yoluyla tek bir vektörde birleştirin.

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)

Modeli Model.compile ile yapılandırın:

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=["accuracy"])

Bağlantı grafiğini görselleştirelim:

# Use `rankdir='LR'` to make the graph horizontal.
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")

png

Ardından, modeli eğitin ve test edin:

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>
yer tutucu33 l10n-yer
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
5/5 [==============================] - 0s 6ms/step - loss: 0.5012 - accuracy: 0.7626
Accuracy 0.762565016746521

çıkarım yap

Geliştirdiğiniz model, ön işleme katmanlarını modelin kendi içine dahil ettikten hemen sonra bir CSV dosyasındaki bir satırı sınıflandırabilir.

Artık yeni veriler üzerinde çıkarım yapmadan önce Keras modelini Model.save ve Model.load_model ile kaydedebilir ve yeniden yükleyebilirsiniz:

model.save('my_pet_classifier')
reloaded_model = tf.keras.models.load_model('my_pet_classifier')
tutucu36 l10n-yer
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

Yeni bir örnek için bir tahmin almak için Model.predict yöntemini çağırmanız yeterlidir. Yapmanız gereken sadece iki şey var:

  1. Parti boyutuna sahip olmak için skaleri bir listeye sarın ( Model tek örnekleri değil, yalnızca veri gruplarını işler).
  2. Her özellik için tf.convert_to_tensor çağırın.
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)
)
tutucu38 l10n-yer
This particular pet had a 77.7 percent probability of getting adopted.

Sonraki adımlar

Yapılandırılmış verileri sınıflandırma hakkında daha fazla bilgi edinmek için diğer veri kümeleriyle çalışmayı deneyin. Modellerinizi eğitirken ve test ederken doğruluğu artırmak için modelinize hangi özellikleri ekleyeceğinizi ve bunların nasıl temsil edilmesi gerektiğini dikkatlice düşünün.

Aşağıda veri kümeleri için bazı öneriler bulunmaktadır: