Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ja/tutorials/structured_data/feature_columns.ipynb
25118 views
Kernel: Python 3
#@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.

特徴量列を使用して構造化データを分類する

警告: このチュートリアルで説明されている tf.feature_columns モジュールは、新しいコードにはお勧めしません。 Keras 前処理レイヤーがこの機能をカバーしています。移行手順については、特徴量列の移行ガイドをご覧ください。tf.feature_columns モジュールは、TF1 Estimators で使用するために設計されました。互換性保証の対象となりますが、セキュリティの脆弱性以外の修正は行われません。

This tutorial demonstrates how to classify structured data (e.g. tabular data in a CSV). We will use Keras to define the model, and tf.feature_column as a bridge to map from columns in a CSV to features used to train the model. This tutorial contains complete code to:

  • Pandas を使用して CSV ファイルを読み込みます。

  • tf.data を使用して、行をバッチ化してシャッフルする入力パイプラインを構築します。

  • 特徴量の列を使ってモデルをトレーニングするために使用する特徴量に、CSV の列をマッピングします。

  • Kerasを使ったモデルの構築と、訓練及び評価

データセット

下記はこのデータセットの說明です。数値列とカテゴリー列があることに注目してください。

Following is a description of this dataset. Notice there are both numeric and categorical columns. There is a free text column which we will not use in this tutorial.

説明特徴量の型データ型
Type動物の種類(犬、猫)カテゴリカル文字列
Ageペットの年齢数値整数
Breed1ペットの主な品種カテゴリカル文字列
Color1ペットの毛色 1カテゴリカル文字列
Color2ペットの毛色 2カテゴリカル文字列
MaturitySize成獣時のサイズカテゴリカル文字列
FurLength毛の長さカテゴリカル文字列
Vaccinated予防接種済みカテゴリカル文字列
Sterilized不妊手術済みカテゴリカル文字列
Health健康状態カテゴリカル文字列
Fee引き取り料数値整数
Descriptionペットのプロフィールテキスト文字列
PhotoAmtアップロードされたペットの写真数数値整数
AdoptionSpeed引き取りまでの期間分類整数

TensorFlow他ライブラリのインポート

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

Pandasを使ったデータフレーム作成

Pandasは、構造化データの読み込みや操作のための便利なユーティリティを持つPythonのライブラリです。ここでは、Pandasを使ってURLからデータをダウンロードし、データフレームに読み込みます。

import pathlib dataset_url = 'http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip' csv_file = 'datasets/petfinder-mini/petfinder-mini.csv' tf.keras.utils.get_file('petfinder_mini.zip', dataset_url, extract=True, cache_dir='.') dataframe = pd.read_csv(csv_file)
dataframe.head()

ターゲット変数を作成する

元のデータセットでは、ペットが引き取られるまでの期間 (1 週目、1 か月目、3 か月目など) を予測することがタスクとなっていますが、このチュートリアルでは、このタスクを単純化します。ここでは、このタスクを二項分類問題にし、単にペットが引き取られるかどうかのみを予測します。

ラベルの列を変更すると、0 は引き取られなかった、1 は引き取られたことを示すようになります。

# In the original dataset "4" indicates the pet was not adopted. dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1) # Drop un-used columns. dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])

データフレームを、訓練用、検証用、テスト用に分割

ダウンロードしたデータセットは1つの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')

tf.dataを使った入力パイプラインの構築

次に、tf.data を使ってデータフレームをラップします。こうすることで、特徴量の列を Pandas データフレームの列からモデルトレーニング用の特徴量へのマッピングするための橋渡し役として使うことができます。(メモリに収まらないぐらいの) 非常に大きな CSV ファイルを扱う場合には、tf.data を使ってディスクから直接 CSV ファイルを読み込むことになります。この方法は、このチュートリアルでは取り上げません。

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

ご覧のとおり、データセットは、データフレームの行から列の値にマップしている列名の (データフレームの列名) のディクショナリを返しています。

特徴量列の様々な型のデモ

TensorFlow には様々な型の特徴量列があります。このセクションでは、いくつかの型の特徴量列を作り、データフレームの列をどのように変換するかを示します。

# We will use this batch to demonstrate several types of feature columns example_batch = next(iter(train_ds))[0]
# feature columnsを作りデータのバッチを変換する # ユーティリティメソッド def demo(feature_column): feature_layer = layers.DenseFeatures(feature_column) print(feature_layer(example_batch).numpy())

数値コラム

特徴量列の出力はモデルへの入力になります (上記で定義したデモ関数を使うと、データフレームの列がどのように変換されるかを見ることができます)。数値列は、最も単純な型の列です。数値列は実数特徴量を表現するのに使われます。この列を使う場合、モデルにはデータフレームの列の値がそのまま渡されます。

photo_count = feature_column.numeric_column('PhotoAmt') demo(photo_count)

PetFinder データセットでは、データフレームのほとんどの列がカテゴリカル型です。

バケット化コラム

数値をそのままモデルに入力するのではなく、値の範囲に基づいた異なるカテゴリに分割したいことがあります。例えば、人の年齢を表す生データを考えてみましょう。バケット化列を使うと年齢を数値列として表現するのではなく、年齢をいくつかのバケットに分割できます。以下のワンホット値が、各行がどの年齢範囲にあるかを表していることに注目してください。

age = feature_column.numeric_column('Age') age_buckets = feature_column.bucketized_column(age, boundaries=[1, 3, 5]) demo(age_buckets)

カテゴリー型コラム

このデータセットでは、型は (「犬」や「猫」などの) 文字列として表現されています。文字列を直接モデルに入力することはできません。まず、文字列を数値にマッピングする必要があります。カテゴリカル語彙列を使うと、(上記で示した年齢バケットのように) 文字列をワンホットベクトルとして表現することができます。語彙はcategorical_column_with_vocabulary_list を使ってリストで渡すか、categorical_column_with_vocabulary_file を使ってファイルから読み込むことができます。

animal_type = feature_column.categorical_column_with_vocabulary_list( 'Type', ['Cat', 'Dog']) animal_type_one_hot = feature_column.indicator_column(animal_type) demo(animal_type_one_hot)

埋め込み型コラム

数種類の文字列ではなく、カテゴリごとに数千 (あるいはそれ以上) の値があるとしましょう。カテゴリの数が多くなってくると、様々な理由から、ワンホットエンコーディングを使ってニューラルネットワークをトレーニングすることが難しくなります。埋め込み列を使うと、こうした制約を克服することが可能です。埋め込み列は、データを多次元のワンホットベクトルとして表すのではなく、セルの値が 0 か 1 かだけではなく、どんな数値でもとれるような密な低次元ベクトルとして表現します。埋め込みのサイズ (下記の例では 8) は、チューニングが必要なパラメータです。

重要ポイント: カテゴリカル列が多くの選択肢を持つ場合、埋め込み列を使用することが最善の方法です。ここでは例を一つ示しますので、今後様々なデータセットを扱う際には、この例を参考にしてください。

# Notice the input to the embedding column is the categorical column # we previously created breed1 = feature_column.categorical_column_with_vocabulary_list( 'Breed1', dataframe.Breed1.unique()) breed1_embedding = feature_column.embedding_column(breed1, dimension=8) demo(breed1_embedding)

ハッシュ化特徴量列

値の種類が多いカテゴリカル列を表現するもう一つの方法として、categorical_column_with_hash_bucket を使うことができます。この特徴量列は入力のハッシュ値を計算し、文字列をエンコードするために hash_bucket_size バケットの 1 つを選択します。この列を使用する場合には、語彙を用意する必要はありません。また、スペースの節約のために、実際のカテゴリ数に比べて極めて少ない hash_buckets 数を選択することも可能です。

重要ポイント: この手法の重要な欠点の一つは、異なる文字列が同じバケットにマッピングされ、衝突が発生する可能性があるということです。しかしながら、データセットによっては問題が発生しない場合もあります。

breed1_hashed = feature_column.categorical_column_with_hash_bucket( 'Breed1', hash_bucket_size=10) demo(feature_column.indicator_column(breed1_hashed))

フィーチャークロス列

複数の特徴量をまとめて1つの特徴量にする、フィーチャークロスとして知られている手法は、モデルが特徴量の組み合わせの一つ一つに別々の重みを学習することを可能にします。ここでは年齢と型を交差させて新しい特徴量を作ってみます。(crossed_column) は、起こりうるすべての組み合わせ全体の表 (これは非常に大きくなる可能性があります) を作るものではないことに注意してください。フィーチャークロス列は、代わりにバックエンドとして hashed_column を使用しているため、表の大きさを選択することができます。

crossed_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=10) demo(feature_column.indicator_column(crossed_feature))

使用するコラムを選択する

これまで、いくつかの特徴量列の使い方を見てきました。これからモデルのトレーニングにそれらを使用します。このチュートリアルの目的は、特徴量列を使うのに必要な完全なコード (いわば仕組み) を示すことです。以下ではモデルをトレーニングするための列を適当に選びました。

キーポイント:正確なモデルを構築するのが目的である場合には、できるだけ大きなデータセットを使用して、どの特徴量を含めるのがもっとも意味があるのかや、それらをどう表現したらよいかを、慎重に検討してください。

feature_columns = [] # numeric cols for header in ['PhotoAmt', 'Fee', 'Age']: feature_columns.append(feature_column.numeric_column(header))
# bucketized cols age = feature_column.numeric_column('Age') age_buckets = feature_column.bucketized_column(age, boundaries=[1, 2, 3, 4, 5]) feature_columns.append(age_buckets)
# indicator_columns indicator_column_names = ['Type', 'Color1', 'Color2', 'Gender', 'MaturitySize', 'FurLength', 'Vaccinated', 'Sterilized', 'Health'] for col_name in indicator_column_names: categorical_column = feature_column.categorical_column_with_vocabulary_list( col_name, dataframe[col_name].unique()) indicator_column = feature_column.indicator_column(categorical_column) feature_columns.append(indicator_column)
# embedding columns breed1 = feature_column.categorical_column_with_vocabulary_list( 'Breed1', dataframe.Breed1.unique()) breed1_embedding = feature_column.embedding_column(breed1, dimension=8) feature_columns.append(breed1_embedding)
# crossed columns age_type_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=100) feature_columns.append(feature_column.indicator_column(age_type_feature))

特徴量層の構築

特徴量列を定義したので、次に DenseFeatures レイヤーを使って Keras モデルに入力します。

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.Dropout(.1), layers.Dense(1) ]) model.compile(optimizer='adam', loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy']) model.fit(train_ds, validation_data=val_ds, epochs=10)
loss, accuracy = model.evaluate(test_ds) print("Accuracy", accuracy)

重要ポイント: 通常、データベースの規模が大きく複雑であるほど、ディープラーニングの結果がよくなります。このチュートリアルのデータセットのように、小さなデータセットを使用する場合は、決定木またはランダムフォレストを強力なベースラインとして使用することをお勧めします。このチュートリアルでは、構造化データとの連携の仕組みを実演することが目的であり、コードは将来的に独自のデータセットを使用する際の出発点として使用することができます。

次のステップ

構造化データの分類をさらに学習するには、ご自分で別のデータセットを使用し、上記のようなコードを使用し、モデルのトレーニングと分類を試してみてください。正解度を改善するには、モデルに含める特徴量とその表現方法を吟味してください。