<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Copyright 2021 The TensorFlow Authors.
Step1:  TFX Estimator コンポーネントのチュートリアル
TensorFlow Extended (TFX) の各コンポーネントの紹介
注：この例は、Jupyter スタイルのノートブックで今すぐ実行できます。セットアップは必要ありません。「Google Colab で実行」をクリックするだけです
<div class="devsite-table-wrapper"><table class="tfo-notebook-buttons" align="left">
<td><a target="_blank" href="https
Step2:  TFX をインストールする
注：Google Colab では、パッケージが更新されるため、このセルを初めて実行するときに、ランタイムを再起動する必要があります（[ランタイム]&gt; [ランタイムの再起動...]）。
Step3:  ランタイムを再起動しましたか？
Google Colab を使用している場合は、上記のセルを初めて実行するときにランタイムを再起動する必要があります（[ランタイム]&gt; [ランタイムの再起動...]）。これは、Colab がパッケージを読み込むために必要です。
パッケージをインポートする
標準の TFX コンポーネント クラスを含む必要なパッケージをインポートします。
Step4:  ライブラリのバージョンを確認します。
Step5:  パイプライン パスを設定
Step6:  サンプルデータのダウンロード
TFX パイプラインで使用するサンプル データセットをダウンロードします。
使用しているデータセットは、シカゴ市がリリースした タクシー乗車データセットです。このデータセットの列は次のとおりです。
<table>
<tr>
<td>pickup_community_area</td>
<td>fare</td>
<td>trip_start_month</td>
</tr>
<tr>
<td>trip_start_hour</td>
<td>trip_start_day</td>
<td>trip_start_timestamp</td>
</tr>
<tr>
<td>pickup_latitude</td>
<td>pickup_longitude</td>
<td>dropoff_latitude</td>
</tr>
<tr>
<td>dropoff_longitude</td>
<td>trip_miles</td>
<td>pickup_census_tract</td>
</tr>
<tr>
<td>dropoff_census_tract</td>
<td>payment_type</td>
<td>company</td>
</tr>
<tr>
<td>trip_seconds</td>
<td>dropoff_community_area</td>
<td>tips</td>
</tr>
</table>
このデータセットを使用して、タクシー乗車のtipsを予測するモデルを構築します。
Step7:  CSV ファイルを見てみましょう。
Step8:  注：この Web サイトは、シカゴ市の公式 Web サイト www.cityofchicago.org で公開されたデータを変更して使用するアプリケーションを提供します。シカゴ市は、この Web サイトで提供されるデータの内容、正確性、適時性、または完全性について一切の表明を行いません。この Web サイトで提供されるデータは、随時変更される可能性があり、提供されるデータはユーザーの自己責任で利用されるものとします。
InteractiveContext を作成する
最後に、このノートブックで TFX コンポーネントをインタラクティブに実行できるようにする InteractiveContext を作成します。
Step9:  TFX コンポーネントをインタラクティブに実行する
次のセルでは、TFX コンポーネントを 1 つずつ作成し、それぞれを実行して、出力アーティファクトを視覚化します。
ExampleGen
ExampleGenコンポーネントは通常、TFX パイプラインの先頭にあり、以下を実行します。
データをトレーニング セットと評価セットに分割します (デフォルトでは、2/3 トレーニング + 1/3 評価)。
データを tf.Example 形式に変換します。 (詳細はこちら)
他のコンポーネントがアクセスできるように、データを _tfx_rootディレクトリにコピーします。
ExampleGenは、データソースへのパスを入力として受け取ります。ここでは、これはダウンロードした CSV を含む_data_rootパスです。
注意
Step10:  ExampleGenの出力アーティファクトを調べてみましょう。このコンポーネントは、トレーニングサンプルと評価サンプルの 2 つのアーティファクトを生成します。
Step11:  また、最初の 3 つのトレーニングサンプルも見てみます。
Step12:  ExampleGenがデータの取り込みを完了したので、次のステップ、データ分析に進みます。
StatisticsGen
StatisticsGenコンポーネントは、データ分析用のデータセットの統計を計算し、ダウンストリームのコンポーネントで使用します。これは、TensorFlow Data Validation ライブラリを使用します。
StatisticsGenコンポーネントは、データ分析用のデータセットの統計を計算し、ダウンストリーム コンポーネントで使用します。
Step13:  StatisticsGenの実行が完了すると、出力された統計を視覚化できます。色々なプロットを試してみてください！
Step14:  SchemaGen
SchemaGenコンポーネントは、データ統計に基づいてスキーマを生成します。（スキーマは、データセット内の特徴の予想される境界、タイプ、プロパティを定義します。）また、TensorFlow データ検証ライブラリも使用します。
SchemaGenは、StatisticsGenで生成した統計を入力として受け取り、デフォルトでトレーニング分割を参照します。
Step15:  SchemaGenの実行が完了すると、生成されたスキーマを表として視覚化できます。
Step16:  データセットのそれぞれの特徴量は、スキーマ表のプロパティの横に行として表示されます。スキーマは、ドメインとして示される、カテゴリカル特徴量が取るすべての値もキャプチャします。
スキーマの詳細については、SchemaGen のドキュメントをご覧ください。
ExampleValidator
ExampleValidatorコンポーネントは、スキーマで定義された期待に基づいて、データの異常を検出します。また、TensorFlow Data Validation ライブラリも使用します。
ExampleValidatorは、StatisticsGenからの統計とSchemaGenからのスキーマを入力として受け取ります。
Step17:  ExampleValidatorの実行が完了すると、異常を表として視覚化できます。
Step18:  異常の表では、異常がないことがわかります。これは、分析した最初のデータセットで、スキーマはこれに合わせて調整されているため、異常がないことが予想されます。このスキーマは確認する必要があります。予期されないものがある場合は、データに異常があることを意味します。確認されたスキーマを使用することにより将来のデータを保護できます。ここで生成された異常は、モデルのパフォーマンスをデバッグし、データが時間の経過とともにどのように変化するかを理解し、データ エラーを特定するために使用できます。
変換
Transformコンポーネントは、トレーニングとサービングの両方で特徴量エンジニアリングを実行します。これは、TensorFlow Transform ライブラリを使用します。
Transformは、ExampleGenからのデータ、SchemaGenからのスキーマ、ユーザー定義の Transform コードを含むモジュールを入力として受け取ります。
以下のユーザー定義の Transform コードの例を見てみましょう（TensorFlow Transform API の概要については、チュートリアルを参照してください）。まず、特徴量エンジニアリングのいくつかの定数を定義します。
注意
Step21:  次に、生データを入力として受け取り、モデルのトレーニングに使用できる変換された特徴量を返すpreprocessing_fnを記述します。
Step22:  次に、この特徴量エンジニアリング コードを Transformコンポーネントに渡し、実行してデータを変換します。
Step23:  Transformの出力アーティファクトを調べてみましょう。このコンポーネントは、2 種類の出力を生成します。
transform_graphは、前処理演算を実行できるグラフです (このグラフは、サービングモデルと評価モデルに含まれます)。
transformed_examplesは前処理されたトレーニングおよび評価データを表します。
Step24:  transform_graphアーティファクトを見てみましょう。これは、3 つのサブディレクトリを含むディレクトリを指しています。
Step25:  transformed_metadataサブディレクトリには、前処理されたデータのスキーマが含まれています。transform_fnサブディレクトリには、実際の前処理グラフが含まれています。metadataサブディレクトリには、元のデータのスキーマが含まれています。
また、最初の 3 つの変換された例も見てみます。
Step31:  Transformコンポーネントがデータを特徴量に変換したら、次にモデルをトレーニングします。
Trainer
Trainerコンポーネントは、TensorFlow で定義したモデルをトレーニングします (Estimator API または Keras API を  model_to_estimator  とともに使用します)。
Trainerは、SchemaGenからのスキーマ、Transformからの変換されたデータとグラフ、トレーニング パラメータ、およびユーザー定義されたモデル コードを含むモジュールを入力として受け取ります。
以下のユーザー定義モデル コードの例を見てみましょう（TensorFlow Estimator API の概要については、チュートリアルを参照してください）。
Step32:  次に、このモデル コードをTrainerコンポーネントに渡し、それを実行してモデルをトレーニングします。
Step33:  TensorBoard でトレーニングを分析する
オプションで、TensorBoard を Trainer に接続して、モデルの学習曲線を分析できます。
Step34:  Evaluator
Evaluatorコンポーネントは、評価セットに対してモデル パフォーマンス指標を計算します。これには、TensorFlow Model Analysis ライブラリが使用されますEvaluatorは、オプションで、新しくトレーニングされたモデルが以前のモデルよりも優れていることを検証できます。これは、モデルを毎日自動的にトレーニングおよび検証する実稼働環境のパイプライン設定で役立ちます。このノートブックでは 1 つのモデルのみをトレーニングするため、Evaluatorはモデルに自動的に「good」というラベルを付けます。
Evaluatorは、ExampleGenからのデータ、Trainerからのトレーニング済みモデル、およびスライス構成を入力として受け取ります。スライス構成により、特徴値に関する指標をスライスすることができます (たとえば、午前 8 時から午後 8 時までのタクシー乗車でモデルがどのように動作するかなど)。この構成の例は、以下を参照してください。
Step35:  次に、この構成をEvaluatorに渡して実行します。
Step36:  Evaluatorの出力アーティファクトを調べてみましょう。
Step37:  evaluation出力を使用すると、評価セット全体のグローバル指標のデフォルトの視覚化を表示できます。
Step38:  スライスされた評価メトリクスの視覚化を表示するには、TensorFlow Model Analysis ライブラリを直接呼び出します。
Step39:  この視覚化は同じ指標を示していますが、評価セット全体ではなく、trip_start_hourのすべての特徴値で計算されています。
TensorFlow モデル分析は、公平性インジケーターやモデル パフォーマンスの時系列のプロットなど、他の多くの視覚化をサポートしています。詳細については、チュートリアルを参照してください。
構成にしきい値を追加したため、検証出力も利用できます。blessingアーティファクトの存在は、モデルが検証に合格したことを示しています。これは実行される最初の検証であるため、候補は自動的に bless されます。
Step40:  検証結果レコードを読み込み、成功を確認することもできます。
Step41:  Pusher
Pusherコンポーネントは通常、TFX パイプラインの最後にあります。このコンポーネントはモデルが検証に合格したかどうかをチェックし、合格した場合はモデルを _serving_model_dirにエクスポートします。
Step42:  次にPusherの出力アーティファクトを調べてみましょう。
Step43:  特に、Pusher はモデルを次のような SavedModel 形式でエクスポートします。
<ASSISTANT_TASK:>
Python Code:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Explanation: Copyright 2021 The TensorFlow Authors.
End of explanation
try:
  import colab
  !pip install --upgrade pip
except:
  pass
Explanation: TFX Estimator コンポーネントのチュートリアル
TensorFlow Extended (TFX) の各コンポーネントの紹介
注：この例は、Jupyter スタイルのノートブックで今すぐ実行できます。セットアップは必要ありません。「Google Colab で実行」をクリックするだけです
<div class="devsite-table-wrapper"><table class="tfo-notebook-buttons" align="left">
<td><a target="_blank" href="https://www.tensorflow.org/tfx/tutorials/tfx/components"> <img src="https://www.tensorflow.org/images/tf_logo_32px.png">TensorFlow.org で表示</a></td>
<td><a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ja/tfx/tutorials/tfx/components.ipynb"> <img src="https://www.tensorflow.org/images/colab_logo_32px.png">Google Colab で実行</a></td>
<td><a target="_blank" href="https://github.com/tensorflow/docs-l10n/blob/master/site/ja/tfx/tutorials/tfx/components.ipynb"> <img width="32px" src="https://www.tensorflow.org/images/GitHub-Mark-32px.png">GitHub でソースを表示</a></td>
<td><a target="_blank" href="https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ja/tfx/tutorials/tfx/components.ipynb"><img width="32px" src="https://www.tensorflow.org/images/download_logo_32px.png">ノートブックをダウンロード</a></td>
</table></div>
警告: 新しいコードには Estimators は推奨されません。Estimators は v1.Session スタイルのコードを実行しますが、これは正しく記述するのはより難しく、特に TF 2 コードと組み合わせると予期しない動作をする可能性があります。Estimators は、互換性保証の対象となりますが、セキュリティの脆弱性以外の修正は行われません。詳細については、移行ガイドを参照してください。
この Colab ベースのチュートリアルでは、TensorFlow Extended (TFX) のそれぞれの組み込みコンポーネントをインタラクティブに説明します。
ここではデータの取り込みからモデルのプッシュ、サービングまで、エンド ツー エンドの機械学習パイプラインのすべてのステップを見ていきます。
完了したら、このノートブックのコンテンツを TFX パイプライン ソース コードとして自動的にエクスポートできます。これは、Apache Airflow および Apache Beam とオーケストレーションできます。
注: このノートブックとそれに関連する API は試験的なものであり、現在開発中です。機能、動作、およびプレゼンテーションの大幅な変更が予想されます。
背景情報
このノートブックでは、Jupyter/Colab 環境で TFX を使用する方法を紹介します。ここでは、インタラクティブなノートブックでシカゴのタクシーの例を見ていきます。
TFX パイプラインの構造に慣れるのには、インタラクティブなノートブックで作業するのが便利です。独自のパイプラインを軽量の開発環境として開発する場合にも役立ちますが、インタラクティブ ノートブックのオーケストレーションとメタデータ アーティファクトへのアクセス方法には違いがあるので注意してください。
オーケストレーション
TFX の実稼働デプロイメントでは、Apache Airflow、Kubeflow Pipelines、Apache Beam などのオーケストレーターを使用して、TFX コンポーネントの事前定義済みパイプライン グラフをオーケストレーションします。インタラクティブなノートブックでは、ノートブック自体がオーケストレーターであり、ノートブック セルを実行するときにそれぞれの TFX コンポーネントを実行します。
メタデータ
TFX の実稼働デプロイメントでは、ML Metadata（MLMD）API を介してメタデータにアクセスします。MLMD は、メタデータ プロパティを MySQL や SQLite などのデータベースに格納し、メタデータ ペイロードをファイル システムなどの永続ストアに保存します。インタラクティブなノートブックでは、プロパティとペイロードの両方が、Jupyter ノートブックまたは Colab サーバーの/tmpディレクトリにあるエフェメラル SQLite データベースに保存されます。
Setup
まず、必要なパッケージをインストールしてインポートし、パスを設定して、データをダウンロードします。
Pip のアップグレード
ローカルで実行する場合にシステム Pip をアップグレードしないようにするには、Colab で実行していることを確認してください。もちろん、ローカルシステムは個別にアップグレードできます。
End of explanation
!pip install -U tfx
Explanation: TFX をインストールする
注：Google Colab では、パッケージが更新されるため、このセルを初めて実行するときに、ランタイムを再起動する必要があります（[ランタイム]&gt; [ランタイムの再起動...]）。
End of explanation
import os
import pprint
import tempfile
import urllib
import absl
import tensorflow as tf
import tensorflow_model_analysis as tfma
tf.get_logger().propagate = False
pp = pprint.PrettyPrinter()
from tfx import v1 as tfx
from tfx.orchestration.experimental.interactive.interactive_context import InteractiveContext
%load_ext tfx.orchestration.experimental.interactive.notebook_extensions.skip
Explanation: ランタイムを再起動しましたか？
Google Colab を使用している場合は、上記のセルを初めて実行するときにランタイムを再起動する必要があります（[ランタイム]&gt; [ランタイムの再起動...]）。これは、Colab がパッケージを読み込むために必要です。
パッケージをインポートする
標準の TFX コンポーネント クラスを含む必要なパッケージをインポートします。
End of explanation
print('TensorFlow version: {}'.format(tf.__version__))
print('TFX version: {}'.format(tfx.__version__))
Explanation: ライブラリのバージョンを確認します。
End of explanation
# This is the root directory for your TFX pip package installation.
_tfx_root = tfx.__path__[0]
# This is the directory containing the TFX Chicago Taxi Pipeline example.
_taxi_root = os.path.join(_tfx_root, 'examples/chicago_taxi_pipeline')
# This is the path where your model will be pushed for serving.
_serving_model_dir = os.path.join(
    tempfile.mkdtemp(), 'serving_model/taxi_simple')
# Set up logging.
absl.logging.set_verbosity(absl.logging.INFO)
Explanation: パイプライン パスを設定
End of explanation
_data_root = tempfile.mkdtemp(prefix='tfx-data')
DATA_PATH = 'https://raw.githubusercontent.com/tensorflow/tfx/master/tfx/examples/chicago_taxi_pipeline/data/simple/data.csv'
_data_filepath = os.path.join(_data_root, "data.csv")
urllib.request.urlretrieve(DATA_PATH, _data_filepath)
Explanation: サンプルデータのダウンロード
TFX パイプラインで使用するサンプル データセットをダウンロードします。
使用しているデータセットは、シカゴ市がリリースした タクシー乗車データセットです。このデータセットの列は次のとおりです。
<table>
<tr>
<td>pickup_community_area</td>
<td>fare</td>
<td>trip_start_month</td>
</tr>
<tr>
<td>trip_start_hour</td>
<td>trip_start_day</td>
<td>trip_start_timestamp</td>
</tr>
<tr>
<td>pickup_latitude</td>
<td>pickup_longitude</td>
<td>dropoff_latitude</td>
</tr>
<tr>
<td>dropoff_longitude</td>
<td>trip_miles</td>
<td>pickup_census_tract</td>
</tr>
<tr>
<td>dropoff_census_tract</td>
<td>payment_type</td>
<td>company</td>
</tr>
<tr>
<td>trip_seconds</td>
<td>dropoff_community_area</td>
<td>tips</td>
</tr>
</table>
このデータセットを使用して、タクシー乗車のtipsを予測するモデルを構築します。
End of explanation
!head {_data_filepath}
Explanation: CSV ファイルを見てみましょう。
End of explanation
# Here, we create an InteractiveContext using default parameters. This will
# use a temporary directory with an ephemeral ML Metadata database instance.
# To use your own pipeline root or database, the optional properties
# `pipeline_root` and `metadata_connection_config` may be passed to
# InteractiveContext. Calls to InteractiveContext are no-ops outside of the
# notebook.
context = InteractiveContext()
Explanation: 注：この Web サイトは、シカゴ市の公式 Web サイト www.cityofchicago.org で公開されたデータを変更して使用するアプリケーションを提供します。シカゴ市は、この Web サイトで提供されるデータの内容、正確性、適時性、または完全性について一切の表明を行いません。この Web サイトで提供されるデータは、随時変更される可能性があり、提供されるデータはユーザーの自己責任で利用されるものとします。
InteractiveContext を作成する
最後に、このノートブックで TFX コンポーネントをインタラクティブに実行できるようにする InteractiveContext を作成します。
End of explanation
example_gen = tfx.components.CsvExampleGen(input_base=_data_root)
context.run(example_gen)
Explanation: TFX コンポーネントをインタラクティブに実行する
次のセルでは、TFX コンポーネントを 1 つずつ作成し、それぞれを実行して、出力アーティファクトを視覚化します。
ExampleGen
ExampleGenコンポーネントは通常、TFX パイプラインの先頭にあり、以下を実行します。
データをトレーニング セットと評価セットに分割します (デフォルトでは、2/3 トレーニング + 1/3 評価)。
データを tf.Example 形式に変換します。 (詳細はこちら)
他のコンポーネントがアクセスできるように、データを _tfx_rootディレクトリにコピーします。
ExampleGenは、データソースへのパスを入力として受け取ります。ここでは、これはダウンロードした CSV を含む_data_rootパスです。
注意: このノートブックでは、コンポーネントを 1 つずつインスタンス化し、InteractiveContext.run()で実行しますが、実稼働環境では、すべてのコンポーネントを事前にPipelineで指定して、オーケストレーターに渡します（TFX パイプライン ガイドの構築を参照してください）。
End of explanation
artifact = example_gen.outputs['examples'].get()[0]
print(artifact.split_names, artifact.uri)
Explanation: ExampleGenの出力アーティファクトを調べてみましょう。このコンポーネントは、トレーニングサンプルと評価サンプルの 2 つのアーティファクトを生成します。
End of explanation
# Get the URI of the output artifact representing the training examples, which is a directory
train_uri = os.path.join(example_gen.outputs['examples'].get()[0].uri, 'Split-train')
# Get the list of files in this directory (all compressed TFRecord files)
tfrecord_filenames = [os.path.join(train_uri, name)
                      for name in os.listdir(train_uri)]
# Create a `TFRecordDataset` to read these files
dataset = tf.data.TFRecordDataset(tfrecord_filenames, compression_type="GZIP")
# Iterate over the first 3 records and decode them.
for tfrecord in dataset.take(3):
  serialized_example = tfrecord.numpy()
  example = tf.train.Example()
  example.ParseFromString(serialized_example)
  pp.pprint(example)
Explanation: また、最初の 3 つのトレーニングサンプルも見てみます。
End of explanation
statistics_gen = tfx.components.StatisticsGen(examples=example_gen.outputs['examples'])
context.run(statistics_gen)
Explanation: ExampleGenがデータの取り込みを完了したので、次のステップ、データ分析に進みます。
StatisticsGen
StatisticsGenコンポーネントは、データ分析用のデータセットの統計を計算し、ダウンストリームのコンポーネントで使用します。これは、TensorFlow Data Validation ライブラリを使用します。
StatisticsGenコンポーネントは、データ分析用のデータセットの統計を計算し、ダウンストリーム コンポーネントで使用します。
End of explanation
context.show(statistics_gen.outputs['statistics'])
Explanation: StatisticsGenの実行が完了すると、出力された統計を視覚化できます。色々なプロットを試してみてください！
End of explanation
schema_gen = tfx.components.SchemaGen(
    statistics=statistics_gen.outputs['statistics'],
    infer_feature_shape=False)
context.run(schema_gen)
Explanation: SchemaGen
SchemaGenコンポーネントは、データ統計に基づいてスキーマを生成します。（スキーマは、データセット内の特徴の予想される境界、タイプ、プロパティを定義します。）また、TensorFlow データ検証ライブラリも使用します。
SchemaGenは、StatisticsGenで生成した統計を入力として受け取り、デフォルトでトレーニング分割を参照します。
End of explanation
context.show(schema_gen.outputs['schema'])
Explanation: SchemaGenの実行が完了すると、生成されたスキーマを表として視覚化できます。
End of explanation
example_validator = tfx.components.ExampleValidator(
    statistics=statistics_gen.outputs['statistics'],
    schema=schema_gen.outputs['schema'])
context.run(example_validator)
Explanation: データセットのそれぞれの特徴量は、スキーマ表のプロパティの横に行として表示されます。スキーマは、ドメインとして示される、カテゴリカル特徴量が取るすべての値もキャプチャします。
スキーマの詳細については、SchemaGen のドキュメントをご覧ください。
ExampleValidator
ExampleValidatorコンポーネントは、スキーマで定義された期待に基づいて、データの異常を検出します。また、TensorFlow Data Validation ライブラリも使用します。
ExampleValidatorは、StatisticsGenからの統計とSchemaGenからのスキーマを入力として受け取ります。
End of explanation
context.show(example_validator.outputs['anomalies'])
Explanation: ExampleValidatorの実行が完了すると、異常を表として視覚化できます。
End of explanation
_taxi_constants_module_file = 'taxi_constants.py'
%%writefile {_taxi_constants_module_file}
# Categorical features are assumed to each have a maximum value in the dataset.
MAX_CATEGORICAL_FEATURE_VALUES = [24, 31, 12]
CATEGORICAL_FEATURE_KEYS = [
    'trip_start_hour', 'trip_start_day', 'trip_start_month',
    'pickup_census_tract', 'dropoff_census_tract', 'pickup_community_area',
    'dropoff_community_area'
]
DENSE_FLOAT_FEATURE_KEYS = ['trip_miles', 'fare', 'trip_seconds']
# Number of buckets used by tf.transform for encoding each feature.
FEATURE_BUCKET_COUNT = 10
BUCKET_FEATURE_KEYS = [
    'pickup_latitude', 'pickup_longitude', 'dropoff_latitude',
    'dropoff_longitude'
]
# Number of vocabulary terms used for encoding VOCAB_FEATURES by tf.transform
VOCAB_SIZE = 1000
# Count of out-of-vocab buckets in which unrecognized VOCAB_FEATURES are hashed.
OOV_SIZE = 10
VOCAB_FEATURE_KEYS = [
    'payment_type',
    'company',
]
# Keys
LABEL_KEY = 'tips'
FARE_KEY = 'fare'
Explanation: 異常の表では、異常がないことがわかります。これは、分析した最初のデータセットで、スキーマはこれに合わせて調整されているため、異常がないことが予想されます。このスキーマは確認する必要があります。予期されないものがある場合は、データに異常があることを意味します。確認されたスキーマを使用することにより将来のデータを保護できます。ここで生成された異常は、モデルのパフォーマンスをデバッグし、データが時間の経過とともにどのように変化するかを理解し、データ エラーを特定するために使用できます。
変換
Transformコンポーネントは、トレーニングとサービングの両方で特徴量エンジニアリングを実行します。これは、TensorFlow Transform ライブラリを使用します。
Transformは、ExampleGenからのデータ、SchemaGenからのスキーマ、ユーザー定義の Transform コードを含むモジュールを入力として受け取ります。
以下のユーザー定義の Transform コードの例を見てみましょう（TensorFlow Transform API の概要については、チュートリアルを参照してください）。まず、特徴量エンジニアリングのいくつかの定数を定義します。
注意: %%writefileセル マジックは、セルの内容をディスク上の.pyファイルとして保存します。これにより、Transformコンポーネントはコードをモジュールとして読み込むことができます。
End of explanation
_taxi_transform_module_file = 'taxi_transform.py'
%%writefile {_taxi_transform_module_file}
import tensorflow as tf
import tensorflow_transform as tft
import taxi_constants
_DENSE_FLOAT_FEATURE_KEYS = taxi_constants.DENSE_FLOAT_FEATURE_KEYS
_VOCAB_FEATURE_KEYS = taxi_constants.VOCAB_FEATURE_KEYS
_VOCAB_SIZE = taxi_constants.VOCAB_SIZE
_OOV_SIZE = taxi_constants.OOV_SIZE
_FEATURE_BUCKET_COUNT = taxi_constants.FEATURE_BUCKET_COUNT
_BUCKET_FEATURE_KEYS = taxi_constants.BUCKET_FEATURE_KEYS
_CATEGORICAL_FEATURE_KEYS = taxi_constants.CATEGORICAL_FEATURE_KEYS
_FARE_KEY = taxi_constants.FARE_KEY
_LABEL_KEY = taxi_constants.LABEL_KEY
def preprocessing_fn(inputs):
  tf.transform's callback function for preprocessing inputs.
  Args:
    inputs: map from feature keys to raw not-yet-transformed features.
  Returns:
    Map from string feature key to transformed feature operations.
  
  outputs = {}
  for key in _DENSE_FLOAT_FEATURE_KEYS:
    # If sparse make it dense, setting nan's to 0 or '', and apply zscore.
    outputs[key] = tft.scale_to_z_score(
        _fill_in_missing(inputs[key]))
  for key in _VOCAB_FEATURE_KEYS:
    # Build a vocabulary for this feature.
    outputs[key] = tft.compute_and_apply_vocabulary(
        _fill_in_missing(inputs[key]),
        top_k=_VOCAB_SIZE,
        num_oov_buckets=_OOV_SIZE)
  for key in _BUCKET_FEATURE_KEYS:
    outputs[key] = tft.bucketize(
        _fill_in_missing(inputs[key]), _FEATURE_BUCKET_COUNT)
  for key in _CATEGORICAL_FEATURE_KEYS:
    outputs[key] = _fill_in_missing(inputs[key])
  # Was this passenger a big tipper?
  taxi_fare = _fill_in_missing(inputs[_FARE_KEY])
  tips = _fill_in_missing(inputs[_LABEL_KEY])
  outputs[_LABEL_KEY] = tf.where(
      tf.math.is_nan(taxi_fare),
      tf.cast(tf.zeros_like(taxi_fare), tf.int64),
      # Test if the tip was > 20% of the fare.
      tf.cast(
          tf.greater(tips, tf.multiply(taxi_fare, tf.constant(0.2))), tf.int64))
  return outputs
def _fill_in_missing(x):
  Replace missing values in a SparseTensor.
  Fills in missing values of `x` with '' or 0, and converts to a dense tensor.
  Args:
    x: A `SparseTensor` of rank 2.  Its dense shape should have size at most 1
      in the second dimension.
  Returns:
    A rank 1 tensor where missing values of `x` have been filled in.
  
  if not isinstance(x, tf.sparse.SparseTensor):
    return x
  default_value = '' if x.dtype == tf.string else 0
  return tf.squeeze(
      tf.sparse.to_dense(
          tf.SparseTensor(x.indices, x.values, [x.dense_shape[0], 1]),
          default_value),
      axis=1)
Explanation: 次に、生データを入力として受け取り、モデルのトレーニングに使用できる変換された特徴量を返すpreprocessing_fnを記述します。
End of explanation
transform = tfx.components.Transform(
    examples=example_gen.outputs['examples'],
    schema=schema_gen.outputs['schema'],
    module_file=os.path.abspath(_taxi_transform_module_file))
context.run(transform)
Explanation: 次に、この特徴量エンジニアリング コードを Transformコンポーネントに渡し、実行してデータを変換します。
End of explanation
transform.outputs
Explanation: Transformの出力アーティファクトを調べてみましょう。このコンポーネントは、2 種類の出力を生成します。
transform_graphは、前処理演算を実行できるグラフです (このグラフは、サービングモデルと評価モデルに含まれます)。
transformed_examplesは前処理されたトレーニングおよび評価データを表します。
End of explanation
train_uri = transform.outputs['transform_graph'].get()[0].uri
os.listdir(train_uri)
Explanation: transform_graphアーティファクトを見てみましょう。これは、3 つのサブディレクトリを含むディレクトリを指しています。
End of explanation
# Get the URI of the output artifact representing the transformed examples, which is a directory
train_uri = os.path.join(transform.outputs['transformed_examples'].get()[0].uri, 'Split-train')
# Get the list of files in this directory (all compressed TFRecord files)
tfrecord_filenames = [os.path.join(train_uri, name)
                      for name in os.listdir(train_uri)]
# Create a `TFRecordDataset` to read these files
dataset = tf.data.TFRecordDataset(tfrecord_filenames, compression_type="GZIP")
# Iterate over the first 3 records and decode them.
for tfrecord in dataset.take(3):
  serialized_example = tfrecord.numpy()
  example = tf.train.Example()
  example.ParseFromString(serialized_example)
  pp.pprint(example)
Explanation: transformed_metadataサブディレクトリには、前処理されたデータのスキーマが含まれています。transform_fnサブディレクトリには、実際の前処理グラフが含まれています。metadataサブディレクトリには、元のデータのスキーマが含まれています。
また、最初の 3 つの変換された例も見てみます。
End of explanation
_taxi_trainer_module_file = 'taxi_trainer.py'
%%writefile {_taxi_trainer_module_file}
import tensorflow as tf
import tensorflow_model_analysis as tfma
import tensorflow_transform as tft
from tensorflow_transform.tf_metadata import schema_utils
from tfx_bsl.tfxio import dataset_options
import taxi_constants
_DENSE_FLOAT_FEATURE_KEYS = taxi_constants.DENSE_FLOAT_FEATURE_KEYS
_VOCAB_FEATURE_KEYS = taxi_constants.VOCAB_FEATURE_KEYS
_VOCAB_SIZE = taxi_constants.VOCAB_SIZE
_OOV_SIZE = taxi_constants.OOV_SIZE
_FEATURE_BUCKET_COUNT = taxi_constants.FEATURE_BUCKET_COUNT
_BUCKET_FEATURE_KEYS = taxi_constants.BUCKET_FEATURE_KEYS
_CATEGORICAL_FEATURE_KEYS = taxi_constants.CATEGORICAL_FEATURE_KEYS
_MAX_CATEGORICAL_FEATURE_VALUES = taxi_constants.MAX_CATEGORICAL_FEATURE_VALUES
_LABEL_KEY = taxi_constants.LABEL_KEY
# Tf.Transform considers these features as "raw"
def _get_raw_feature_spec(schema):
  return schema_utils.schema_as_feature_spec(schema).feature_spec
def _build_estimator(config, hidden_units=None, warm_start_from=None):
  Build an estimator for predicting the tipping behavior of taxi riders.
  Args:
    config: tf.estimator.RunConfig defining the runtime environment for the
      estimator (including model_dir).
    hidden_units: [int], the layer sizes of the DNN (input layer first)
    warm_start_from: Optional directory to warm start from.
  Returns:
    A dict of the following:
      - estimator: The estimator that will be used for training and eval.
      - train_spec: Spec for training.
      - eval_spec: Spec for eval.
      - eval_input_receiver_fn: Input function for eval.
  
  real_valued_columns = [
      tf.feature_column.numeric_column(key, shape=())
      for key in _DENSE_FLOAT_FEATURE_KEYS
  ]
  categorical_columns = [
      tf.feature_column.categorical_column_with_identity(
          key, num_buckets=_VOCAB_SIZE + _OOV_SIZE, default_value=0)
      for key in _VOCAB_FEATURE_KEYS
  ]
  categorical_columns += [
      tf.feature_column.categorical_column_with_identity(
          key, num_buckets=_FEATURE_BUCKET_COUNT, default_value=0)
      for key in _BUCKET_FEATURE_KEYS
  ]
  categorical_columns += [
      tf.feature_column.categorical_column_with_identity(  # pylint: disable=g-complex-comprehension
          key,
          num_buckets=num_buckets,
          default_value=0) for key, num_buckets in zip(
              _CATEGORICAL_FEATURE_KEYS,
              _MAX_CATEGORICAL_FEATURE_VALUES)
  ]
  return tf.estimator.DNNLinearCombinedClassifier(
      config=config,
      linear_feature_columns=categorical_columns,
      dnn_feature_columns=real_valued_columns,
      dnn_hidden_units=hidden_units or [100, 70, 50, 25],
      warm_start_from=warm_start_from)
def _example_serving_receiver_fn(tf_transform_graph, schema):
  Build the serving in inputs.
  Args:
    tf_transform_graph: A TFTransformOutput.
    schema: the schema of the input data.
  Returns:
    Tensorflow graph which parses examples, applying tf-transform to them.
  
  raw_feature_spec = _get_raw_feature_spec(schema)
  raw_feature_spec.pop(_LABEL_KEY)
  raw_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
      raw_feature_spec, default_batch_size=None)
  serving_input_receiver = raw_input_fn()
  transformed_features = tf_transform_graph.transform_raw_features(
      serving_input_receiver.features)
  return tf.estimator.export.ServingInputReceiver(
      transformed_features, serving_input_receiver.receiver_tensors)
def _eval_input_receiver_fn(tf_transform_graph, schema):
  Build everything needed for the tf-model-analysis to run the model.
  Args:
    tf_transform_graph: A TFTransformOutput.
    schema: the schema of the input data.
  Returns:
    EvalInputReceiver function, which contains:
      - Tensorflow graph which parses raw untransformed features, applies the
        tf-transform preprocessing operators.
      - Set of raw, untransformed features.
      - Label against which predictions will be compared.
  
  # Notice that the inputs are raw features, not transformed features here.
  raw_feature_spec = _get_raw_feature_spec(schema)
  serialized_tf_example = tf.compat.v1.placeholder(
      dtype=tf.string, shape=[None], name='input_example_tensor')
  # Add a parse_example operator to the tensorflow graph, which will parse
  # raw, untransformed, tf examples.
  features = tf.io.parse_example(serialized_tf_example, raw_feature_spec)
  # Now that we have our raw examples, process them through the tf-transform
  # function computed during the preprocessing step.
  transformed_features = tf_transform_graph.transform_raw_features(
      features)
  # The key name MUST be 'examples'.
  receiver_tensors = {'examples': serialized_tf_example}
  # NOTE: Model is driven by transformed features (since training works on the
  # materialized output of TFT, but slicing will happen on raw features.
  features.update(transformed_features)
  return tfma.export.EvalInputReceiver(
      features=features,
      receiver_tensors=receiver_tensors,
      labels=transformed_features[_LABEL_KEY])
def _input_fn(file_pattern, data_accessor, tf_transform_output, batch_size=200):
  Generates features and label for tuning/training.
  Args:
    file_pattern: List of paths or patterns of input tfrecord files.
    data_accessor: DataAccessor for converting input to RecordBatch.
    tf_transform_output: A TFTransformOutput.
    batch_size: representing the number of consecutive elements of returned
      dataset to combine in a single batch
  Returns:
    A dataset that contains (features, indices) tuple where features is a
      dictionary of Tensors, and indices is a single Tensor of label indices.
  
  return data_accessor.tf_dataset_factory(
      file_pattern,
      dataset_options.TensorFlowDatasetOptions(
          batch_size=batch_size, label_key=_LABEL_KEY),
      tf_transform_output.transformed_metadata.schema)
# TFX will call this function
def trainer_fn(trainer_fn_args, schema):
  Build the estimator using the high level API.
  Args:
    trainer_fn_args: Holds args used to train the model as name/value pairs.
    schema: Holds the schema of the training examples.
  Returns:
    A dict of the following:
      - estimator: The estimator that will be used for training and eval.
      - train_spec: Spec for training.
      - eval_spec: Spec for eval.
      - eval_input_receiver_fn: Input function for eval.
  
  # Number of nodes in the first layer of the DNN
  first_dnn_layer_size = 100
  num_dnn_layers = 4
  dnn_decay_factor = 0.7
  train_batch_size = 40
  eval_batch_size = 40
  tf_transform_graph = tft.TFTransformOutput(trainer_fn_args.transform_output)
  train_input_fn = lambda: _input_fn(  # pylint: disable=g-long-lambda
      trainer_fn_args.train_files,
      trainer_fn_args.data_accessor,
      tf_transform_graph,
      batch_size=train_batch_size)
  eval_input_fn = lambda: _input_fn(  # pylint: disable=g-long-lambda
      trainer_fn_args.eval_files,
      trainer_fn_args.data_accessor,
      tf_transform_graph,
      batch_size=eval_batch_size)
  train_spec = tf.estimator.TrainSpec(  # pylint: disable=g-long-lambda
      train_input_fn,
      max_steps=trainer_fn_args.train_steps)
  serving_receiver_fn = lambda: _example_serving_receiver_fn(  # pylint: disable=g-long-lambda
      tf_transform_graph, schema)
  exporter = tf.estimator.FinalExporter('chicago-taxi', serving_receiver_fn)
  eval_spec = tf.estimator.EvalSpec(
      eval_input_fn,
      steps=trainer_fn_args.eval_steps,
      exporters=[exporter],
      name='chicago-taxi-eval')
  run_config = tf.estimator.RunConfig(
      save_checkpoints_steps=999, keep_checkpoint_max=1)
  run_config = run_config.replace(model_dir=trainer_fn_args.serving_model_dir)
  estimator = _build_estimator(
      # Construct layers sizes with exponetial decay
      hidden_units=[
          max(2, int(first_dnn_layer_size * dnn_decay_factor**i))
          for i in range(num_dnn_layers)
      ],
      config=run_config,
      warm_start_from=trainer_fn_args.base_model)
  # Create an input receiver for TFMA processing
  receiver_fn = lambda: _eval_input_receiver_fn(  # pylint: disable=g-long-lambda
      tf_transform_graph, schema)
  return {
      'estimator': estimator,
      'train_spec': train_spec,
      'eval_spec': eval_spec,
      'eval_input_receiver_fn': receiver_fn
  }
Explanation: Transformコンポーネントがデータを特徴量に変換したら、次にモデルをトレーニングします。
Trainer
Trainerコンポーネントは、TensorFlow で定義したモデルをトレーニングします (Estimator API または Keras API を  model_to_estimator  とともに使用します)。
Trainerは、SchemaGenからのスキーマ、Transformからの変換されたデータとグラフ、トレーニング パラメータ、およびユーザー定義されたモデル コードを含むモジュールを入力として受け取ります。
以下のユーザー定義モデル コードの例を見てみましょう（TensorFlow Estimator API の概要については、チュートリアルを参照してください）。
End of explanation
from tfx.components.trainer.executor import Executor
from tfx.dsl.components.base import executor_spec
trainer = tfx.components.Trainer(
    module_file=os.path.abspath(_taxi_trainer_module_file),
    custom_executor_spec=executor_spec.ExecutorClassSpec(Executor),
    examples=transform.outputs['transformed_examples'],
    schema=schema_gen.outputs['schema'],
    transform_graph=transform.outputs['transform_graph'],
    train_args=tfx.proto.TrainArgs(num_steps=10000),
    eval_args=tfx.proto.EvalArgs(num_steps=5000))
context.run(trainer)
Explanation: 次に、このモデル コードをTrainerコンポーネントに渡し、それを実行してモデルをトレーニングします。
End of explanation
# Get the URI of the output artifact representing the training logs, which is a directory
model_run_dir = trainer.outputs['model_run'].get()[0].uri
%load_ext tensorboard
%tensorboard --logdir {model_run_dir}
Explanation: TensorBoard でトレーニングを分析する
オプションで、TensorBoard を Trainer に接続して、モデルの学習曲線を分析できます。
End of explanation
eval_config = tfma.EvalConfig(
    model_specs=[
        # Using signature 'eval' implies the use of an EvalSavedModel. To use
        # a serving model remove the signature to defaults to 'serving_default'
        # and add a label_key.
        tfma.ModelSpec(signature_name='eval')
    ],
    metrics_specs=[
        tfma.MetricsSpec(
            # The metrics added here are in addition to those saved with the
            # model (assuming either a keras model or EvalSavedModel is used).
            # Any metrics added into the saved model (for example using
            # model.compile(..., metrics=[...]), etc) will be computed
            # automatically.
            metrics=[
                tfma.MetricConfig(class_name='ExampleCount')
            ],
            # To add validation thresholds for metrics saved with the model,
            # add them keyed by metric name to the thresholds map.
            thresholds = {
                'accuracy': tfma.MetricThreshold(
                    value_threshold=tfma.GenericValueThreshold(
                        lower_bound={'value': 0.5}),
                    # Change threshold will be ignored if there is no
                    # baseline model resolved from MLMD (first run).
                    change_threshold=tfma.GenericChangeThreshold(
                       direction=tfma.MetricDirection.HIGHER_IS_BETTER,
                       absolute={'value': -1e-10}))
            }
        )
    ],
    slicing_specs=[
        # An empty slice spec means the overall slice, i.e. the whole dataset.
        tfma.SlicingSpec(),
        # Data can be sliced along a feature column. In this case, data is
        # sliced along feature column trip_start_hour.
        tfma.SlicingSpec(feature_keys=['trip_start_hour'])
    ])
Explanation: Evaluator
Evaluatorコンポーネントは、評価セットに対してモデル パフォーマンス指標を計算します。これには、TensorFlow Model Analysis ライブラリが使用されますEvaluatorは、オプションで、新しくトレーニングされたモデルが以前のモデルよりも優れていることを検証できます。これは、モデルを毎日自動的にトレーニングおよび検証する実稼働環境のパイプライン設定で役立ちます。このノートブックでは 1 つのモデルのみをトレーニングするため、Evaluatorはモデルに自動的に「good」というラベルを付けます。
Evaluatorは、ExampleGenからのデータ、Trainerからのトレーニング済みモデル、およびスライス構成を入力として受け取ります。スライス構成により、特徴値に関する指標をスライスすることができます (たとえば、午前 8 時から午後 8 時までのタクシー乗車でモデルがどのように動作するかなど)。この構成の例は、以下を参照してください。
End of explanation
# Use TFMA to compute a evaluation statistics over features of a model and
# validate them against a baseline.
# The model resolver is only required if performing model validation in addition
# to evaluation. In this case we validate against the latest blessed model. If
# no model has been blessed before (as in this case) the evaluator will make our
# candidate the first blessed model.
model_resolver = tfx.dsl.Resolver(
      strategy_class=tfx.dsl.experimental.LatestBlessedModelStrategy,
      model=tfx.dsl.Channel(type=tfx.types.standard_artifacts.Model),
      model_blessing=tfx.dsl.Channel(
          type=tfx.types.standard_artifacts.ModelBlessing)).with_id(
              'latest_blessed_model_resolver')
context.run(model_resolver)
evaluator = tfx.components.Evaluator(
    examples=example_gen.outputs['examples'],
    model=trainer.outputs['model'],
    eval_config=eval_config)
context.run(evaluator)
Explanation: 次に、この構成をEvaluatorに渡して実行します。
End of explanation
evaluator.outputs
Explanation: Evaluatorの出力アーティファクトを調べてみましょう。
End of explanation
context.show(evaluator.outputs['evaluation'])
Explanation: evaluation出力を使用すると、評価セット全体のグローバル指標のデフォルトの視覚化を表示できます。
End of explanation
import tensorflow_model_analysis as tfma
# Get the TFMA output result path and load the result.
PATH_TO_RESULT = evaluator.outputs['evaluation'].get()[0].uri
tfma_result = tfma.load_eval_result(PATH_TO_RESULT)
# Show data sliced along feature column trip_start_hour.
tfma.view.render_slicing_metrics(
    tfma_result, slicing_column='trip_start_hour')
Explanation: スライスされた評価メトリクスの視覚化を表示するには、TensorFlow Model Analysis ライブラリを直接呼び出します。
End of explanation
blessing_uri = evaluator.outputs['blessing'].get()[0].uri
!ls -l {blessing_uri}
Explanation: この視覚化は同じ指標を示していますが、評価セット全体ではなく、trip_start_hourのすべての特徴値で計算されています。
TensorFlow モデル分析は、公平性インジケーターやモデル パフォーマンスの時系列のプロットなど、他の多くの視覚化をサポートしています。詳細については、チュートリアルを参照してください。
構成にしきい値を追加したため、検証出力も利用できます。blessingアーティファクトの存在は、モデルが検証に合格したことを示しています。これは実行される最初の検証であるため、候補は自動的に bless されます。
End of explanation
PATH_TO_RESULT = evaluator.outputs['evaluation'].get()[0].uri
print(tfma.load_validation_result(PATH_TO_RESULT))
Explanation: 検証結果レコードを読み込み、成功を確認することもできます。
End of explanation
pusher = tfx.components.Pusher(
    model=trainer.outputs['model'],
    model_blessing=evaluator.outputs['blessing'],
    push_destination=tfx.proto.PushDestination(
        filesystem=tfx.proto.PushDestination.Filesystem(
            base_directory=_serving_model_dir)))
context.run(pusher)
Explanation: Pusher
Pusherコンポーネントは通常、TFX パイプラインの最後にあります。このコンポーネントはモデルが検証に合格したかどうかをチェックし、合格した場合はモデルを _serving_model_dirにエクスポートします。
End of explanation
pusher.outputs
Explanation: 次にPusherの出力アーティファクトを調べてみましょう。
End of explanation
push_uri = pusher.outputs['pushed_model'].get()[0].uri
model = tf.saved_model.load(push_uri)
for item in model.signatures.items():
  pp.pprint(item)
Explanation: 特に、Pusher はモデルを次のような SavedModel 形式でエクスポートします。
End of explanation
<END_TASK>