หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

สร้างแบบจำลองเชิงเส้นด้วยเครื่องมือประมาณการ

ดูใน TensorFlow.org เรียกใช้ใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดสมุดบันทึก

ภาพรวม

คำแนะนำแบบ end-to-end นี้ฝึกโมเดลการถดถอยโลจิสติกโดยใช้ tf.estimator API แบบจำลองนี้มักใช้เป็นพื้นฐานสำหรับอัลกอริทึมอื่น ๆ ที่ซับซ้อนกว่า

ติดตั้ง

pip install -q sklearn
import os
import sys

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import clear_output
from six.moves import urllib

โหลดชุดข้อมูลไททานิก

คุณจะใช้ชุดข้อมูลไททานิกโดยมีเป้าหมาย (ค่อนข้างเป็นโรค) ในการทำนายการอยู่รอดของผู้โดยสารลักษณะที่กำหนดเช่นเพศอายุชั้นเรียน ฯลฯ

import tensorflow.compat.v2.feature_column as fc

import tensorflow as tf
# Load dataset.
dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv')
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv')
y_train = dftrain.pop('survived')
y_eval = dfeval.pop('survived')

สำรวจข้อมูล

ชุดข้อมูลประกอบด้วยคุณสมบัติดังต่อไปนี้

dftrain.head()
dftrain.describe()

มีตัวอย่าง 627 และ 264 ตัวอย่างในชุดการฝึกอบรมและการประเมินผลตามลำดับ

dftrain.shape[0], dfeval.shape[0]
(627, 264)

ผู้โดยสารส่วนใหญ่อยู่ในวัย 20 และ 30

dftrain.age.hist(bins=20)
<matplotlib.axes._subplots.AxesSubplot at 0x7f8e946914a8>

png

มีผู้โดยสารชายมากกว่าผู้โดยสารหญิงบนเรือประมาณสองเท่า

dftrain.sex.value_counts().plot(kind='barh')
<matplotlib.axes._subplots.AxesSubplot at 0x7f8e925da208>

png

ผู้โดยสารส่วนใหญ่อยู่ในชั้น "สาม"

dftrain['class'].value_counts().plot(kind='barh')
<matplotlib.axes._subplots.AxesSubplot at 0x7f8e920e0588>

png

เพศหญิงมีโอกาสรอดชีวิตสูงกว่าเพศชายมาก นี่เป็นคุณลักษณะที่คาดเดาได้อย่างชัดเจนสำหรับแบบจำลอง

pd.concat([dftrain, y_train], axis=1).groupby('sex').survived.mean().plot(kind='barh').set_xlabel('% survive')
Text(0.5, 0, '% survive')

png

วิศวกรรมคุณลักษณะสำหรับรุ่น

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

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

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

คอลัมน์คุณลักษณะพื้นฐาน

CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
                       'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']

feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
  vocabulary = dftrain[feature_name].unique()
  feature_columns.append(tf.feature_column.categorical_column_with_vocabulary_list(feature_name, vocabulary))

for feature_name in NUMERIC_COLUMNS:
  feature_columns.append(tf.feature_column.numeric_column(feature_name, dtype=tf.float32))

input_function ระบุวิธีการแปลงข้อมูลเป็นtf.data.Dataset ที่ฟีดไปป์ไลน์อินพุตในรูปแบบการสตรีมtf.data.Dataset สามารถรับได้ในหลายแหล่งเช่น dataframe ไฟล์รูปแบบ csv และอื่น ๆ

def make_input_fn(data_df, label_df, num_epochs=10, shuffle=True, batch_size=32):
  def input_function():
    ds = tf.data.Dataset.from_tensor_slices((dict(data_df), label_df))
    if shuffle:
      ds = ds.shuffle(1000)
    ds = ds.batch(batch_size).repeat(num_epochs)
    return ds
  return input_function

train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, num_epochs=1, shuffle=False)

คุณสามารถตรวจสอบชุดข้อมูล:

ds = make_input_fn(dftrain, y_train, batch_size=10)()
for feature_batch, label_batch in ds.take(1):
  print('Some feature keys:', list(feature_batch.keys()))
  print()
  print('A batch of class:', feature_batch['class'].numpy())
  print()
  print('A batch of Labels:', label_batch.numpy())
Some feature keys: ['sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']

A batch of class: [b'Third' b'Third' b'Third' b'Third' b'First' b'Third' b'Third' b'First'
 b'Third' b'Third']

A batch of Labels: [1 0 0 0 1 0 0 0 0 0]

คุณยังสามารถตรวจสอบผลลัพธ์ของคอลัมน์คุณลักษณะเฉพาะโดยใช้เลเยอร์ tf.keras.layers.DenseFeatures :

age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
WARNING:tensorflow:Layer dense_features is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.


array([[27.],
       [28.],
       [30.],
       [18.],
       [32.],
       [26.],
       [61.],
       [37.],
       [28.],
       [40.]], dtype=float32)

DenseFeatures ยอมรับเฉพาะเทนเซอร์ที่หนาแน่นเพื่อตรวจสอบคอลัมน์ที่เป็นหมวดหมู่คุณต้องแปลงเป็นคอลัมน์ตัวบ่งชี้ก่อน:

gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
WARNING:tensorflow:Layer dense_features_1 is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.


array([[1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.]], dtype=float32)

หลังจากเพิ่มคุณสมบัติพื้นฐานทั้งหมดลงในโมเดลแล้วเรามาฝึกโมเดลกัน การฝึกโมเดลเป็นเพียงคำสั่งเดียวโดยใช้ tf.estimator API:

linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)

clear_output()
print(result)
{'accuracy': 0.7613636, 'accuracy_baseline': 0.625, 'auc': 0.809244, 'auc_precision_recall': 0.75609726, 'average_loss': 0.5452906, 'label/mean': 0.375, 'loss': 0.5347039, 'precision': 0.75, 'prediction/mean': 0.27201703, 'recall': 0.54545456, 'global_step': 200}

คอลัมน์คุณลักษณะที่ได้รับ

ตอนนี้คุณมีความแม่นยำถึง 75% แล้ว การใช้คอลัมน์คุณลักษณะพื้นฐานแต่ละคอลัมน์แยกกันอาจไม่เพียงพอที่จะอธิบายข้อมูล ตัวอย่างเช่นความสัมพันธ์ระหว่างเพศและป้ายกำกับอาจแตกต่างกันสำหรับเพศที่แตกต่างกัน ดังนั้นหากคุณเรียนรู้น้ำหนักโมเดลเดียวสำหรับ gender="Male" และ gender="Female" คุณจะไม่จับชุดค่าผสมอายุ - เพศทั้งหมด (เช่นการแยกแยะระหว่าง gender="Male" และ age="30" และ gender="Male" และ age="40" )

หากต้องการเรียนรู้ความแตกต่างระหว่างชุดคุณลักษณะต่างๆคุณสามารถเพิ่ม คอลัมน์คุณลักษณะแบบไขว้ ลงในโมเดลได้ (คุณสามารถจัดคอลัมน์อายุไว้ก่อนคอลัมน์ไขว้):

age_x_gender = tf.feature_column.crossed_column(['age', 'sex'], hash_bucket_size=100)

หลังจากเพิ่มคุณสมบัติการรวมเข้ากับโมเดลแล้วให้ฝึกโมเดลอีกครั้ง:

derived_feature_columns = [age_x_gender]
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns+derived_feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)

clear_output()
print(result)
{'accuracy': 0.7613636, 'accuracy_baseline': 0.625, 'auc': 0.84352624, 'auc_precision_recall': 0.78346276, 'average_loss': 0.48114488, 'label/mean': 0.375, 'loss': 0.4756022, 'precision': 0.65789473, 'prediction/mean': 0.4285249, 'recall': 0.75757575, 'global_step': 200}

ตอนนี้มีความแม่นยำ 77.6% ซึ่งดีกว่าการฝึกฝนในคุณสมบัติพื้นฐานเล็กน้อย คุณสามารถลองใช้คุณสมบัติและการเปลี่ยนแปลงเพิ่มเติมเพื่อดูว่าคุณทำได้ดีขึ้นหรือไม่!

ตอนนี้คุณสามารถใช้โมเดลรถไฟเพื่อคาดการณ์ผู้โดยสารจากชุดการประเมินได้ แบบจำลอง TensorFlow ได้รับการปรับให้เหมาะสมเพื่อทำการคาดคะเนในชุดงานหรือชุดตัวอย่างพร้อมกัน ก่อนหน้านี้ eval_input_fn ถูกกำหนดโดยใช้ชุดการประเมินทั้งหมด

pred_dicts = list(linear_est.predict(eval_input_fn))
probs = pd.Series([pred['probabilities'][1] for pred in pred_dicts])

probs.plot(kind='hist', bins=20, title='predicted probabilities')
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Layer linear/linear_model is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpg17o3o7e/model.ckpt-200
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.

<matplotlib.axes._subplots.AxesSubplot at 0x7f8e2c1dd358>

png

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

from sklearn.metrics import roc_curve
from matplotlib import pyplot as plt

fpr, tpr, _ = roc_curve(y_eval, probs)
plt.plot(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.xlim(0,)
plt.ylim(0,)
(0.0, 1.05)

png