Xây dựng mô hình tuyến tính với Công cụ ước tính

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Tổng quat

Hướng dẫn end-to-end này đào tạo mô hình hồi quy logistic bằng cách sử dụng API tf.estimator . Mô hình thường được sử dụng làm cơ sở cho các thuật toán khác, phức tạp hơn.

Thành lập

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

Tải tập dữ liệu titanic

Bạn sẽ sử dụng bộ dữ liệu Titanic với mục tiêu (khá bệnh hoạn) là dự đoán khả năng sống sót của hành khách, các đặc điểm cụ thể như giới tính, tuổi, hạng, v.v.

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

Khám phá dữ liệu

Tập dữ liệu chứa các tính năng sau

dftrain.head()
dftrain.describe()

Có 627 và 264 ví dụ trong bộ đào tạo và đánh giá, tương ứng.

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

Phần lớn hành khách ở độ tuổi 20 và 30.

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

png

Có khoảng gấp đôi số hành khách nam so với số hành khách nữ trên tàu.

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

png

Phần lớn hành khách thuộc hạng "thứ ba".

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

png

Con cái có cơ hội sống sót cao hơn nhiều so với con đực. Đây rõ ràng là một tính năng tiên đoán cho mô hình.

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

png

Kỹ thuật tính năng cho mô hình

Công cụ ước tính sử dụng một hệ thống được gọi là các cột tính năng để mô tả cách mô hình diễn giải từng tính năng đầu vào thô. Công cụ ước tính mong đợi một vectơ gồm các đầu vào số và các cột tính năng mô tả cách mô hình sẽ chuyển đổi từng tính năng.

Lựa chọn và tạo tập hợp các cột tính năng phù hợp là chìa khóa để học một mô hình hiệu quả. Cột tính năng có thể là một trong những đầu vào thô trong các tính năng ban đầu dict ( cột tính năng cơ sở ) hoặc bất kỳ cột mới nào được tạo bằng cách sử dụng các phép biến đổi được xác định trên một hoặc nhiều cột cơ sở (cột tính năng dẫn xuất ).

Công cụ ước tính tuyến tính sử dụng cả tính năng số và phân loại. Các cột tính năng hoạt động với tất cả các công cụ ước tính TensorFlow và mục đích của chúng là xác định các tính năng được sử dụng để lập mô hình. Ngoài ra, chúng cung cấp một số khả năng kỹ thuật tính năng như mã hóa một nóng, chuẩn hóa và bucketization.

Các cột tính năng cơ bản

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

Chức năng đầu vào chỉ định cách dữ liệu được chuyển đổi thành input_function tf.data.Dataset cấp đường dẫn đầu vào theo kiểu truyền trực tuyến. tf.data.Dataset có thể lấy nhiều nguồn như khung dữ liệu, tệp định dạng csv, v.v.

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)

Bạn có thể kiểm tra tập dữ liệu:

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]

Bạn cũng có thể kiểm tra kết quả của một cột tính năng cụ thể bằng cách sử dụng lớp 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 chỉ chấp nhận các tensors dày đặc, để kiểm tra một cột phân loại, trước tiên bạn cần chuyển đổi cột đó thành cột chỉ báo:

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)

Sau khi thêm tất cả các tính năng cơ bản vào mô hình, hãy đào tạo mô hình. Đào tạo một mô hình chỉ là một lệnh duy nhất bằng cách sử dụng API tf.estimator :

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}

Các cột tính năng có nguồn gốc

Bây giờ bạn đã đạt đến độ chính xác 75%. Việc sử dụng riêng từng cột tính năng cơ sở có thể không đủ để giải thích dữ liệu. Ví dụ: mối tương quan giữa tuổi và nhãn có thể khác nhau đối với các giới tính khác nhau. Do đó, nếu bạn chỉ tìm hiểu một trọng số mô hình duy nhất cho gender="Male"gender="Female" , bạn sẽ không nắm bắt được mọi kết hợp tuổi-giới tính (ví dụ: phân biệt giữa gender="Male"age="30"gender="Male"age="40" ).

Để tìm hiểu sự khác biệt giữa các kết hợp tính năng khác nhau, bạn có thể thêm các cột tính năng gạch chéo vào mô hình (bạn cũng có thể bán đấu giá cột độ tuổi trước cột chéo):

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

Sau khi thêm tính năng kết hợp vào mô hình, hãy đào tạo lại mô hình:

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}

Nó hiện đạt độ chính xác 77,6%, tốt hơn một chút so với chỉ được đào tạo về các tính năng cơ bản. Bạn có thể thử sử dụng nhiều tính năng và biến đổi hơn để xem liệu bạn có thể làm tốt hơn không!

Giờ đây, bạn có thể sử dụng mô hình tàu để đưa ra dự đoán về một hành khách từ tập hợp đánh giá. Các mô hình TensorFlow được tối ưu hóa để đưa ra dự đoán về một loạt hoặc bộ sưu tập các ví dụ cùng một lúc. Trước đó, eval_input_fn được xác định bằng cách sử dụng toàn bộ tập hợp đánh giá.

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

Cuối cùng, hãy nhìn vào đặc tính hoạt động của máy thu (ROC) của kết quả, điều này sẽ cho chúng ta ý tưởng tốt hơn về sự cân bằng giữa tỷ lệ dương tính thực và tỷ lệ dương tính giả.

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