ワインの品種の予測

はじめに

2回目の記事です。

今回は、SIGNATEのワインの品種予測を行います。

ポイントは、練習としてディープラーニング (DNN) にて予想を行うという点です。

 

お題

ワインの化学成分から使用されているぶどうの品種を予測します。

 

評価方法

評価関数「Accuracy」です。

 

データ

学習データサンプル数:89

テストデータサンプル数:89
変数の数:13
欠損値:無し

 

各変数の項目は以下。

--

アルコール, リンゴ酸, 灰のアルカリ性, 灰, マグネシウム, フェノール類全量, フラバノイド, 非フラバノイドフェノール類, プロアントシアニン, 色彩強度, 色調, 蒸留ワインのOD280/OD315, プロリン

--

 

すべて"連続変数"です。

<連続変数の説明>

https://support.minitab.com/ja-jp/minitab/18/help-and-how-to/modeling-statistics/regression/supporting-topics/basics/what-are-categorical-discrete-and-continuous-variables/

 

モデル

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)

result.to_csv("result.csv", encoding="shift_jis")

 

予測結果

Accuracy = 0.97753 になりました。

 

感想

あとで。