ワインの品種の予測
はじめに
2回目の記事です。
今回は、SIGNATEのワインの品種予測を行います。
ポイントは、練習としてディープラーニング (DNN) にて予想を行うという点です。
お題
ワインの化学成分から使用されているぶどうの品種を予測します。
評価方法
評価関数「Accuracy」です。
データ
学習データサンプル数:89
テストデータサンプル数:89
変数の数:13
欠損値:無し
各変数の項目は以下。
--
アルコール, リンゴ酸, 灰のアルカリ性, 灰, マグネシウム, フェノール類全量, フラバノイド, 非フラバノイドフェノール類, プロアントシアニン, 色彩強度, 色調, 蒸留ワインのOD280/OD315, プロリン
--
すべて"連続変数"です。
<連続変数の説明>
モデル
DNNを使用します。
今回は、DNNの練習をするのが目的なので、モデルの選別はしないです。
○DNNの詳細
隠れ層の数 = 3 (適当。特に理由はなし。)
隠れ層あたりのニューロン数 = 13 (入力層と同一。3層とも同数)
活性化関数 = ReLU関数
コスト関数 = 交差エントロピー
オプティマイザ = 勾配降下法
バッチサイズ = 10 (適当。特に理由はなし。)
エポック数 = 5000 (適当。特に理由はなし。)
○DNNの参考
オライリーの"scikit-learnとTensorFlowによる実践機械学習"の第10章を参考にしました。
ソースコード
# In[1]:
from sklearn import preprocessing
import pandas as pd
min_max_scaler = preprocessing.MinMaxScaler()
wine = pd.read_csv("train.tsv", delimiter='\t')
wine_copy = wine.copy()
wine_data = wine_copy.drop(["Y", "id"], axis=1)
wine_data_scaled = min_max_scaler.fit_transform(wine_data)
wine_label = wine_copy["Y"].copy()
wine_label_minus = wine_label - 1
wine_data_numpy = wine_data_scaled
wine_label_numpy = wine_label_minus.values
# In[2]:
import numpy as np
def next_batch(num, data, labels):
idx = np.arange(0 , len(data))
np.random.shuffle(idx)
idx = idx[:num]
data_shuffle = [data[ i] for i in idx]
labels_shuffle = [labels[ i] for i in idx]
return np.asarray(data_shuffle), np.asarray(labels_shuffle)
# In[3]:
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
import tensorflow as tf
import numpy as np
n_inputs = 13
n_hidden1 = 13
n_hidden2 = 13
n_hidden3 = 13
n_outputs = 3
num_examples = 89
X = tf.placeholder(tf.float32, shape=(None, n_inputs), name="X")
y = tf.placeholder(tf.int64, shape=(None), name="y")
# In[4]:
def neuron_layer(X, n_neurons, name, activation=None):
with tf.name_scope(name):
n_inputs = int(X.get_shape()[1])
stddev = 2 / np.sqrt(n_inputs + n_neurons)
init = tf.truncated_normal( (n_inputs, n_neurons), stddev=stddev)
W = tf.Variable(init, name="kernel")
b = tf.Variable(tf.zeros([n_neurons]), name="bias")
Z = tf.matmul(X, W) + b
if activation is not None:
return activation(Z)
else:
return Z
# In[5]:
with tf.name_scope("dnn"):
hidden1 = neuron_layer(X, n_hidden1, name="hidden1", activation=tf.nn.relu)
hidden2 = neuron_layer(X, n_hidden2, name="hidden2", activation=tf.nn.relu)
hidden3 = neuron_layer(X, n_hidden3, name="hidden3", activation=tf.nn.relu)
logits = neuron_layer(hidden3, n_outputs, name="outputs")
# In[6]:
with tf.name_scope("loss"):
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
loss = tf.reduce_mean(xentropy, name="loss")
# In[7]:
learning_rate = 0.01
with tf.name_scope("train"):
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
training_op = optimizer.minimize(loss)
# In[8]:
with tf.name_scope("eval"):
correct = tf.nn.in_top_k(logits, y, 1)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
# In[9]:
init = tf.global_variables_initializer()
saver = tf.train.Saver()
# In[10]:
n_epochs = 5000
batch_size = 10
# In[11]:
with tf.Session() as sess:
init.run()
for epoch in range(n_epochs):
for iteration in range(num_examples // batch_size):
X_batch, y_batch = next_batch(batch_size, wine_data_numpy, wine_label_numpy)
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch})
if epoch%500 == 0:
print(epoch, "Train accuracy:", acc_train)
save_path = saver.save(sess, "./my_model_final.ckpt")
# In[12]:
wine_test = pd.read_csv("test.tsv", delimiter='\t')
wine_test_copy = wine_test.copy()
wine_test_data = wine_test_copy.drop(["id"], axis=1)
wine_test_data_scaled = min_max_scaler.fit_transform(wine_test_data)
wine_test_data_numpy = wine_test_data_scaled
wine_test_id = wine_test_copy["id"].copy()
# In[13]:
with tf.Session() as sess:
saver.restore(sess, "./my_model_final.ckpt")
Z = logits.eval(feed_dict={X: wine_test_data_numpy})
y_pred = np.argmax(Z, axis=1)
y_pred_plus = y_pred + 1
# In[14]:
result = pd.Series(y_pred_plus, index = wine_test_id)
予測結果
Accuracy = 0.97753 になりました。
感想
あとで。