本当に質問を削除しますか?
質問が解決した場合は、クローズをすることができます。
解決した質問を削除せずに残しておくことで、他の方の役に立つかもしれません!
ぜひご活用ください!
Q&A
[Python LSTM ]LSTMのモデルで2値分類を実行する
解決したいこと
現在、Pythonの深層学習の勉強をしており、その過程で少しつまづいています。
詰まっている内容としては、LSTMの2値分類をを行いたいのですが、以下のモデルではLSTMの異常検知と2値分類が混ざった内容のコードになっているというところです。
LSTMの2値分類の実行方法等を調べてみたのですが、実行方法がわかりませんでした。
Pythonでの深層学習実行に関する知見のある方、LSTMを用いた2値分類の実行方法を教えていただけますでしょうか。
何卒よろしくお願いいたします。🙇♂️
データの前処理に関しては、以下のサイトを参考にしました。
https://qiita.com/ell/items/34f069651b551709d127
具体的にこんなことを実行したい
具体的には、LSTMの2値分類を実行し、LSTMモデルに学習させたアウトプットを、[11111.....00000]みたいな出力にしたいです。(正常な場合は1、異常な場合は0となるようにする)
その[1~0]の配列を、confusion_matrix()
の引数として渡し、計算できるようにしたいです。
環境・データセット
以下、研究で用いるデータ構造になります。
fTEpoch fLen fCLen pDelta ipProt1 ipProt6 ipProt17 portSrc portDst
0 1.541251e+09 1373.0 1373.0 0.550714 0 0 1 46649 5087
1 1.541251e+09 1514.0 1514.0 0.551437 0 0 1 46657 39736
2 1.541251e+09 1498.0 1498.0 0.549570 0 0 1 46657 39736
3 1.541251e+09 1514.0 1514.0 0.549820 0 0 1 46667 46528
4 1.541251e+09 972.0 972.0 0.549818 0 0 1 46667 46528
... ... ... ... ... ... ... ... ... ...
199995 1.609564e+09 60.0 42.0 0.413288 0 0 1 1526 5897
199996 1.609564e+09 60.0 42.0 0.413286 0 0 1 1526 7341
199997 1.609564e+09 98.0 66.0 0.546451 0 1 0 27683 16172
199998 1.609564e+09 67.0 66.0 0.545296 0 1 0 27683 16172
199999 1.609564e+09 113.0 66.0 0.547878 0 1 0 27683 16172
該当するソースコード
# ライブラリのインポート
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import time
import pickle
from settingfile import BASE_PATH
from sklearn.preprocessing import LabelEncoder
# ルックバック数
look_back = 6 # 偶数にする
# データ数
sample_size = len(dFTrain_oc) - look_back
# 予測に用いる期間
test_size = int(len(dFTest_oc))
# データセットを作る関数
def make_dataset(raw_data, look_back=1):
_X = []
_y = []
for i in range(len(raw_data) - look_back):
_X.append(raw_data[i : i + look_back])
_y.append(raw_data[i + look_back])
_X = np.array(_X).reshape(len(_X), look_back, 1)
_y = np.array(_y).reshape(len(_y), 1)
return _X, _y
from sklearn import preprocessing
columns = list(dFTrain_oc.columns)
print(columns)
# 最小0、最大1に正規化
Xs = []
for i in range(len(columns)):
Xs.append(preprocessing.minmax_scale(dFTrain_oc[columns[i]]))
Xs = np.array(Xs)
Xs_t = []
for i in range(len(columns)):
Xs_t.append(preprocessing.minmax_scale(dFTest_oc[columns[i]]))
Xs_t = np.array(Xs_t)
# 各数値データを作成
X_1, y_1 = make_dataset(Xs[0], look_back=look_back)
X_2, y_2 = make_dataset(Xs[1], look_back=look_back)
X_3, y_3 = make_dataset(Xs[2], look_back=look_back)
X_4, y_4 = make_dataset(Xs[3], look_back=look_back)
X_5, y_5 = make_dataset(Xs[4], look_back=look_back)
X_6, y_6 = make_dataset(Xs[5], look_back=look_back)
X_7, y_7 = make_dataset(Xs[6], look_back=look_back)
X_8, y_8 = make_dataset(Xs[7], look_back=look_back)
X_9, y_9 = make_dataset(Xs[8], look_back=look_back)
X_1_t, y_1_t = make_dataset(Xs_t[0], look_back=look_back)
X_2_t, y_2_t = make_dataset(Xs_t[1], look_back=look_back)
X_3_t, y_3_t = make_dataset(Xs_t[2], look_back=look_back)
X_4_t, y_4_t = make_dataset(Xs_t[3], look_back=look_back)
X_5_t, y_5_t = make_dataset(Xs_t[4], look_back=look_back)
X_6_t, y_6_t = make_dataset(Xs_t[5], look_back=look_back)
X_7_t, y_7_t = make_dataset(Xs_t[6], look_back=look_back)
X_8_t, y_8_t = make_dataset(Xs_t[7], look_back=look_back)
X_9_t, y_9_t = make_dataset(Xs_t[8], look_back=look_back)
# 多変量LSTMに対応するために各データを結合
X_con = np.concatenate([X_2,X_3,X_4,X_5,X_6,X_7], axis=2)
X_con_t = np.concatenate([X_2_t,X_3_t,X_4_t,X_5_t,X_6_t,X_7_t], axis=2)
# x_test,x_train,y_test,y_trainの設定====================
X = X_con
y = y_3
X_t = X_con_t
y_t = y_3_t
# 訓練データを定義
X_train = X # X_con
y_train = y
X_test = X_t
y_test = y_t
import tensorflow as tf
from tensorflow.keras.layers import Input, LSTM, Dense, BatchNormalization
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import SGD, Adam
# LSTMモデルを作成する関数
def create_LSTM_model():
input = Input(shape=(np.array(X_train).shape[1], np.array(X_train).shape[2]))
x = LSTM(64, return_sequences=True)(input)
x = BatchNormalization()(x)
x = LSTM(64)(x)
output = Dense(1, activation='tanh')(x)
model = Model(input, output)
return model
model = create_LSTM_model()
model.summary()
model.compile(optimizer=Adam(learning_rate=0.0001), loss='mean_squared_error')
history = model.fit(X_train, y_train, epochs=10, batch_size=64, verbose=1, validation_data=(X_test, y_test))
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(len(loss))
plt.figure(figsize=(15,5))
plt.plot(epochs, loss, "b", label="Training loss")
plt.plot(epochs, val_loss, "r", label="Validatioin loss")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.title("Training and validation loss")
plt.legend(fontsize=20)
plt.show()
predictions = model.predict(X_test)
predictions_round = np.round(predictions)
plt.figure(figsize=(15,5))
plt.plot( predictions_round, "r", label="predictions")
plt.legend(fontsize=20)
plt.show()
from sklearn.metrics import confusion_matrix
sizePos = 100000 - int(look_back / 2)#異常値のデータ数
sizeNeg = 100000 - int(look_back / 2) #正常値のデータ数
calc_oc = calc([1] * sizePos + [0] * sizeNeg, predictions_round, [1, 0]) # 正常値は1,異常値は0で表現する配列を第1引数に渡している??
tp, fn, fp, tn = confusion_matrix(a, b, labels=l).ravel() # 第1引数に正解ラベル、第2引数に予測ラベル
0
回答はまだありません