Tensorflow 身長・体重・BMIの学習(ソシム本、218ページ)
# 2017-5-21 ソシム スクレイピング本 # 218ページ〜 BMI計算、CSVファイル # 予め用意したCSVファイルを使って、BMI分類を学習 # 交差エントロピ、ソフトマックス、勾配法 import pandas as pd import numpy as np import tensorflow as tf # 身長,体重,ラベルのCSVデータを読み出す # pandas でCSVファイル読み出し csv = pd.read_csv("bmi.csv") # データを正規化 、0〜1に csv["height"] = csv["height"] / 200 csv["weight"] = csv["weight"] / 100 # ラベルを三次元のクラスで表す --- (※3) # 痩せ、普通、肥満を3つの三次元クラスデータで表す # thin=(1,0,0) / normal=(0,1,0) / fat=(0,0,1) bclass = {"thin": [1,0,0], "normal": [0,1,0], "fat": [0,0,1]} csv["label_pat"] = csv["label"].apply(lambda x : np.array(bclass[x])) # 正解率を求めるためにテストデータを準備 # 2万件のうち末尾5000件をテストデータにする test_csv = csv[15000:20000] test_pat = test_csv[["weight","height"]] test_ans = list(test_csv["label_pat"]) # データフローグラフを構築する # データを入れるプレースホルダを宣言 x = tf.placeholder(tf.float32, [None, 2]) # 身長,体重のデータを入れる y_ = tf.placeholder(tf.float32, [None, 3]) # 答えのラベルを入れる # 変数を宣言 --- (※6) W = tf.Variable(tf.zeros([2, 3])); # 重み b = tf.Variable(tf.zeros([3])); # バイアス # ソフトマックス回帰を定義 # y=softmax(Wb+b) y = tf.nn.softmax(tf.matmul(x, W) + b) # モデルを訓練する cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) # 降下法でWやbを学習する、tfに用意されているもの optimizer = tf.train.GradientDescentOptimizer(0.01) train = optimizer.minimize(cross_entropy) # 正解率を求める # 誤差関数:交差エントロピー # SummaryWriter predict = tf.equal(tf.argmax(y, 1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(predict, tf.float32)) # セッションを開始 sess = tf.Session() sess.run(tf.global_variables_initializer()) #変数を初期化 # テストデータを用いて学習させる、100件ずつ3500回学習 # 最初30%くらいの正解率が、95%くらいまで向上 print("- トレーニング中 -") for step in range(3500): i = (step * 100) % 14000 rows = csv[1 + i : 1 + i + 100] x_pat = rows[["weight","height"]] y_ans = list(rows["label_pat"]) fd = {x: x_pat, y_: y_ans} sess.run(train, feed_dict=fd) if step % 500 == 0: cre = sess.run(cross_entropy, feed_dict=fd) acc = sess.run(accuracy, feed_dict={x: test_pat, y_: test_ans}) print("step=", step, "cre=", cre, "acc=", acc) # => - トレーニング中 - step= 0 cre= 109.101 acc= 0.3084 step= 500 cre= 52.4673 acc= 0.8688 step= 1000 cre= 46.4283 acc= 0.9226 step= 1500 cre= 38.8364 acc= 0.9472 step= 2000 cre= 35.4385 acc= 0.9588 step= 2500 cre= 31.0386 acc= 0.9494 step= 3000 cre= 31.2941 acc= 0.9532 # 最終的な正解率を求める acc = sess.run(accuracy, feed_dict={x: test_pat, y_: test_ans}) print("正解率=", acc) # => 正解率= 0.966