【Tensorflow4】データセットの前処理を”Tensorflow公式手法”でやってみよう。

【Tensorflow4】データセットの前処理を”Tensorflow公式手法”でやってみよう。

ども、アイーンです。

「うちに来ませんか?」という企業様からのお誘いを頂き

改めて自分のプログラミング技術を見てみると

なんとお粗末。

なんと稚拙。

「能力的に不可能です」

とお断りさせていただきました・・・。

 

だがしかし!!

書籍「独学プログラマー」のお力添えをいただいて

Python能力を底上げして帰ってまいりました!!

 

だれかの助けになればと思い始めたこのブログ

私の能力が絶望的だからこそ

記録を残すことに価値が生まれると信じていきたいと思います。

 

さてさて、今日はデータを学習させるうえで必要な

「型にはめる」ための加工技術

アイリスデータセットの前処理をやっていきましょう。

 

フィーチャとラベルの解析

まずは前回手に入れたアイリスデータセットのCSVファイルを見てみましょう。

解析には、対象を見極める必要があります。

私のPCには

C:\tmp\.keras\datasetsの中に

iris_training.csv

というCSVファイルが作成されています。

中身をメモ帳で開いてみると・・・

こんな情報になっていました。

CSVファイルの特徴は「,(カンマ)で区切られたデータ」なことです。

comma-separated values(カンマ・セパレーテッド・バリュー)

カンマで区切っただけなので、どのシステムからも読み込みしやすい形になっているんですね。

独学プログラマーの学習が生かされてますw

 

CSVはEXCELファイルで開くと改行もされて見やすくなります。

しかし問題がありました。

・・・おれEXCEL持ってない・・・

 

会社で使えればいいじゃ~ん。

自宅で見ることなんてないよ~。

などと供述していた昨日までの自分に

魔貫光殺砲を食らわせて、ラディッツと一緒に閻魔大王のもとへ送りたい気持ちです。

 

そんなときでも大丈夫

ネット界の神龍「Google」に

「CSVファイルをキレイにみせておくれ~!!」

と頼むと

Googleスプレッドシートという便利なものを教えてくれました。

 

Googleスプレッドシートとは?

グーグル先生が提供してくれる

Windowsでいう「officeシリーズ」

WordやExcel等を簡単に使えるWEBサイトです。

 

まずはGoogleスプレッドシートを使うクリックして

この画面にCSVファイルをドラッグ&ドロップします。

すると、改行もされたキレイなファイルが確認できます。

それがコチラ

データをよく見てみましょう。

テキストを分割してみると・・・

120, 4, setosa, versicolor, virginica

120個のデータセット、4つの分類に使われるデータ、3種類のラベル名

が書かれていると理解できます。

 

数字の羅列はデータレコードと呼ばれます。

「6.4」,「2.8」,「5.6」,「2.2」,「2」…

のように

一行に5つのデータがあることが分かります。

どうやら最初の4つが順に

sepal length (cm) がく片の長さ
sepal width (cm) がく片の幅
petal length (cm) 花弁の長さ
petal width (cm) 花弁の幅

を表しているようです。

 

そして最後の行が

0:セトサ

1:ヴァーシカラー

2:ヴァージニカ

ラベル(答え)を表していることが見て取れます。

 

それがわかれば占めたもの。

4つのデータを使って、3つの学習結果を出力すればいい。

入力値が4、出力値が3

というニューラルネットワークを組めばいいんですね。

中間層の量と層数は作成者のセンスに任されているのがディープラーニングのつらいところです。

 

それでは、このCSVファイルからデータを抽出して

Pythonで使用できる形に整えていきましょう。

 

データの前処理をする関数作成

さぁ、楽しい楽しいコーディングのお時間です。

CSVファイルを加工する関数を作りましょう。

 

def parse_csv(line):
example_defaults= [[0.], [0.], [0.], [0.], [0]]

parse(パース)は「解析」という意味です。

 

まずデータ格納用の場所を作ります。

「6.4」,「2.8」,「5.6」,「2.2」のように

浮動小数点で区切られているため

float型で保存するよう[0.]と指定します。

最後のラベルデータ部分は

int型で保存するよう[0]と指定します。

 

parsed_line = tf.decode_csv(line, example_defaults)

tensorflowの組み込み関数である

decode_csv()を使っています。

これでparsed_lineに行ごとにデータをリスト化します。

これで中には

persed_line[0]
120,4,setosa,versicolor,virginica
persed_line[1]
6.4,2.8,5.6,2.2,2
persed_line[2]
5.0,2.3,3.3,1.0,1
persed_line[3]
4.9,2.5,4.5,1.7,2

というリストが作成されました。

 

次にフィーチャとラベルに各行を分割しましょう。

features = tf.reshape(parsed_line[:-1], shape=(4,))

reshape関数で、parsed_lineの0列目から最終列ー1個までを

,カンマの部分で4つに分割し

featuresに入れ

label = tf.reshape(parsed_line[-1], shape=())

最後の列をlabelに入れます。

return features, label

で関数の完成です。

 

TensorFlowのDataset APIを使おう!

TensorFlowのDataset APIとは

データを学習用に構築されたモデル(ニューラルネットワーク)に入れるための便利機能です。

 

ここでは、データを読み込んで学習用の形に変形するために使用します。

train_dataset = tf.data.TextLineDataset(train_dataset_fp)

train_dataset = train_dataset.skip(1)

train_dataset = train_dataset.map(parse_csv)

tf.data.TextLineDatasetを使ってCSVファイルを読み込みます。

 

.skip(1)というのは一行目を取り除く処理です。

一行目のデータが

persed_line[0]
120,4,setosa,versicolor,virginica

のような概要データだからです。

ジャマですので、捨てておきましょう。

 

.map()によりCSVファイルの各行を解析、分割します。

 

train_dataset = train_dataset.shuffle(buffer_size = 1000)

train_dataset = train_dataset.batch(32)

 

.shuffleでデータセットのトレーニングを効果的にするため

データの順番をランダムに変更しています。

ここで記述されているbuffer_size=1000とは

ランダム化するために使うメモリの使用数みたいです。

データセット数の120より多めに指定しているだけで、120より多ければ大丈夫そう。

.batch(32)にて

一度の学習に使うバッチ数を32個に指定し

テストを効率化しています。

 

最後にデータの中身を見てみましょう。

 

前処理した中身の確認

features, label = iter(train_dataset).next()

pythonのiter関数を使用して

train_datasetリストから、.next()でfeaturesとlabelに中身を格納します。

 

分かりやすい参考元:http://uxmilk.jp/39295

 

中身を表示すると

フィーチャサンプル:
{} tf.Tensor(
[[5.9 3.  5.1 1.8]
 [5.7 4.4 1.5 0.4]
 [5.2 2.7 3.9 1.4]
 [5.  3.2 1.2 0.2]
 [6.4 2.8 5.6 2.1]
], shape=(5, 4), dtype=float32)
ラベルサンプル:
 tf.Tensor(
[2 0 1 0 2]
, shape=(5,), dtype=int32)

となりました。

featuresとlabelに学習データとラベルデータを格納することに成功しました。

 

まとめ

・・・まだちゃんと理解できていないところはあります。

ただ公式をなぞっているだけの部分がめっちゃムカつく。

プロ級のプログラマーは、こういった組み込み関数の知識量と理解度が高いんでしょう。

 

いじって初めて理解できることがたくさんありますね~。

これがプログラミングの面白さでもあり泣き所でもあると思いました。

 

これで貴方の肩書は「前処理の知識が1つ増えた人」です。

Chainerの方が分かりやすかったような気がするなぁ。

まだまだこれから。