うずまき2017 powered by Jun-Systems

耳管開放症, SAS, 統計解析, 人工知能, プログラミングそれに思考

*

TensorFlowについて書くよ pt.2: 重回帰への拡張

   

前回で単回帰の学習モデルについて見てみましたが,今回はアレを適当に拡張して説明変数を複数にした重回帰分析をやってみることとする.

っていうか思ったより簡単だった

触ってないところはそのまま書きます.

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
rng = np.random

learning_rate = 0.01
training_epochs = 2000
display_step = 50

この辺の初期設定はそのままでも別にいいんですけど,あとでEpochごとのパラメータの推移を見てたら収束してなさそうだったのでEpochを倍にしました.それとnumpyをnpで呼べるようにしたくらいですか.

今回は2つぐらいダミー変数でも入れて下のモデルで行きます.
Y = W1*X1 + W2*X2 + W3*X3 + b

とりあえず重回帰の元データ作るのが面倒なので全部乱数で生成させます.

n_samples = 20
train_X1 = rng.binomial(1,0.5,size=n_samples)
train_X2 = rng.binomial(1,0.3,size=n_samples)
train_X3 = rng.normal(1,1,n_samples)
W1_real = rng.normal(10,1)
W2_real = rng.normal(-3,1)
W3_real = rng.normal(10,1)
b_real = rng.normal(10,1)
rand = rng.randn(n_samples)
train_Y = W1_real*train_X1 + W2_real*train_X2 + W3_real*train_X3 + b_real + rand 

オブザベーション数を20とした上で,X1-X3までの説明変数についてはnumpyの確率分布に従った乱数生成の関数を使って二項分布と正規分布で生成しました.次に各ウェイトとバイアスも乱数で適当に作りました.
その上で目的変数Yの真値としてtrain_Yを作るわけですが,そのまま全部を足し上げたものを学習させても仕方ないので,標準正規分布に従った乱数randを20個生成して値を散らしています.

X1 = tf.placeholder("float")
X2 = tf.placeholder("float")
X3 = tf.placeholder("float")
Y = tf.placeholder("float")

W1 = tf.Variable(rng.randn(), name="weight1")
W2 = tf.Variable(rng.randn(), name="weight2")
W3 = tf.Variable(rng.randn(), name="weight3")
b = tf.Variable(rng.randn(), name="bias")

この辺はただ変数に数字付けて増やしただけですね.

sum_list = [tf.mul(X1,W1),tf.mul(X2,W2),tf.mul(X3,W3)]
pred_X = tf.add_n(sum_list)
pred = tf.add(pred_X,b)

モデルの定義です.先述のようにモデルはY = W1*X1 + W2*X2 + W3*X3 + bです.ただ,これまではtf.add(tf.mul(X,W),b)で書いてましたが,tf.addが引数を2つまでしか取れなくて全部書くのがだるいので,sum_listという形で配列にした上で,add_nで配列内の要素を足し上げています.最後にpred_Xとbを足したらモデル完成です.

cost = tf.reduce_sum(tf.pow(pred-Y,2))/(2*n_samples)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

init = tf.initialize_all_variables()
with tf.Session() as session:
    session.run(init)

ここら辺は元と同じです.

for epoch in range(training_epochs):
    for (x1,x2,x3,y) in zip(train_X1,train_X2,train_X3,train_Y):
        session.run(optimizer, feed_dict={X1: x1, X2: x2, X3: x3, Y: y})

    if (epoch+1) % display_step==0:
        c = session.run(cost, feed_dict={X1: train_X1, X2: train_X2, X3: train_X3, Y: train_Y})
        print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \
                   "W1=", session.run(W1), "W2=",session.run(W2), "W3=",session.run(W3), "b=",session.run(b)

この辺はもはや,ただ単に元のコードのXとかWとかtrain_Xとかを増やしてるだけなので,見落としと間違いさえ起きなければ何の面白みもなく終わります.

print "Optimization Finished!"
training_cost = session.run(cost,feed_dict={X1: train_X1, X2: train_X2, X3: train_X3, Y: train_Y})
print "training_cost=",training_cost
print "Results: predicted value (true value)"
print "W1=",session.run(W1),"(",W1_real,")"
print "W2=",session.run(W2),"(",W2_real,")"
print "W3=",session.run(W3),"(",W3_real,")"
print "b=",session.run(b),"(",b_real,")",'\n'

今回はモデルのWeightとBiasを乱数で決定しておりパラメータの真値は結局いくつだったのか,そして推定値はどれぐらいなのかの比較ぐらいはしたいということで,最後で並べて出力させています.

ちなみにぼくが試しに1回走らせた結果は,
training_cost= 0.28
W1 = 9.73 (8.99)
W2 = -2.04 (-1.85)
W3 = 7.99 (8.06)
b = 10.23 (10.31)
んー,まあこんなもんじゃないッスかねー.

書いたプログラムは一応Gistで貼っときます.適当に書いてるので内容の正確さや精度に責任は一切持ちません.


 - TensorFlow , , , , ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事