Path: blob/master/site/ja/tutorials/load_data/csv.ipynb
25118 views
Copyright 2018 The TensorFlow Authors.
CSV データを読み込む
このチュートリアルでは、TensorFlow で CSV データを使用する方法の例を示します。
これには2つの主要な部分があります。
ディスクからデータを読み込む
トレーニングに適した形式に前処理する
このチュートリアルでは、読み込みに焦点を当て、前処理の簡単な例をいくつか実演します。前処理レイヤーの使用方法の詳細については、前処理レイヤーの使用ガイドと Keras 前処理レイヤーを使用した構造化データの分類チュートリアルを参照してください。
セットアップ
インメモリデータ
小さな CSV データセットの場合、TensorFlow モデルをトレーニングする最も簡単な方法は、pandas データフレームまたは NumPy 配列としてメモリを読み込むことです。
比較的単純な例は、アワビデータセットです。
データセットが小さい。
すべての入力特徴量は、制限された範囲の浮動小数点値です。
データを pandas DataFrame
にダウンロードする方法は次のとおりです。
このデータセットの名目上のタスクは、他の測定値から年齢を予測することなので、トレーニング用に特徴とラベルを分離します。
このデータセットでは、すべての特徴を同じように扱います。特徴を単一の NumPy アレイにパックします。
次に、回帰モデルで年齢を予測します。入力テンソルは 1 つしかないため、ここでは keras.Sequential
モデルで十分です。
モデルをトレーニングするには、特徴とラベルをModel.fit
に渡します。
CSV データを使用してモデルをトレーニングする最も基本的な方法を見てきました。次に、前処理を適用して数値列を正規化する方法を学習します。
基本的な前処理
モデルへの入力を正規化することをお勧めします。Keras 前処理レイヤーは、この正規化をモデルに組み込むための便利な方法を提供します。
tf.keras.layers.Normalization
レイヤーは、各列の平均と分散を事前に計算し、これらを使用してデータを正規化します。
まず、レイヤーを作成します。
次に、Normalization.adapt()
メソッドを使用して、正規化レイヤーをデータに適合させます。
注意: トレーニングデータは、PreprocessingLayer.adapt
メソッドでのみ使用してください。検証データやテストデータは使用しないでください。
次に、モデルで正規化レイヤーを使用します。
混合データ型
「タイタニック」データセットには、タイタニックの乗客に関する情報が含まれています。 このデータセットの名目上のタスクは、誰が生き残ったかを予測することです。
画像出典:Wikimedia
生データは Pandas DataFrame
として簡単に読み込むことができますが、TensorFlow モデルへの入力としてすぐに使用することはできません。
データ型と範囲が異なるため、特徴を NumPy 配列に単純にスタックして、tf.keras.Sequential
モデルに渡すことはできません。各列は個別に処理する必要があります。
1 つのオプションとして、データをオフラインで前処理して(任意のツールを使用して)、カテゴリカル列を数値列に変換してから、処理された出力を TensorFlow モデルに渡すことができます。このアプローチの欠点は、モデルを保存してエクスポートすると、前処理が一緒に保存されないことです。Keras 前処理レイヤーはモデルの一部であるため、この問題を回避できます。
この例では、Keras Functional API を使用して前処理ロジックを実装するモデルを構築します。サブクラス化によって行うこともできます。
Functional API は、「シンボリック」テンソルで動作します。 通常の「eager」テンソルには値があります。 対照的に、これらの「シンボリック」テンソルはそうではありません。代わりに、実行されている演算を追跡し、後で実行できる計算の表現を構築します。 簡単な例を次に示します。
前処理モデルを構築するには、まず、CSV 列の名前とデータ型に一致する一連のシンボリック keras.Input
オブジェクトを構築します。
前処理ロジックの最初のステップは、数値入力を連結して、正規化レイヤーを介して実行することです。
シンボリック前処理の結果をすべて収集して、後で連結します。
文字列入力の場合は、tf.keras.layers.StringLookup
関数を使用して、文字列から語彙の整数インデックスにマップします。次に、tf.keras.layers.CategoryEncoding
を使用して、インデックスをモデルに適した float32
データに変換します。
tf.keras.layers.CategoryEncoding
レイヤーのデフォルト設定は、入力ごとにワンホットベクターを作成します。tf.keras.layers.Embedding
も機能します。 このトピックの詳細については、前処理レイヤーガイドおよび Keras 前処理レイヤーを使用して構造化データを分類するチュートリアルを参照してください。
収集された inputs
と processed_inputs
を使用すると、前処理されたすべての入力を連結して、前処理を処理するモデルを構築できます。
このmodel
には、入力の前処理のみが含まれています。実行して、データに対して何が行われるかを確認できます。 Keras モデルは、Pandas DataFrames
を自動的に変換しません。これは、1 つのテンソルに変換する必要があるのか、テンソルのディクショナリに変換する必要があるのかが明確でないためです。ここでは、テンソルのディクショナリに変換します。
最初のトレーニングサンプルをスライスしてこの前処理モデルに渡すと、数値特徴と文字列のワンホットがすべて連結されていることがわかります。
次に、この上にモデルを構築します。
モデルをトレーニングする際に、特徴のディクショナリをx
、ラベルをy
として渡します。
前処理はモデルの一部であるため、モデルを保存して別の場所で再読み込みしても、同じ結果を得ることができます。
tf.data を使用する
前のセクションでは、モデルのトレーニングの際に、モデルに組み込まれているデータのシャッフルとバッチ処理に依存しました。
入力データパイプラインをさらに制御する必要がある場合、またはメモリに簡単に収まらないデータを使用する必要がある場合は、tf.data
を使用します。
詳細については、tf.data
: TensorFlow 入力パイプラインをビルドするガイドをご覧ください。
インメモリデータ
tf.data
を CSV データに適用する最初の例として、次のコードで前のセクションの特徴のディクショナリを手動でスライスします。各インデックスは、特徴ごとにそのインデックスを取得します。
実行して、最初のサンプルを出力します。
メモリデータローダーの最も基本的なtf.data.Dataset
は、Dataset.from_tensor_slices
コンストラクタです。これにより、TensorFlowで上記のslices
関数の一般化されたバージョンを実装するtf.data.Dataset
が返されます。
他の Python 反復可能と同様に、tf.data.Dataset
を反復できます。
from_tensor_slices
関数は、ネストされたディクショナリーまたはタプルの任意の構造を処理できます。次のコードは、(features_dict, labels)
ペアのデータセットを作成します。
このDataset
を使用してモデルをトレーニングするには、少なくともshuffle
とbatch
のデータが必要です。
features
とlabels
をModel.fit
に渡す代わりに、データセットを渡します。
単一のファイルから
これまでのところ、このチュートリアルはインメモリデータを扱ってきました。tf.data
は、データパイプラインを構築するための非常にスケーラブルなツールキットであり、CSV ファイルの読み込みを処理するためのいくつかの関数を提供します。
次に、ファイルから CSV データを読み取り、tf.data.Dataset
を作成します。
(完全なドキュメントについては、tf.data.experimental.make_csv_dataset
を参照してください。)
この関数には以下のような多くの便利な機能が含まれているため、データを簡単に操作できます。
列ヘッダーをディクショナリキーとして使用する。
それぞれの列の型を自動的に決定する。
注意: tf.data.experimental.make_csv_dataset
で num_epochs
引数を設定してください。
そうしないと、tf.data.Dataset
のデフォルトの動作は無限ループです。
注意: 上記のセルを 2 回実行すると、異なる結果が生成されます。tf.data.experimental.make_csv_dataset
のデフォルト設定には、shuffle_buffer_size=1000
が含まれます。これは、この小さなデータセットには十分ですが、実際のデータセットには適切ではない場合があります。
圧縮ファイルから直接読み取るようにcompression_type
引数を設定します。
注意: tf.data
パイプラインでこれらの日時文字列を解析する必要がある場合は、tfa.text.parse_time
を使用できます。
キャッシング
CSV データの解析にはオーバーヘッドがあります。小さなモデルの場合、これがトレーニングのボトルネックになる可能性があります。
ユースケースによっては、Dataset.cache
または tf.data.Dataset.snapshot
を使用して、CSV データが最初のエポックでのみ解析されるようにすることをお勧めします。
cache
メソッドと snapshot
メソッドの主な違いは、cache
ファイルは、それらを作成した TensorFlow プロセスでのみ使用できることですが、snapshot
ファイルは他のプロセスで読み取ることができます。
たとえば、traffic_volume_csv_gz_ds
を 20 回繰り返すと、キャッシュなしで最大15秒、キャッシュありで最大 2 秒かかります。
注意: Dataset.cache
は、最初のエポックからのデータを保存し、順番に再生します。したがって、cache
を使用すると、パイプラインの早い段階でシャッフルが無効になります。以下では、Dataset.shuffle
は、Dataset.cache
の後に追加されます。
注意: tf.data.Dataset.snapshot
ファイルは、使用中のデータセットの一時ストレージ用です。これは、長期保存用の形式ではありません。このファイル形式は内部の詳細と見なされ、TensorFlow バージョン間で保証されません。
CSV ファイルの読み込みによってデータの読み込みが遅くなり、Dataset.cache
と tf.data.Dataset.snapshot
がユースケースに不十分な場合は、データをより合理化された形式に再度エンコードすることを検討してください。
複数のファイル
このセクションのこれまでのすべての例は、tf.data
なしで簡単に実行できます。 tf.data
が単純化できるのは、ファイルの収集を処理するときだけです。
たとえば、文字フォント画像データセットは、フォントごとに1つずつの CSV ファイルのコレクションとして配布されます。
画像出典:Pixabay、Willi Heidelbach
データセットをダウンロードし、そのファイルを確認します。
多数のファイルを処理する場合、glob スタイルの file_pattern
を tf.data.experimental.make_csv_dataset
関数に渡すことができます。ファイルの順序は、反復ごとにシャッフルされます。
num_parallel_reads
引数を使用して、並列に読み取り、共にインターリーブされるファイルの数を設定します。
これらの CSV ファイルでは、画像が 1 行にフラット化されています。列名の形式は r{row}c{column}
です。以下は最初のバッチです。
オプション:パッキングフィールド
以上のように、各ピクセルを別々の列で操作することは望ましくありません。このデータセットを使用する前に、必ずピクセルをイメージテンソルにパックしてください。
次に、列名を解析して各例の画像を作成するコードを示します。
その関数をデータセット内の各バッチに適用します。
結果の画像をプロットします。
下位レベルの関数
このチュートリアルでは、CSV データを読み取るための最高レベルのユーティリティに焦点を当ててきました。ユースケースが基本的なパターンに適合しない場合に上級ユーザーに役立つ API が他の 2 つあります。
tf.io.decode_csv
: テキストの行を CSV 列テンソルのリストに解析するための関数。tf.data.experimental.CsvDataset
: 下位レベルの CSV データセットコンストラクタ。
このセクションでは、tf.data.experimental.make_csv_dataset
により提供される機能を再作成して、この低レベルの機能をどのように使用できるかを示します。
tf.io.decode_csv
この関数は、文字列または文字列のリストを列のリストにデコードします。
tf.data.experimental.make_csv_dataset
とは異なり、この関数は列のデータ型を推測しようとしません。列ごとの正しい型の値を含む record_defaults
のリストを提供することにより、列の型を指定します。
次のように tf.io.decode_csv
を使用してタイタニックデータを文字列として読み取ります。
それらを実際のタイプで解析するには、対応する型のrecord_defaults
のリストを作成します。
注意: CSV テキストの個々の行を呼び出すよりも、行の大きなバッチで tf.io.decode_csv
を呼び出す方が効率的です。
tf.data.experimental.CsvDataset
tf.data.experimental.CsvDataset
クラスは、tf.data.experimental.make_csv_dataset
関数の便利な機能(列ヘッダーの解析、列の型推論、自動シャッフル、ファイルのインターリーブ)なしで、最小限の CSV Dataset
インターフェースを提供します。
このコンストラクタは、tf.io.decode_csv
と同じ方法で record_defaults
を使用します。
上記のコードは基本的に次と同等です。
複数のファイル
tf.data.experimental.CsvDataset
を使用してフォントデータセットを解析するには、最初に record_defaults
の列の型を決定する必要があります。まず、1 つのファイルの最初の行を調べます。
最初の 2 つのフィールドのみが文字列で、残りは int または float です。コンマを数えることで特徴の総数を取得できます。
tf.data.experimental.CsvDataset
コンストラクタは、入力ファイルのリストを取得できますが、それらを順番に読み取ります。CSV のリストの最初のファイルは AGENCY.csv
です。
したがって、ファイルのリストを CsvDataset
に渡すと、AGENCY.csv
のレコードが最初に読み取られます。
複数のファイルをインターリーブするには、Dataset.interleave
を使用します。
CSV ファイル名を含む初期データセットは次のとおりです。
これにより、各エポックのファイル名がシャッフルされます。
interleave
メソッドは、親Dataset
の各要素に対して子Dataset
を作成するmap_func
を取ります。
ここでは、ファイルのデータセットの各要素から tf.data.experimental.CsvDataset
を作成します。
インターリーブによって返される Dataset
は、子 Dataset
の数を循環することによって要素を返します。以下でデータセットが cycle_length=3
で 3 つのフォントファイルをどのように循環するかに注目してください。
性能
前述のとおり、文字列のバッチで実行する場合、tf.io.decode_csv
の方が効率的です。
大きなバッチサイズを使用する場合は、これを利用して CSV の読み込みパフォーマンスを向上させることができます(ただし、最初に caching を試してください)。
組み込みローダー 20 では、2048 サンプルのバッチは約 17 秒かかります。
テキスト行のバッチをdecode_csv
に渡すと、約 5 秒で高速に実行されます。
大きなバッチを使用して CSV パフォーマンスを向上させる別の例については、過剰適合および過少学習チュートリアルを参照してください。
このようなアプローチは機能する可能性がありますが、Dataset.cache
や tf.data.Dataset.snapshot
などの他のオプションやデータをより合理化された形式に再エンコードすることを検討してください。