基本的なコードはこことかここを参考にしている。 次稿で回帰の特性を確認する例として取り上げたかったので、Pandasの最新の仕様に合わせたり、説明がしやすくなるように微調整しています。
import keras
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers.normalization import BatchNormalization
from keras.callbacks import EarlyStopping
import math, random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def generate_data(period):
random_factor = 0.5
length = 500
data = pd.DataFrame(np.arange(period * length + 1), columns=["t"])
data["sine_wave"] = data.t.apply(lambda x: math.sin(
x * (2 * math.pi / period)+ random.uniform(-1.0, +1.0) * random_factor))
return data
def generate_dataset(dataframe, plen, inputs):
x, y = [], []
for i in range(len(dataframe)-inputs*2):
x.append(dataframe[["sine_wave"]].iloc[i:i+inputs].values.flatten())
y.append(dataframe[["sine_wave"]].iloc[i+inputs+plen].values.flatten())
return np.array(x), np.array(y)
def load_data(data, test_size, inputs):
n = int(round(len(data) * (1 - test_size)))
x_train, y_train = generate_dataset(data.iloc[0:n], inputs, inputs)
x_test, y_test = generate_dataset(data.iloc[n:], inputs, inputs)
return (x_train, y_train), (x_test, y_test)
period = 100
data = generate_data(period)
# data[["sine_wave"]].head(period * 2).plot()
# plt.show()
inputs = 400
hiddens = 200
(x_train, y_train), (x_test, y_test) = load_data(data, 0.1, inputs)
model = Sequential()
model.add(Dense(hiddens, input_shape=(len(x_train[0]),)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
for i in range(1, 4):
model.add(Dense(hiddens))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(1))
model.compile(loss="mean_squared_error", optimizer="adam")
early_stopping = EarlyStopping(patience=0, verbose=1)
model.fit(x_train, y_train, batch_size=50, epochs=10, validation_data=(x_test, y_test), callbacks=[early_stopping])
score = model.evaluate(x_test, y_test)
print('Test score:', score)
predicts = model.predict(x_test)
positive = np.sum((predicts > 0) == (y_test > 0))
print('Test Accuracy:', positive / predicts.size)
上記のコードは過去のinputs = 400の動きを元にplen = 400後の数値を予測します。
これを実行すると多少のノイズがあるsin波でも正負の判定なら92%くらい、誤差なら0.04くらいの精度で予測できる事が確認できると思います。
0 件のコメント:
コメントを投稿