野菜価格に影響する要因を探り当てよう!
Oregin
野菜取引価格の予測で、価格の時系列を利用した簡単なLSTMのサンプルコードです。精度や見栄えはイマイチですが、なんとか動くものを作れました。ご参考までご活用ください。
※Google Colab(CPU利用,GPU不要)で実行可能です。
LB= 0.27614 でした。
ディレクトリ構成
import numpy as np import random import tensorflow as tf import pandas as pd from keras import backend as K from sklearn.preprocessing import MinMaxScaler import os
# 各種パスの設定 ###################################################################### base_path = '/content/drive/MyDrive/Probspace/20230519-Vegetable' # ベースとなるパスを指定してください。####### ###################################################################### os.makedirs(os.path.join(base_path,'output'), exist_ok=True) # 提出用ファイルを出力するディレクトリを作成 train_data_path = os.path.join(base_path,'data/train_data.csv') # 訓練データのパスを指定 submit_data_path = os.path.join(base_path,'data/submission.csv') # 提出用サンプルfileのパスを指定 output_file_path = os.path.join(base_path,'output/001_submission.csv') # 提出用ファイルのパスを指定
seed_value = 42 # NumPyの乱数シードを設定 np.random.seed(seed_value) # Pythonの組み込みのrandomの乱数シードを設定 random.seed(seed_value) # TensorFlowの乱数シードを設定 tf.random.set_seed(seed_value) # Kerasのバックエンド(TensorFlow)の乱数シードを設定 session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1) sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf) K.set_session(sess)
# 訓練データの読み込み train_data = pd.read_csv(train_data_path) train_data.shape
(47, 341)
# 列名から野菜の種類と地域を抽出 columns = train_data.columns[1:] # タイムスタンプの列を除外 vegetable_types = [col.split('_')[0] for col in columns] regions = [col.split('_')[1] for col in columns] print(len(vegetable_types)) print(len(regions))
340 340
# LSTMモデル用にデータを準備 scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(train_data.iloc[:, 1:]) print(scaled_data.shape)
(47, 340)
# 各予測に考慮するタイムステップ数を定義 lookback = 12 # データセットや要件に応じてこの値を調整できます
# シーケンスと対応するラベルを作成 sequences = [] labels = [] for i in range(lookback, len(scaled_data)): sequences.append(scaled_data[i - lookback:i]) labels.append(scaled_data[i])
# シーケンスとラベルをNumPy配列に変換 sequences = np.array(sequences) labels = np.array(labels) # データをトレーニングセットとバリデーションセットに分割 train_size = int(0.8 * len(sequences)) train_X, train_y = sequences[:train_size], labels[:train_size] val_X, val_y = sequences[train_size:], labels[train_size:]
from keras.models import Sequential from keras.layers import LSTM, Dense # LSTMモデルを構築 model = Sequential() model.add(LSTM(64, input_shape=(lookback, len(columns)))) model.add(Dense(len(columns))) # 列数と同じ数のユニットを持つ出力層 # モデルをコンパイル model.compile(loss='mse', optimizer='adam', metrics=['mse']) # モデルを訓練 model.fit(train_X, train_y, epochs=100, batch_size=16, validation_data=(val_X, val_y))
# 各列に対して将来のデータを予測 future_predictions = model.predict(sequences[-lookback:]) future_prices = scaler.inverse_transform(future_predictions)
1/1 [==============================] - 0s 289ms/step
# 各列の予測された将来価格を10行分表示 for i, col in enumerate(range(10)): # (columns): print(f"{vegetable_types[i]}の{regions[i]}における予測価格:{future_prices[0][i]}")
えのきだけの中国における予測価格:273.3566589355469 えのきだけの九州における予測価格:275.98046875 えのきだけの北海道における予測価格:255.60968017578125 えのきだけの北陸における予測価格:240.4779510498047 えのきだけの四国における予測価格:253.03582763671875 えのきだけの東北における予測価格:193.06195068359375 えのきだけの東海における予測価格:243.9519805908203 えのきだけの近畿における予測価格:246.7424774169922 えのきだけの関東における予測価格:205.58560180664062 かぶの北海道における予測価格:111.2426528930664
#テスト結果の出力 submit_df = pd.read_csv(submit_data_path) submit_df['y'] = pd.DataFrame(future_prices[0]) submit_df.to_csv(output_file_path,index=None)
# 出力ファイルの確認 read_df = pd.read_csv(output_file_path) read_df.head()