とりあえずTensorFlowでIrisを分類してみた1

skflowというscikit-learnのようにTensorFlowが使えるライブラリを使えばたった数行でIrisの分類ができるみたいだが、今回はTensorFlowの勉強のためにskflowは使わずに書いてみた。
[MNIST For ML Beginners](https://www.tensorflow.org/tutorials/mnist/beginners/)を参考にしました。

```python3:環境
python==3.5.2
tensorflow==0.12.0
```

# データを準備する
まずは必要なモジュールをインポート

```python3
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split
```


データセットを読み込む

```
iris = datasets.load_iris()
```

訓練用とテスト用にデータを分ける

```
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)
```

MNISTのようにミニバッチ学習をするために、とりあえずデータを３つのセットに分けてみた。

```
k = [0, 38, 76, 112]
train_xs=train_ys=[]
for i in range(1, 4):
    tmp_x=tmp_y=[]
    for j in range(k[i-1], k[i]):
        tmp_x, tmp_y = tmp_x + [X_train[j]], tmp_y + [y_train[j]]
    train_xs, train_ys = train_xs + [tmp_x], train_ys + [tmp_y]
```

MNISTのように教師ラベルをone-hotベクトルに変換する。

```
train_labels = tf.placeholder(tf.int64, [None])
test_labels = tf.placeholder(tf.int64, [None])
train_ = tf.one_hot(train_labels, depth=3, dtype=tf.float32)
test_ = tf.one_hot(test_labels, depth=3, dtype=tf.float32)
```

# モデル作成
Irisのデータは入力が４次元、出力が３次元になるので以下のようなモデルになった。

```
x = tf.placeholder(tf.float32, [None, 4])
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]))

y = tf.nn.softmax(tf.matmul(x, W) + b)
```

# モデル訓練
ミニバッチ学習でモデルの訓練をする。

```
with tf.Session() as sess:
    sess.run(init)

    ytest.append(sess.run(test_, feed_dict={test_labels: y_test}))
    xtest = [sess.run(train_, feed_dict={train_labels: train_ys[i]}) for i in range(3)]

    for i in range(300):
        for j in range(3):
            sess.run(train_step, feed_dict={x: train_xs[j], y_: xtest[j]})

```

# モデル評価

```
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    res = sess.run(accuracy, feed_dict={x: X_test, y_: ytest[0]})
    print("{0:.2f}".format(res))
```

精度はこんな感じになりました。

```
0.95
```


# 全体のコード

```python3:iris-classification1.py
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split

iris = datasets.load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)

k = [0, 38, 76, 112]
train_xs=train_ys=[]
for i in range(1, 4):
    tmp_x=tmp_y=[]
    for j in range(k[i-1], k[i]):
        tmp_x, tmp_y = tmp_x + [X_train[j]], tmp_y + [y_train[j]]
    train_xs, train_ys = train_xs + [tmp_x], train_ys + [tmp_y]

train_labels = tf.placeholder(tf.int64, [None])
test_labels = tf.placeholder(tf.int64, [None])
train_ = tf.one_hot(train_labels, depth=3, dtype=tf.float32)
test_ = tf.one_hot(test_labels, depth=3, dtype=tf.float32)

x = tf.placeholder(tf.float32, [None, 4])
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]))

y = tf.nn.softmax(tf.matmul(x, W) + b)
y_ = tf.placeholder(tf.float32, [None, 3])

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

xtest=ytest=[]
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)

    ytest.append(sess.run(test_, feed_dict={test_labels: y_test}))
    xtest = [sess.run(train_, feed_dict={train_labels: train_ys[i]}) for i in range(3)]

    for i in range(300):
        for j in range(3):
            sess.run(train_step, feed_dict={x: train_xs[j], y_: xtest[j]})

    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    res = sess.run(accuracy, feed_dict={x: X_test, y_: ytest[0]})
    print("{0:.2f}".format(res))

```