จำแนกข้อมูลที่มีโครงสร้างด้วยคอลัมน์คุณลักษณะ

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

บทช่วยสอนนี้สาธิตวิธีการจัดประเภทข้อมูลที่มีโครงสร้าง (เช่น ข้อมูลแบบตารางใน CSV) เราจะใช้ Keras เพื่อกำหนดโมเดล และ tf.feature_column เป็นสะพานเชื่อมไปยังแมปจากคอลัมน์ใน CSV กับฟีเจอร์ที่ใช้ในการฝึกโมเดล บทช่วยสอนนี้มีรหัสที่สมบูรณ์เพื่อ:

  • โหลดไฟล์ CSV โดยใช้ Pandas
  • สร้างไพพ์ไลน์อินพุตเพื่อแบทช์และสับเปลี่ยนแถวโดยใช้ tf.data
  • แมปจากคอลัมน์ใน CSV ไปยังจุดสนใจที่ใช้ในการฝึกโมเดลโดยใช้คอลัมน์คุณลักษณะ
  • สร้าง ฝึกฝน และประเมินโมเดลโดยใช้ Keras

ชุดข้อมูล

เราจะใช้ ชุดข้อมูล PetFinder รุ่นที่เรียบง่าย CSV มีหลายพันแถว แต่ละแถวอธิบายสัตว์เลี้ยง และแต่ละคอลัมน์อธิบายแอตทริบิวต์ เราจะใช้ข้อมูลนี้เพื่อคาดการณ์ความเร็วที่สัตว์เลี้ยงจะถูกรับเลี้ยง

ต่อไปนี้เป็นคำอธิบายของชุดข้อมูลนี้ สังเกตว่ามีทั้งคอลัมน์ตัวเลขและหมวดหมู่ มีคอลัมน์ข้อความฟรีซึ่งเราจะไม่ใช้ในบทช่วยสอนนี้

คอลัมน์ คำอธิบาย ประเภทคุณสมบัติ ประเภทข้อมูล
พิมพ์ ประเภทสัตว์ (สุนัข แมว) หมวดหมู่ สตริง
อายุ อายุของสัตว์เลี้ยง ตัวเลข จำนวนเต็ม
พันธุ์1 สายพันธุ์หลักของสัตว์เลี้ยง หมวดหมู่ สตริง
สี1 สี 1 ของสัตว์เลี้ยง หมวดหมู่ สตริง
Color2 สีที่ 2 ของสัตว์เลี้ยง หมวดหมู่ สตริง
ขนาดครบกำหนด ขนาดเมื่อครบกำหนด หมวดหมู่ สตริง
ความยาวขน ความยาวขน หมวดหมู่ สตริง
ฉีดวัคซีนแล้ว สัตว์เลี้ยงได้รับการฉีดวัคซีน หมวดหมู่ สตริง
ฆ่าเชื้อ สัตว์เลี้ยงได้รับการฆ่าเชื้อ หมวดหมู่ สตริง
สุขภาพ เงื่อนไขสุขภาพ หมวดหมู่ สตริง
ค่าธรรมเนียม ค่าธรรมเนียมการรับเลี้ยงบุตรบุญธรรม ตัวเลข จำนวนเต็ม
คำอธิบาย การเขียนโปรไฟล์สำหรับสัตว์เลี้ยงตัวนี้ ข้อความ สตริง
PhotoAmt รูปที่อัพโหลดทั้งหมดสำหรับสัตว์เลี้ยงตัวนี้ ตัวเลข จำนวนเต็ม
การยอมรับความเร็ว ความเร็วในการนำไปใช้ การจำแนกประเภท จำนวนเต็ม

นำเข้า TensorFlow และไลบรารีอื่นๆ

pip install 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

ใช้ Pandas เพื่อสร้าง dataframe

Pandas เป็นไลบรารี Python ที่มียูทิลิตี้ที่เป็นประโยชน์มากมายสำหรับการโหลดและทำงานกับข้อมูลที่มีโครงสร้าง เราจะใช้ Pandas เพื่อดาวน์โหลดชุดข้อมูลจาก URL และโหลดลงใน dataframe

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
1679360/1668792 [==============================] - 0s 0us/step
dataframe.head()

สร้างตัวแปรเป้าหมาย

งานในชุดข้อมูลเดิมคือการคาดการณ์ความเร็วที่สัตว์เลี้ยงจะถูกนำมาใช้ (เช่น ในสัปดาห์แรก เดือนแรก 3 เดือนแรก เป็นต้น) มาทำให้สิ่งนี้ง่ายขึ้นสำหรับบทช่วยสอนของเรา ในที่นี้ เราจะแปลงสิ่งนี้ให้เป็นปัญหาการจำแนกเลขฐานสอง และเพียงคาดเดาว่าสัตว์เลี้ยงนั้นถูกรับเลี้ยงหรือไม่

หลังจากแก้ไขคอลัมน์ป้ายกำกับแล้ว 0 จะระบุว่าสัตว์เลี้ยงไม่ได้ถูกรับเลี้ยง และ 1 จะระบุว่าเป็นสัตว์เลี้ยง

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

แบ่ง dataframe เป็น train, validation และ test

ชุดข้อมูลที่เราดาวน์โหลดเป็นไฟล์ CSV ไฟล์เดียว เราจะแยกสิ่งนี้ออกเป็นชุดฝึก การตรวจสอบ และชุดทดสอบ

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

ต่อไป เราจะห่อ dataframes ด้วย tf.data ซึ่งจะช่วยให้เราใช้คอลัมน์คุณลักษณะเป็นสะพานเชื่อมระหว่างคอลัมน์ในดาต้าเฟรมของ Pandas กับคุณลักษณะที่ใช้ในการฝึกโมเดล หากเราทำงานกับไฟล์ CSV ขนาดใหญ่มาก (ใหญ่จนไม่พอดีกับหน่วยความจำ) เราจะใช้ tf.data เพื่ออ่านจากดิสก์โดยตรง ที่ไม่ครอบคลุมในบทช่วยสอนนี้

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

ทำความเข้าใจกับไปป์ไลน์อินพุต

ตอนนี้เราได้สร้างไพพ์ไลน์อินพุตแล้ว ให้เรียกมันว่าเพื่อดูรูปแบบของข้อมูลที่ส่งคืน เราใช้ขนาดแบทช์ขนาดเล็กเพื่อให้เอาต์พุตสามารถอ่านได้

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([ 6  2 36  2  2], shape=(5,), dtype=int64)
A batch of targets: tf.Tensor([1 1 1 1 1], shape=(5,), dtype=int64)

เราจะเห็นว่าชุดข้อมูลส่งคืนพจนานุกรมของชื่อคอลัมน์ (จาก dataframe) ที่จับคู่กับค่าของคอลัมน์จากแถวใน dataframe

แสดงคอลัมน์คุณลักษณะหลายประเภท

TensorFlow มีคอลัมน์คุณลักษณะหลายประเภท ในส่วนนี้ เราจะสร้างคอลัมน์คุณลักษณะหลายประเภท และสาธิตวิธีการแปลงคอลัมน์จากดาต้าเฟรม

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

คอลัมน์ตัวเลข

เอาต์พุตของคอลัมน์คุณลักษณะจะกลายเป็นอินพุตของโมเดล (โดยใช้ฟังก์ชันสาธิตที่กำหนดไว้ข้างต้น เราจะสามารถเห็นได้อย่างชัดเจนว่าแต่ละคอลัมน์จาก dataframe ถูกแปลงอย่างไร) คอลัมน์ตัวเลขเป็นคอลัมน์ ประเภทที่ง่ายที่สุด มันถูกใช้เพื่อแสดงถึงคุณสมบัติอันทรงคุณค่าที่แท้จริง เมื่อใช้คอลัมน์นี้ โมเดลของคุณจะได้รับค่าคอลัมน์จาก dataframe ไม่เปลี่ยนแปลง

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

ในชุดข้อมูล PetFinder คอลัมน์ส่วนใหญ่จากดาต้าเฟรมจัดเป็นหมวดหมู่

คอลัมน์ที่ฝากข้อมูล

บ่อยครั้ง คุณไม่ต้องการป้อนตัวเลขลงในแบบจำลองโดยตรง แต่ให้แบ่งค่าออกเป็นหมวดหมู่ต่างๆ ตามช่วงตัวเลข พิจารณาข้อมูลดิบที่แสดงถึงอายุของบุคคล แทนที่จะแสดงอายุเป็นคอลัมน์ตัวเลข เราสามารถแบ่งอายุออกเป็นหลายกลุ่มโดยใช้ คอลัมน์ ในที่เก็บข้อมูล สังเกตค่า one-hot ด้านล่างเพื่ออธิบายว่าช่วงอายุใดที่แต่ละแถวตรงกัน

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. 1. 0. 0.]
 [0. 0. 0. 1.]
 [0. 0. 1. 0.]
 [0. 1. 0. 0.]]

คอลัมน์หมวดหมู่

ในชุดข้อมูลนี้ Type จะแสดงเป็นสตริง (เช่น 'Dog' หรือ 'Cat') เราไม่สามารถป้อนสตริงโดยตรงไปยังโมเดล เราต้องแมปพวกมันกับค่าตัวเลขก่อน คอลัมน์คำศัพท์ตามหมวดหมู่เป็นวิธีแสดงสตริงเป็นเวกเตอร์ยอดนิยม (เหมือนกับที่คุณเคยเห็นด้านบนกับกลุ่มอายุ) คำศัพท์สามารถส่งผ่านเป็นรายการได้โดยใช้ categorical_column_with_vocabulary_list หรือโหลดจากไฟล์โดยใช้ categorical_column_with_vocabulary_file

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.]
 [1. 0.]
 [1. 0.]
 [0. 1.]]

การฝังคอลัมน์

สมมติว่าแทนที่จะมีสตริงที่เป็นไปได้เพียงเล็กน้อย เรามีค่าเป็นพันๆ (หรือมากกว่า) ต่อหมวดหมู่ ด้วยเหตุผลหลายประการ เนื่องจากจำนวนหมวดหมู่มีจำนวนมากขึ้น จึงเป็นไปไม่ได้ที่จะฝึกโครงข่ายประสาทเทียมโดยใช้การเข้ารหัสแบบ one-hot เราสามารถใช้คอลัมน์ฝังตัวเพื่อเอาชนะข้อจำกัดนี้ได้ แทนที่จะแสดงข้อมูลเป็นเวกเตอร์ร้อนเดียวในหลายมิติ คอลัมน์ที่ฝังจะ แสดงข้อมูลนั้นเป็นเวกเตอร์ที่มีมิติต่ำกว่าและหนาแน่น ซึ่งแต่ละเซลล์สามารถมีตัวเลขใดๆ ได้ ไม่ใช่แค่ 0 หรือ 1 เท่านั้น ขนาดของการฝัง ( 8 ในตัวอย่างด้านล่าง) เป็นพารามิเตอร์ที่ต้องปรับ

# 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.22380038 -0.09379731  0.21349265  0.33451992 -0.49730566  0.05174963
   0.2668497   0.27391028]
 [-0.5484653  -0.03492585  0.05648395 -0.09792244  0.02530896 -0.15477926
  -0.10695003 -0.45474145]
 [-0.22380038 -0.09379731  0.21349265  0.33451992 -0.49730566  0.05174963
   0.2668497   0.27391028]
 [ 0.10050306  0.43513173  0.375823    0.5652766   0.40925583 -0.03928828
   0.4901914   0.20637617]
 [-0.2319875  -0.21874283  0.12272807  0.33345345 -0.4563055   0.21609035
  -0.2410521   0.4736915 ]]
ตัวยึดตำแหน่ง22

คอลัมน์คุณลักษณะที่แฮช

อีกวิธีในการแสดงคอลัมน์หมวดหมู่ที่มีค่าจำนวนมากคือการใช้ categorical_column_with_hash_bucket คอลัมน์คุณลักษณะนี้จะคำนวณค่าแฮชของอินพุต จากนั้นเลือกที่เก็บข้อมูล hash_bucket_size อันใดอันหนึ่งเพื่อเข้ารหัสสตริง เมื่อใช้คอลัมน์นี้ คุณไม่จำเป็นต้องจัดเตรียมคำศัพท์ และคุณสามารถเลือกที่จะทำให้จำนวน hash_buckets น้อยกว่าจำนวนหมวดหมู่จริงอย่างมากเพื่อประหยัดพื้นที่

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. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]

ข้ามคอลัมน์คุณลักษณะ

การรวมคุณลักษณะต่างๆ ไว้ในคุณลักษณะเดียว ซึ่งรู้จักกันดีในชื่อ feature crosses ทำให้โมเดลสามารถเรียนรู้น้ำหนักที่แยกจากกันสำหรับการผสมผสานของคุณลักษณะแต่ละอย่าง ที่นี่ เราจะสร้างคุณสมบัติใหม่ที่ข้ามระหว่างอายุและประเภท โปรดทราบว่า crossed_column ไม่ได้สร้างตารางแบบเต็มของชุดค่าผสมที่เป็นไปได้ทั้งหมด (ซึ่งอาจมีขนาดใหญ่มาก) แต่ได้รับการสนับสนุนโดย hashed_column ดังนั้นคุณสามารถเลือกขนาดของตารางได้

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. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]

เลือกคอลัมน์ที่จะใช้

เราได้เห็นวิธีการใช้คอลัมน์คุณลักษณะหลายประเภทแล้ว ตอนนี้เราจะใช้มันเพื่อฝึกโมเดล เป้าหมายของบทช่วยสอนนี้คือการแสดงโค้ดที่สมบูรณ์ (เช่น กลไก) ที่จำเป็นสำหรับการทำงานกับคอลัมน์คุณลักษณะ เราได้เลือกคอลัมน์สองสามคอลัมน์เพื่อฝึกโมเดลของเราด้านล่างโดยพลการ

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

สร้างคุณสมบัติเลเยอร์

ตอนนี้เราได้กำหนดคอลัมน์คุณลักษณะแล้ว เราจะใช้เลเยอร์ DenseFeatures เพื่อป้อนข้อมูลลงในโมเดล Keras ของเรา

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

ก่อนหน้านี้ เราใช้แบทช์ขนาดเล็กเพื่อสาธิตวิธีการทำงานของคอลัมน์คุณลักษณะ เราสร้างไปป์ไลน์อินพุตใหม่ด้วยขนาดแบทช์ที่ใหญ่ขึ้น

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)

สร้าง รวบรวม และฝึกโมเดล

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. Received: inputs={'Type': <tf.Tensor 'IteratorGetNext:11' shape=(None,) dtype=string>, 'Age': <tf.Tensor 'IteratorGetNext:0' shape=(None,) dtype=int64>, 'Breed1': <tf.Tensor 'IteratorGetNext:1' shape=(None,) dtype=string>, 'Gender': <tf.Tensor 'IteratorGetNext:6' shape=(None,) dtype=string>, 'Color1': <tf.Tensor 'IteratorGetNext:2' shape=(None,) dtype=string>, 'Color2': <tf.Tensor 'IteratorGetNext:3' shape=(None,) dtype=string>, 'MaturitySize': <tf.Tensor 'IteratorGetNext:8' shape=(None,) dtype=string>, 'FurLength': <tf.Tensor 'IteratorGetNext:5' shape=(None,) dtype=string>, 'Vaccinated': <tf.Tensor 'IteratorGetNext:12' shape=(None,) dtype=string>, 'Sterilized': <tf.Tensor 'IteratorGetNext:10' shape=(None,) dtype=string>, 'Health': <tf.Tensor 'IteratorGetNext:7' shape=(None,) dtype=string>, 'Fee': <tf.Tensor 'IteratorGetNext:4' shape=(None,) dtype=int64>, 'PhotoAmt': <tf.Tensor 'IteratorGetNext:9' shape=(None,) dtype=int64>}. Consider rewriting this model with the Functional API.
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor. Received: inputs={'Type': <tf.Tensor 'IteratorGetNext:11' shape=(None,) dtype=string>, 'Age': <tf.Tensor 'IteratorGetNext:0' shape=(None,) dtype=int64>, 'Breed1': <tf.Tensor 'IteratorGetNext:1' shape=(None,) dtype=string>, 'Gender': <tf.Tensor 'IteratorGetNext:6' shape=(None,) dtype=string>, 'Color1': <tf.Tensor 'IteratorGetNext:2' shape=(None,) dtype=string>, 'Color2': <tf.Tensor 'IteratorGetNext:3' shape=(None,) dtype=string>, 'MaturitySize': <tf.Tensor 'IteratorGetNext:8' shape=(None,) dtype=string>, 'FurLength': <tf.Tensor 'IteratorGetNext:5' shape=(None,) dtype=string>, 'Vaccinated': <tf.Tensor 'IteratorGetNext:12' shape=(None,) dtype=string>, 'Sterilized': <tf.Tensor 'IteratorGetNext:10' shape=(None,) dtype=string>, 'Health': <tf.Tensor 'IteratorGetNext:7' shape=(None,) dtype=string>, 'Fee': <tf.Tensor 'IteratorGetNext:4' shape=(None,) dtype=int64>, 'PhotoAmt': <tf.Tensor 'IteratorGetNext:9' shape=(None,) dtype=int64>}. Consider rewriting this model with the Functional API.
231/231 [==============================] - ETA: 0s - loss: 0.6759 - accuracy: 0.6802WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor. Received: inputs={'Type': <tf.Tensor 'IteratorGetNext:11' shape=(None,) dtype=string>, 'Age': <tf.Tensor 'IteratorGetNext:0' shape=(None,) dtype=int64>, 'Breed1': <tf.Tensor 'IteratorGetNext:1' shape=(None,) dtype=string>, 'Gender': <tf.Tensor 'IteratorGetNext:6' shape=(None,) dtype=string>, 'Color1': <tf.Tensor 'IteratorGetNext:2' shape=(None,) dtype=string>, 'Color2': <tf.Tensor 'IteratorGetNext:3' shape=(None,) dtype=string>, 'MaturitySize': <tf.Tensor 'IteratorGetNext:8' shape=(None,) dtype=string>, 'FurLength': <tf.Tensor 'IteratorGetNext:5' shape=(None,) dtype=string>, 'Vaccinated': <tf.Tensor 'IteratorGetNext:12' shape=(None,) dtype=string>, 'Sterilized': <tf.Tensor 'IteratorGetNext:10' shape=(None,) dtype=string>, 'Health': <tf.Tensor 'IteratorGetNext:7' shape=(None,) dtype=string>, 'Fee': <tf.Tensor 'IteratorGetNext:4' shape=(None,) dtype=int64>, 'PhotoAmt': <tf.Tensor 'IteratorGetNext:9' shape=(None,) dtype=int64>}. Consider rewriting this model with the Functional API.
231/231 [==============================] - 4s 10ms/step - loss: 0.6759 - accuracy: 0.6802 - val_loss: 0.5361 - val_accuracy: 0.7351
Epoch 2/10
231/231 [==============================] - 2s 9ms/step - loss: 0.5742 - accuracy: 0.7054 - val_loss: 0.5178 - val_accuracy: 0.7411
Epoch 3/10
231/231 [==============================] - 2s 9ms/step - loss: 0.5369 - accuracy: 0.7231 - val_loss: 0.5031 - val_accuracy: 0.7438
Epoch 4/10
231/231 [==============================] - 2s 9ms/step - loss: 0.5161 - accuracy: 0.7214 - val_loss: 0.5115 - val_accuracy: 0.7259
Epoch 5/10
231/231 [==============================] - 2s 9ms/step - loss: 0.5034 - accuracy: 0.7296 - val_loss: 0.5173 - val_accuracy: 0.7237
Epoch 6/10
231/231 [==============================] - 2s 8ms/step - loss: 0.4983 - accuracy: 0.7301 - val_loss: 0.5153 - val_accuracy: 0.7254
Epoch 7/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4912 - accuracy: 0.7412 - val_loss: 0.5258 - val_accuracy: 0.7010
Epoch 8/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4890 - accuracy: 0.7360 - val_loss: 0.5066 - val_accuracy: 0.7221
Epoch 9/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4824 - accuracy: 0.7443 - val_loss: 0.5091 - val_accuracy: 0.7481
Epoch 10/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4758 - accuracy: 0.7466 - val_loss: 0.5159 - val_accuracy: 0.7492
<keras.callbacks.History at 0x7f06b52a1810>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
73/73 [==============================] - 0s 6ms/step - loss: 0.4812 - accuracy: 0.7543
Accuracy 0.7543327808380127

ขั้นตอนถัดไป

วิธีที่ดีที่สุดในการเรียนรู้เพิ่มเติมเกี่ยวกับการจัดประเภทข้อมูลที่มีโครงสร้างคือการลองด้วยตัวเอง เราขอแนะนำให้ค้นหาชุดข้อมูลอื่นเพื่อใช้งาน และฝึกโมเดลเพื่อจัดประเภทโดยใช้โค้ดที่คล้ายกับด้านบน เพื่อปรับปรุงความแม่นยำ ให้คิดอย่างรอบคอบว่าคุณลักษณะใดที่จะรวมไว้ในแบบจำลองของคุณ และควรแสดงคุณลักษณะดังกล่าวอย่างไร