Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

Yapılandırılmış verileri özellik sütunlarıyla sınıflandırın

TensorFlow.org'da görüntüleyin Google Colab'de çalıştırın Kaynağı GitHub'da görüntüleyin Defteri indirin

Bu eğitim, yapılandırılmış verilerin nasıl sınıflandırılacağını gösterir (örneğin, bir CSV'deki tablo verileri). Modeli tanımlamak için Keras'ı ve bir CSV'deki sütunlardan modeli eğitmek için kullanılan özelliklere eşlemek için bir köprü olarak sütunları kullanacağız. Bu öğretici, aşağıdakilere yönelik tam kod içerir:

  • Pandaları kullanarak bir CSV dosyası yükleyin.
  • Tf.data kullanarak satırları toplu işlemek ve karıştırmak için bir giriş ardışık düzeni oluşturun .
  • Özellik sütunlarını kullanarak modeli eğitmek için kullanılan özelliklerle CSV'deki sütunlardan eşleyin.
  • Keras kullanarak bir model oluşturun, eğitin ve değerlendirin.

Veri Kümesi

PetFinder veri kümesinin basitleştirilmiş bir sürümünü kullanacağız. CSV'de birkaç bin satır var. Her satır bir evcil hayvanı açıklar ve her sütun bir özniteliği açıklar. Bu bilgiyi, evcil hayvanın sahiplenileceği hızı tahmin etmek için kullanacağız.

Aşağıda bu veri kümesinin bir açıklaması bulunmaktadır. Hem sayısal hem de kategorik sütunların olduğuna dikkat edin. Bu eğitimde kullanmayacağımız bir serbest metin sütunu var.

Sütun Açıklama Özellik Türü Veri tipi
Tür Hayvan türü (Köpek, Kedi) Kategorik dizi
Yaş Evcil hayvanın yaşı Sayısal tamsayı
Irk1 Evcil hayvanın birincil cinsi Kategorik dizi
Renk1 Evcil hayvanın rengi 1 Kategorik dizi
Renk2 Evcil hayvanın rengi 2 Kategorik dizi
OlgunlukBoyut Vade sonunda boyut Kategorik dizi
FurLength Kürk uzunluğu Kategorik dizi
Aşılanmış Evcil hayvan aşılandı Kategorik dizi
Sterilize Evcil hayvan sterilize edildi Kategorik dizi
Sağlık Sağlık durumu Kategorik dizi
Ücret Benimseme Ücreti Sayısal tamsayı
Açıklama Bu evcil hayvan için profil yazımı Metin dizi
PhotoAmt Bu evcil hayvan için yüklenen toplam fotoğraf Sayısal tamsayı
Benimseme Hızı Evlat edinme hızı Sınıflandırma tamsayı

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

pip install -q sklearn
import numpy as np
import pandas as pd

import tensorflow as tf

from tensorflow import feature_column
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split

Bir veri çerçevesi oluşturmak için Pandalar'ı kullanın

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. Veri setini bir URL'den indirmek ve bir veri çerçevesine yüklemek için Pandalar'ı kullanacağız.

import pathlib

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

dataframe.head()

Hedef değişken oluştur

Orijinal veri kümesindeki görev, bir evcil hayvanın sahiplenileceği hızı tahmin etmektir (örneğin, ilk hafta, ilk ay, ilk üç ay vb.). Öğreticimiz için bunu basitleştirelim. Burada, bunu ikili bir sınıflandırma problemine dönüştüreceğiz ve basitçe evcil hayvanın benimsenip evlat edinilmediğini tahmin edeceğiz.

Etiket sütununu değiştirdikten sonra, 0, evcil hayvanın sahiplenilmediğini ve 1, evcil hayvanın sahiplenilmediğini gösterecektir.

# In the original dataset "4" indicates the pet was not adopted.
dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1)

# Drop un-used columns.
dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])

Veri çerçevesini eğitim, doğrulama ve teste ayırın

İndirdiğimiz veri kümesi tek bir CSV dosyasıydı. Bunu tren, doğrulama ve test setlerine ayıracağız.

train, test = train_test_split(dataframe, test_size=0.2)
train, val = train_test_split(train, test_size=0.2)
print(len(train), 'train examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
7383 train examples
1846 validation examples
2308 test examples

Tf.data kullanarak bir giriş ardışık düzeni oluşturun

Ardından, veri çerçevelerini tf.data ile sarmalayacağız . Bu, Pandas veri çerçevesindeki sütunlardan modeli eğitmek için kullanılan özelliklere eşlemek için özellik sütunlarını bir köprü olarak kullanmamızı sağlayacaktır. Çok büyük bir CSV dosyasıyla çalışıyor olsaydık (belleğe sığmayacak kadar büyük), doğrudan diskten okumak için tf.data kullanırdık. Bu, bu öğreticide ele alınmamaktadır.

# A utility method to create a tf.data dataset from a Pandas Dataframe
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
  dataframe = dataframe.copy()
  labels = dataframe.pop('target')
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(dataframe))
  ds = ds.batch(batch_size)
  return ds
batch_size = 5 # A small batch sized is used for demonstration purposes
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)

Giriş ardışık düzenini anlayın

Şimdi girdi pipeline'ı oluşturduğumuza göre, onu geri döndürdüğü verilerin formatını görmek için arayalım. Çıktıyı okunabilir tutmak için küçük bir parti boyutu kullandık.

for feature_batch, label_batch in train_ds.take(1):
  print('Every feature:', list(feature_batch.keys()))
  print('A batch of ages:', feature_batch['Age'])
  print('A batch of targets:', label_batch )
Every feature: ['Type', 'Age', 'Breed1', 'Gender', 'Color1', 'Color2', 'MaturitySize', 'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Fee', 'PhotoAmt']
A batch of ages: tf.Tensor([36 48  3 30 24], shape=(5,), dtype=int64)
A batch of targets: tf.Tensor([1 0 1 0 0], shape=(5,), dtype=int64)

Veri kümesinin, veri çerçevesindeki satırlardan sütun değerleriyle eşleşen bir sütun adları sözlüğü (veri çerçevesinden) döndürdüğünü görebiliriz.

Birkaç tür özellik sütununu gösterin

TensorFlow birçok türde özellik sütunu sağlar. Bu bölümde, birkaç tür özellik sütunu oluşturacağız ve bir sütunu veri çerçevesinden nasıl dönüştürdüklerini göstereceğiz.

# We will use this batch to demonstrate several types of feature columns
example_batch = next(iter(train_ds))[0]
# A utility method to create a feature column
# and to transform a batch of data
def demo(feature_column):
  feature_layer = layers.DenseFeatures(feature_column)
  print(feature_layer(example_batch).numpy())

Sayısal sütunlar

Bir özellik sütununun çıktısı modelin girdisi olur (yukarıda tanımlanan demo işlevini kullanarak, veri çerçevesindeki her sütunun tam olarak nasıl dönüştürüldüğünü görebileceğiz). Sayısal sütun , en basit sütun türüdür. Gerçek değerli özellikleri temsil etmek için kullanılır. Bu sütunu kullanırken, modeliniz sütun değerini veri çerçevesinden değiştirmeden alacaktır.

photo_count = feature_column.numeric_column('PhotoAmt')
demo(photo_count)
[[1.]
 [2.]
 [2.]
 [4.]
 [1.]]

PetFinder veri kümesinde, veri çerçevesindeki çoğu sütun kategoriktir.

Bölümlenmiş sütunlar

Genellikle, bir sayıyı doğrudan modele beslemek istemezsiniz, bunun yerine değerini sayısal aralıklara göre farklı kategorilere ayırırsınız. Bir kişinin yaşını temsil eden ham verileri düşünün. Yaşı sayısal bir sütun olarak göstermek yerine, gruplanmış bir sütun kullanarak yaşı birkaç gruba ayırabiliriz . Aşağıdaki tek sıcak değerlerin her satırın hangi yaş aralığıyla eşleştiğini tanımladığına dikkat edin.

age = feature_column.numeric_column('Age')
age_buckets = feature_column.bucketized_column(age, boundaries=[1, 3, 5])
demo(age_buckets)
[[0. 0. 0. 1.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]]

Kategorik sütunlar

Bu veri kümesinde, Tür bir dize olarak temsil edilir (ör. "Köpek" veya "Kedi"). Dizeleri doğrudan bir modele besleyemeyiz. Bunun yerine, önce onları sayısal değerlerle eşlemeliyiz. Kategorik kelime sütunları dizeleri tek sıcak vektör olarak temsil etmenin bir yolunu sağlar (yukarıda yaş gruplarında gördüğünüz gibi). Kelime haznesi categorical_column_with_vocabulary_list kullanılarak bir liste olarak aktarılabilir veya categorical_column_with_vocabulary_file kullanılarak bir dosyadan yüklenebilir.

animal_type = feature_column.categorical_column_with_vocabulary_list(
      'Type', ['Cat', 'Dog'])

animal_type_one_hot = feature_column.indicator_column(animal_type)
demo(animal_type_one_hot)
[[1. 0.]
 [1. 0.]
 [0. 1.]
 [0. 1.]
 [0. 1.]]

Sütunları katıştırma

Sadece birkaç olası diziye sahip olmak yerine, kategori başına binlerce (veya daha fazla) değerimiz olduğunu varsayalım. Birkaç nedenden dolayı, kategorilerin sayısı arttıkça, tek sıcak kodlamalar kullanarak bir sinir ağını eğitmek olanaksız hale gelir. Bu sınırlamanın üstesinden gelmek için bir gömme sütunu kullanabiliriz. Bir gömme sütunu , verileri birçok boyutun tek sıcak vektörü olarak temsil etmek yerine, bu verileri daha düşük boyutlu, yoğun bir vektör olarak temsil eder; burada her bir hücre sadece 0 veya 1 değil, herhangi bir sayıyı içerebilir. 8, aşağıdaki örnekte) ayarlanması gereken bir parametredir.

# Notice the input to the embedding column is the categorical column
# we previously created
breed1 = feature_column.categorical_column_with_vocabulary_list(
      'Breed1', dataframe.Breed1.unique())
breed1_embedding = feature_column.embedding_column(breed1, dimension=8)
demo(breed1_embedding)
[[ 0.3324157   0.4197986   0.50347906 -0.49933374  0.01970459 -0.2535548
  -0.01637078  0.37853056]
 [ 0.38036337  0.20561606 -0.15727694  0.00184843 -0.19711411  0.46115682
  -0.05730496 -0.35953665]
 [-0.03274023  0.36311874  0.3822702   0.12975089 -0.6652591   0.5957904
   0.49060807 -0.05435312]
 [ 0.44843388 -0.00815179  0.11813674 -0.22067873  0.03251803 -0.3833288
  -0.45184475  0.5564358 ]
 [ 0.44843388 -0.00815179  0.11813674 -0.22067873  0.03251803 -0.3833288
  -0.45184475  0.5564358 ]]

Hashing uygulanmış özellik sütunları

Değerleri ile çok sayıda kategorik sütun temsil etmek için başka bir yol, bir kullanmaktır categorical_column_with_hash_bucket . Bu özellik sütunu, girişin bir karma değerini hesaplar ve ardından bir dizeyi kodlamak için hash_bucket_size birini seçer. Bu sütunu kullanırken, kelime dağarcığı sağlamanıza gerek yoktur ve yer kazanmak için hash_bucket sayısını gerçek kategori sayısından önemli ölçüde daha küçük yapmayı seçebilirsiniz.

breed1_hashed = feature_column.categorical_column_with_hash_bucket(
      'Breed1', hash_bucket_size=10)
demo(feature_column.indicator_column(breed1_hashed))
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]

Çapraz özellik sütunları

Özellikleri, daha iyi özellik çarpımları olarak bilinen tek bir özellikte birleştirmek, bir modelin her özellik kombinasyonu için ayrı ağırlıkları öğrenmesini sağlar. Burada, Yaş ve Türün kesiştiği yeni bir özellik oluşturacağız. crossed_column tüm olası kombinasyonların tam tablosunu oluşturmadığını unutmayın (çok büyük olabilir). Bunun yerine, bir hashed_column ile desteklenir, böylece tablonun ne kadar büyük olduğunu seçebilirsiniz.

crossed_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=10)
demo(feature_column.indicator_column(crossed_feature))
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]]

Hangi sütunları kullanacağınızı seçin

Birkaç tür özellik sütununu nasıl kullanacağımızı gördük. Şimdi onları bir model yetiştirmek için kullanacağız. Bu öğreticinin amacı, size özellik sütunlarıyla çalışmak için gereken tüm kodu (örn. Mekanikler) göstermektir. Aşağıda modelimizi keyfi olarak eğitmek için birkaç sütun seçtik.

feature_columns = []

# numeric cols
for header in ['PhotoAmt', 'Fee', 'Age']:
  feature_columns.append(feature_column.numeric_column(header))
# bucketized cols
age = feature_column.numeric_column('Age')
age_buckets = feature_column.bucketized_column(age, boundaries=[1, 2, 3, 4, 5])
feature_columns.append(age_buckets)
# indicator_columns
indicator_column_names = ['Type', 'Color1', 'Color2', 'Gender', 'MaturitySize',
                          'FurLength', 'Vaccinated', 'Sterilized', 'Health']
for col_name in indicator_column_names:
  categorical_column = feature_column.categorical_column_with_vocabulary_list(
      col_name, dataframe[col_name].unique())
  indicator_column = feature_column.indicator_column(categorical_column)
  feature_columns.append(indicator_column)
# embedding columns
breed1 = feature_column.categorical_column_with_vocabulary_list(
      'Breed1', dataframe.Breed1.unique())
breed1_embedding = feature_column.embedding_column(breed1, dimension=8)
feature_columns.append(breed1_embedding)
# crossed columns
age_type_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=100)
feature_columns.append(feature_column.indicator_column(age_type_feature))

Bir özellik katmanı oluşturun

Artık özellik sütunlarımızı tanımladığımıza göre, bunları Keras modelimize girmek için bir DenseFeatures katmanı kullanacağız.

feature_layer = tf.keras.layers.DenseFeatures(feature_columns)

Daha önce, özellik sütunlarının nasıl çalıştığını göstermek için küçük bir parti boyutu kullandık. Daha büyük parti boyutuna sahip yeni bir girdi ardışık düzeni oluşturuyoruz.

batch_size = 32
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)

Modeli oluşturun, derleyin ve eğitin

model = tf.keras.Sequential([
  feature_layer,
  layers.Dense(128, activation='relu'),
  layers.Dense(128, activation='relu'),
  layers.Dropout(.1),
  layers.Dense(1)
])

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

model.fit(train_ds,
          validation_data=val_ds,
          epochs=10)
Epoch 1/10
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
225/231 [============================>.] - ETA: 0s - loss: 0.6649 - accuracy: 0.6749WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
231/231 [==============================] - 3s 11ms/step - loss: 0.6621 - accuracy: 0.6768 - val_loss: 0.5403 - val_accuracy: 0.6891
Epoch 2/10
231/231 [==============================] - 2s 8ms/step - loss: 0.5542 - accuracy: 0.7154 - val_loss: 0.5154 - val_accuracy: 0.7210
Epoch 3/10
231/231 [==============================] - 2s 8ms/step - loss: 0.5178 - accuracy: 0.7268 - val_loss: 0.4996 - val_accuracy: 0.7411
Epoch 4/10
231/231 [==============================] - 2s 8ms/step - loss: 0.5044 - accuracy: 0.7295 - val_loss: 0.4856 - val_accuracy: 0.7449
Epoch 5/10
231/231 [==============================] - 2s 7ms/step - loss: 0.4956 - accuracy: 0.7398 - val_loss: 0.4814 - val_accuracy: 0.7486
Epoch 6/10
231/231 [==============================] - 2s 8ms/step - loss: 0.4894 - accuracy: 0.7363 - val_loss: 0.4875 - val_accuracy: 0.7514
Epoch 7/10
231/231 [==============================] - 2s 7ms/step - loss: 0.4832 - accuracy: 0.7413 - val_loss: 0.4824 - val_accuracy: 0.7443
Epoch 8/10
231/231 [==============================] - 2s 7ms/step - loss: 0.4766 - accuracy: 0.7469 - val_loss: 0.4907 - val_accuracy: 0.7134
Epoch 9/10
231/231 [==============================] - 2s 8ms/step - loss: 0.4749 - accuracy: 0.7492 - val_loss: 0.4838 - val_accuracy: 0.7503
Epoch 10/10
231/231 [==============================] - 2s 7ms/step - loss: 0.4673 - accuracy: 0.7502 - val_loss: 0.4847 - val_accuracy: 0.7486

<tensorflow.python.keras.callbacks.History at 0x7f3b296a8e48>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
73/73 [==============================] - 0s 5ms/step - loss: 0.5179 - accuracy: 0.7413
Accuracy 0.7413344979286194

Sonraki adımlar

Yapılandırılmış verileri sınıflandırmayla ilgili daha fazla bilgi edinmenin en iyi yolu, onu kendiniz denemektir. Çalışmak için başka bir veri kümesi bulmanızı ve yukarıdakine benzer bir kod kullanarak bir modeli sınıflandırmak için eğitmenizi öneririz. Doğruluğu artırmak için, modelinize hangi özellikleri dahil edeceğinizi ve bunların nasıl temsil edileceğini dikkatlice düşünün.