TensorFlow 2.0 : 上級 Tutorials : 構造化データ :- 特徴カラムで構造化データを分類する (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 11/15/2019
* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Structured data の以下のページを翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
構造化データ :- 特徴カラムで構造化データを分類する
このチュートリアルは構造化データ (e.g. CSV の表形式データ) をどのように分類するかを実演します。モデルを定義するために Keras を、そして CSV のカラムからモデルを訓練するために使用される特徴へマップするためのブリッジとして feature columns を使用します。このチュートリアルは以下を行なうための完全なコードを含みます :
- Pandas を使用して CSV ファイルをロードする。
- tf.data を使用して行をバッチ処理してシャッフルするために入力パイプラインを構築する。
- feature columns を使用して CSV のカラムからモデルを訓練するために使用される特徴にマップする。
- Keras を使用して、モデルを構築、訓練そして評価する。
データセット
Cleveland Clinic Foundation for Heart Disease により提供される小さい データセット を使用します。CSV には数百行あります。各行は患者を表し、各カラム (列) は属性を表します。患者が心臓疾患を持つか否かを予測するためにこの情報を使用します、これはこのデータセットにおける二値分類タスクです。
次はこのデータセットの 記述 です。numeric と categorical カラムの両者があることが分かるでしょう。
カラム | 説明 | 特徴型 | データ型 |
Age | 年齢 | Numerical | integer |
Sex | (1 = male; 0 = female) | Categorical | integer |
CP | 胸の痛みのタイプ (0, 1, 2, 3, 4) | Categorical | integer |
Trestbpd | 安静時血圧 (in mm Hg 入院時) | Numerical | integer |
Chol | 血清コレステロール in mg/dl | Numerical | integer |
FBS | (空腹時血糖値 > 120 mg/dl) (1 = true; 0 = false) | Categorical | integer |
RestECG | 安静時心電図結果 (0, 1, 2) | Categorical | integer |
Thalach | 得られた最大心拍数 | Numerical | integer |
Exang | 労作性狭心症 (1 = yes; 0 = no) | Categorical | integer |
Oldpeak | ST 低下 induced by exercise relative to rest | Numerical | integer |
Slope | The slope of 最大運動時 ST 部分 | Numerical | float |
CA | 透視法により色付けられた主要管の数 (0-3) | Numerical | integer |
Thal | 3 = normal; 6 = fixed defect; 7 = reversible defect | Categorical | string |
Target | 心臓疾患の診断 (1 = true; 0 = false) | Classification | integer |
TensorFlow と他のライブラリをインポートする
!pip install -q sklearn
from __future__ import absolute_import, division, print_function, unicode_literals import numpy as np import pandas as pd import tensorflow as tf from tensorflow import feature_column from tensorflow.keras import layers from sklearn.model_selection import train_test_split
dataframe を作成するために Pandas を使用する
Pandas はロードや構造化データで作業するための多くの役立つユティリティを持つ Python ライブラリです。URL からデータセットをダウンロードしてそれを dataframe にロードするために Pandas を使用します。
URL = 'https://storage.googleapis.com/applied-dl/heart.csv' dataframe = pd.read_csv(URL) dataframe.head()
age | sex | cp | trestbps | chol | fbs | restecg | thalach | exang | oldpeak | slope | ca | thal | target | |
0 | 63 | 1 | 1 | 145 | 233 | 1 | 2 | 150 | 0 | 2.3 | 3 | 0 | fixed | 0 |
1 | 67 | 1 | 4 | 160 | 286 | 0 | 2 | 108 | 1 | 1.5 | 2 | 3 | normal | 1 |
2 | 67 | 1 | 4 | 120 | 229 | 0 | 2 | 129 | 1 | 2.6 | 2 | 2 | reversible | 0 |
3 | 37 | 1 | 3 | 130 | 250 | 0 | 0 | 187 | 0 | 3.5 | 3 | 0 | normal | 0 |
4 | 41 | 0 | 2 | 130 | 204 | 0 | 2 | 172 | 0 | 1.4 | 1 | 0 | normal | 0 |
dataframe を訓練、検証とテストに分割する
ダウンロードしたデータセットは単一の CSV ファイルでした。これを訓練、検証とテストセットに分割します。
train, test = train_test_split(dataframe, test_size=0.2) train, val = train_test_split(train, test_size=0.2) print(len(train), 'train examples') print(len(val), 'validation examples') print(len(test), 'test examples')
193 train examples 49 validation examples 61 test examples
tf.data を使用して入力パイプラインを作成する
次に、tf.data で dataframe をラップします。これは Pandas dataframe のカラムからモデルを訓練するために使用される features へマップするブリッジとして feature columns を使用することを可能にします。 (メモリに収まらないほどに) 非常に巨大な CSV ファイルで作業していたとしても、それをディスクから直接読むために tf.data を使用するでしょう。それはこのチュートリアルではカバーされません。
# A utility method to create a tf.data dataset from a Pandas Dataframe def df_to_dataset(dataframe, shuffle=True, batch_size=32): dataframe = dataframe.copy() labels = dataframe.pop('target') ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels)) if shuffle: ds = ds.shuffle(buffer_size=len(dataframe)) ds = ds.batch(batch_size) return ds
batch_size = 5 # A small batch sized is used for demonstration purposes train_ds = df_to_dataset(train, batch_size=batch_size) val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size) test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
入力パイプラインを理解する
入力パイプラインを作成した今、それが返すデータのフォーマットを見るためにそれを呼び出しましょう。出力を可読に維持するために小さいバッチサイズを使用しました。
for feature_batch, label_batch in train_ds.take(1): print('Every feature:', list(feature_batch.keys())) print('A batch of ages:', feature_batch['age']) print('A batch of targets:', label_batch )
Every feature: ['restecg', 'trestbps', 'exang', 'thalach', 'slope', 'chol', 'oldpeak', 'ca', 'cp', 'sex', 'fbs', 'age', 'thal'] A batch of ages: tf.Tensor([60 53 69 54 54], shape=(5,), dtype=int32) A batch of targets: tf.Tensor([0 0 0 0 1], shape=(5,), dtype=int32)
dataset が (dataframe からの) カラム名の辞書を返すことを見ることができます、それは dataframe の行からカラム値へマップします。
feature column の幾つかのタイプを実演する
TensorFlow は feature columns の多くのタイプを提供します。このセクションでは、feature column の幾つかのタイプを作成して、それらが dataframe からのカラムをどのように変換するかを実演します。
# We will use this batch to demonstrate several types of feature columns example_batch = next(iter(train_ds))[0]
# A utility method to create a feature column # and to transform a batch of data def demo(feature_column): feature_layer = layers.DenseFeatures(feature_column) print(feature_layer(example_batch).numpy())
数値 (= Numeric) カラム
feature column の出力はモデルへの入力になります (上で定義された demo 関数を使用して、dataframe からの各カラムがどのように変換されるかを正確に見ることができます)。数値カラム はカラムの最も単純なタイプです。それは実数値の特徴を表わすために使用されます。このカラムを使用するとき、貴方のモデルは (不変の) dataframe からカラム値を受け取ります。
age = feature_column.numeric_column("age") demo(age)
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 it's 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. [[47.] [56.] [52.] [63.] [57.]]
心臓疾患データセットでは、dataframe からの殆どのカラムは numeric です。
Bucketized カラム
しばしば、数値を直接モデルに供給することを望みません、しかし代わりにその値を数値の範囲に基づく異なるカテゴリーに分割します。人の年齢を表わす生データを考えます。年齢を数値カラムとして表わす代わりに、bucketized カラム を使用して年齢を幾つかのバケツに分割できるでしょう。下の one-hot 値が各行がどの年齢範囲に一致するかを記述していることが分かるでしょう。
age_buckets = feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65]) demo(age_buckets)
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 it's 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. [[0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.] [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
Categorical カラム
このデータセットでは、thal は文字列 (e.g. ‘fixed’, ‘normal’ または ‘reversible’) として表わされます。文字列をモデルに直接には供給できません。代わりに、最初にそれらを数値にマップしなければなりません。categorical 語彙カラムは文字列を one-hot ベクトルとして表わす方法を提供します (上で見た年齢バケツに良く似ています)。語彙は categorical_column_with_vocabulary_list を使用してリストとして渡したり、categorical_column_with_vocabulary_file を使用してファイルからロードすることができます。
thal = feature_column.categorical_column_with_vocabulary_list( 'thal', ['fixed', 'normal', 'reversible']) thal_one_hot = feature_column.indicator_column(thal) demo(thal_one_hot)
WARNING:tensorflow:Layer dense_features_2 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 it's 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. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4276: IndicatorColumn._variable_shape (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version. Instructions for updating: The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4331: VocabularyListCategoricalColumn._num_buckets (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version. Instructions for updating: The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead. [[0. 1. 0.] [0. 1. 0.] [0. 1. 0.] [0. 1. 0.] [0. 0. 1.]]
より複雑なデータセットでは、多くのカラムが categorical (e.g. 文字列) でしょう。Feature columns は categorical データと作業するときにもっとも役立ちます。このデータセットには一つの categorical カラムがあるだけですが、他のデータセットで作業するときに使用できる feature columns の幾つかの重要なタイプを実演するためにそれを使用します。
埋め込みカラム
ごく僅かの可能な文字列を持つ代わりに、カテゴリー毎に数千 (or それ以上) の値を持つことを仮定します。幾つかの理由で、カテゴリー数が巨大になるにつれて、one-hot エンコーディングを使用してニューラルネットワークを訓練することは実行不可能になります。この制限を打開するために埋め込みカラムを使用することができます。データを多くの次元の one-hot ベクトルとして表わす代わりに、埋め込みカラム はそのデータをより低次元な、密ベクトルとして表します、そこでは各セルは (単に 0 か 1 ではなく) 任意の数字を含むことができます。埋め込みのサイズ (下の例では 8) は調整しなければならないパラメータです。
Key point: categorical カラムが多くの可能な値を持つとき埋め込みカラムを使用することが最善です。ここでは実演目的で一つを使用していますので、将来的に異なるデータセットのために変更可能な完全なサンプルを貴方は持つことになります。
# Notice the input to the embedding column is the categorical column # we previously created thal_embedding = feature_column.embedding_column(thal, dimension=8) demo(thal_embedding)
WARNING:tensorflow:Layer dense_features_3 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 it's 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. [[ 0.17819044 0.16483337 0.24669515 0.21694453 0.3330087 0.4549101 0.07683729 -0.04714879] [ 0.17819044 0.16483337 0.24669515 0.21694453 0.3330087 0.4549101 0.07683729 -0.04714879] [ 0.17819044 0.16483337 0.24669515 0.21694453 0.3330087 0.4549101 0.07683729 -0.04714879] [ 0.17819044 0.16483337 0.24669515 0.21694453 0.3330087 0.4549101 0.07683729 -0.04714879] [-0.44885436 0.53802776 -0.10125531 0.2730379 0.3384754 0.6002057 0.11581234 -0.21320769]]
Hashed 特徴カラム
非常に多数の値を持つ categorical column を表わすもう一つの方法は categorical_column_with_hash_bucket を使用することです。この feature column は入力のハッシュ値を計算し、それから文字列をエンコードするために hash_bucket_size バケツの一つを選択します。このカラムを使用するとき、語彙を提供する必要はなく、そして容量をセーブするために実際のカテゴリの数よりも hash_buckets の数をかなり小さくすることを選択できます。
Key point: このテクニックの重要な不都合な点は異なる文字列が同じバケツにマップされる衝突があるかもしれないことです。実際には、これは幾つかのデータセットに対して関係なく上手く動作します。
thal_hashed = feature_column.categorical_column_with_hash_bucket( 'thal', hash_bucket_size=1000) demo(feature_column.indicator_column(thal_hashed))
WARNING:tensorflow:Layer dense_features_4 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 it's 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. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4331: HashedCategoricalColumn._num_buckets (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version. Instructions for updating: The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead. [[0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.]]
Crossed 特徴カラム
特徴交差 (= feature cross) として良く知られる、特徴 (群) を単一の特徴に結合することはモデルに特徴の各組み合わせについて別個の重みを学習することを可能にします。ここで、age と thal の交差である新しい特徴を作成します。crossed_column は総ての可能な組み合わせの完全なテーブルを構築しないことに注意してください (それは非常に巨大でしょう)。代わりに、それは hashed_column により支援されますので、テーブルがどのくらい巨大であるかを選択できます。
crossed_feature = feature_column.crossed_column([age_buckets, thal], hash_bucket_size=1000) demo(feature_column.indicator_column(crossed_feature))
WARNING:tensorflow:Layer dense_features_5 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 it's 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. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:4331: CrossedColumn._num_buckets (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version. Instructions for updating: The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead. [[0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.] [0. 0. 0. ... 0. 0. 0.]]
どのカラムを使用するか選択する
feature columns の幾つかのタイプをどのように使用するか見てきました。今はそれらをモデルを訓練するために使用します。このチュートリアルのゴールは feature column で作業するために必要な完全なコード (e.g. mechanics) を示すことです。下のモデルを訓練するために幾つかのカラムを恣意的に選択しました。
Key point: 貴方の目的が正確なモデルを構築することであれば、貴方自身のより大きなデータセット試してください、そしてどの特徴が含めるために最も意味があるか、そしてそれらがどのように表わされるべきかを注意深く考えてください。
feature_columns = [] # numeric cols for header in ['age', 'trestbps', 'chol', 'thalach', 'oldpeak', 'slope', 'ca']: feature_columns.append(feature_column.numeric_column(header)) # bucketized cols age_buckets = feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65]) feature_columns.append(age_buckets) # indicator cols thal = feature_column.categorical_column_with_vocabulary_list( 'thal', ['fixed', 'normal', 'reversible']) thal_one_hot = feature_column.indicator_column(thal) feature_columns.append(thal_one_hot) # embedding cols thal_embedding = feature_column.embedding_column(thal, dimension=8) feature_columns.append(thal_embedding) # crossed cols crossed_feature = feature_column.crossed_column([age_buckets, thal], hash_bucket_size=1000) crossed_feature = feature_column.indicator_column(crossed_feature) feature_columns.append(crossed_feature)
feature 層を作成する
私達の feature columns を定義した今、それらを Keras モデルへ入力するために DenseFeatures 層を使用します。
feature_layer = tf.keras.layers.DenseFeatures(feature_columns)
先程は、feature columns がどのように動作したかを実演するために小さいバッチサイズを使用しました。より大きなバッチサイズを持つ新しい入力パイプラインを作成します。
batch_size = 32 train_ds = df_to_dataset(train, batch_size=batch_size) val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size) test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
モデルを作成、コンパイルそして訓練する
model = tf.keras.Sequential([ feature_layer, layers.Dense(128, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(1, activation='sigmoid') ]) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(train_ds, validation_data=val_ds, epochs=5)
WARNING:tensorflow:Layer sequential 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 it's 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. Epoch 1/5 7/7 [==============================] - 2s 307ms/step - loss: 3.6217 - accuracy: 0.6062 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00 Epoch 2/5 7/7 [==============================] - 0s 11ms/step - loss: 2.2438 - accuracy: 0.6373 - val_loss: 1.1479 - val_accuracy: 0.2857 Epoch 3/5 7/7 [==============================] - 0s 10ms/step - loss: 1.1346 - accuracy: 0.6166 - val_loss: 0.7250 - val_accuracy: 0.7143 Epoch 4/5 7/7 [==============================] - 0s 10ms/step - loss: 1.0081 - accuracy: 0.4611 - val_loss: 1.2260 - val_accuracy: 0.7143 Epoch 5/5 7/7 [==============================] - 0s 10ms/step - loss: 1.1604 - accuracy: 0.7150 - val_loss: 0.6827 - val_accuracy: 0.7143 <tensorflow.python.keras.callbacks.History at 0x7f39b05c04e0>
loss, accuracy = model.evaluate(test_ds) print("Accuracy", accuracy)
2/2 [==============================] - 0s 5ms/step - loss: 0.4188 - accuracy: 0.7705 Accuracy 0.7704918
Key point: 典型的には遥かに巨大でより複雑なデータセットを伴う深層学習で最善の結果を見るでしょう。この一つのように小さいデータセットで作業するときは、決定木やランダムフォレストを強力なベースラインとして使用することを推奨します。このチュートリアルのゴールは正確なモデルを訓練することではなく、構造化データで作業するメカニクスを実演することで、将来的に貴方自身のデータセットで作業するときの開始点として使用するコードを貴方は持っています。
以上