Bangun model linier dengan Penaksir

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Ringkasan

Panduan menyeluruh ini melatih model regresi logistik menggunakan tf.estimator API. Model ini sering digunakan sebagai dasar untuk algoritma lain yang lebih kompleks.

Mempersiapkan

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

Muat kumpulan data titanic

Anda akan menggunakan kumpulan data Titanic dengan tujuan (agak tidak wajar) untuk memprediksi kelangsungan hidup penumpang, dengan karakteristik tertentu seperti jenis kelamin, usia, kelas, dll.

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

Jelajahi datanya

Dataset berisi fitur-fitur berikut:

dftrain.head()
dftrain.describe()

Ada 627 dan 264 contoh dalam set pelatihan dan evaluasi, masing-masing.

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

Mayoritas penumpang berusia 20-an dan 30-an.

dftrain.age.hist(bins=20)
<AxesSubplot:>

png

Jumlah penumpang pria kira-kira dua kali lebih banyak daripada penumpang wanita.

dftrain.sex.value_counts().plot(kind='barh')
<AxesSubplot:>

png

Mayoritas penumpang berada di kelas "ketiga".

dftrain['class'].value_counts().plot(kind='barh')
<AxesSubplot:>

png

Wanita memiliki peluang yang jauh lebih tinggi untuk bertahan hidup dibandingkan pria. Ini jelas merupakan fitur prediksi untuk model.

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

png

Rekayasa Fitur untuk Model

Penaksir menggunakan sistem yang disebut kolom fitur untuk menggambarkan bagaimana model harus menginterpretasikan setiap fitur masukan mentah. Penaksir mengharapkan vektor input numerik, dan kolom fitur menjelaskan bagaimana model harus mengonversi setiap fitur.

Memilih dan menyusun kumpulan kolom fitur yang tepat adalah kunci untuk mempelajari model yang efektif. Kolom fitur dapat berupa salah satu input mentah dalam dict fitur asli ( kolom fitur dasar ), atau kolom baru apa pun yang dibuat menggunakan transformasi yang ditentukan pada satu atau beberapa kolom dasar (kolom fitur turunan ).

Penaksir linier menggunakan fitur numerik dan kategoris. Kolom fitur berfungsi dengan semua estimator TensorFlow dan tujuannya adalah untuk menentukan fitur yang digunakan untuk pemodelan. Selain itu, mereka menyediakan beberapa kemampuan rekayasa fitur seperti one-hot-encoding, normalisasi, dan bucketization.

Kolom Fitur Dasar

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 menentukan bagaimana data dikonversi ke tf.data.Dataset yang mengumpankan pipa input secara streaming. tf.data.Dataset dapat mengambil banyak sumber seperti kerangka data, file berformat csv, dan banyak lagi.

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)

Anda dapat memeriksa kumpulan data:

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'Third' b'First' b'Second' b'First'
 b'First' b'Third']

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

Anda juga dapat memeriksa hasil kolom fitur tertentu menggunakan lapisan tf.keras.layers.DenseFeatures :

age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
array([[35.],
       [14.],
       [28.],
       [19.],
       [28.],
       [35.],
       [60.],
       [63.],
       [45.],
       [21.]], dtype=float32)

DenseFeatures hanya menerima tensor padat, untuk memeriksa kolom kategoris, Anda perlu mengubahnya menjadi kolom indikator terlebih dahulu:

gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
array([[1., 0.],
       [0., 1.],
       [0., 1.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.],
       [0., 1.],
       [0., 1.]], dtype=float32)

Setelah menambahkan semua fitur dasar ke model, mari kita latih modelnya. Melatih model hanyalah satu perintah menggunakan 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.7537879, 'accuracy_baseline': 0.625, 'auc': 0.8060607, 'auc_precision_recall': 0.7480768, 'average_loss': 0.5639972, 'label/mean': 0.375, 'loss': 0.5542658, 'precision': 0.7741935, 'prediction/mean': 0.25232768, 'recall': 0.4848485, 'global_step': 200}

Kolom Fitur Turunan

Sekarang Anda mencapai akurasi 75%. Menggunakan setiap kolom fitur dasar secara terpisah mungkin tidak cukup untuk menjelaskan data. Misalnya, korelasi antara usia dan label mungkin berbeda untuk jenis kelamin yang berbeda. Oleh karena itu, jika Anda hanya mempelajari bobot model tunggal untuk gender="Male" dan gender="Female" , Anda tidak akan menangkap setiap kombinasi usia-gender (misalnya membedakan antara gender="Male" AND age="30" DAN gender="Male" DAN age="40" ).

Untuk mempelajari perbedaan antara kombinasi fitur yang berbeda, Anda dapat menambahkan kolom fitur silang ke model (Anda juga dapat mengelompokkan kolom usia sebelum kolom silang):

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

Setelah menambahkan fitur kombinasi ke model, mari kita latih lagi modelnya:

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.7462121, 'accuracy_baseline': 0.625, 'auc': 0.845577, 'auc_precision_recall': 0.7873878, 'average_loss': 0.47313985, 'label/mean': 0.375, 'loss': 0.46722567, 'precision': 0.6509434, 'prediction/mean': 0.41550797, 'recall': 0.6969697, 'global_step': 200}

Sekarang mencapai akurasi 77,6%, yang sedikit lebih baik daripada hanya dilatih dalam fitur dasar. Anda dapat mencoba menggunakan lebih banyak fitur dan transformasi untuk melihat apakah Anda dapat melakukannya dengan lebih baik!

Sekarang Anda dapat menggunakan model kereta api untuk membuat prediksi pada penumpang dari set evaluasi. Model TensorFlow dioptimalkan untuk membuat prediksi pada sekumpulan, atau kumpulan, contoh sekaligus. Sebelumnya, eval_input_fn didefinisikan menggunakan seluruh set evaluasi.

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.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpe5vngw46/model.ckpt-200
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
<AxesSubplot:title={'center':'predicted probabilities'}, ylabel='Frequency'>

png

Akhirnya, lihat karakteristik operasi penerima (ROC) dari hasil, yang akan memberi kita gagasan yang lebih baik tentang tradeoff antara tingkat positif benar dan tingkat positif palsu.

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