我有一个特定的模型要创建。我将在下面详细介绍
我尝试调整序列长度、时期、批量大小,仅采用数据集的一小部分(这会导致更糟糕的预测) 我还尝试在协议上进行一些重量平衡,但我真的不知道它是如何工作的,而且从我的尝试来看,我没有得到理想的结果。
非常感谢任何有关我应该重点改变的建议!
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from keras.models import Sequential
from keras.layers import LSTM, Dense
import matplotlib.pyplot as plt
# Step 1: Load and preprocess the data
data = pd.read_csv('paketa.csv')
data = data.dropna()
# Encode categorical variables
label_encoder = LabelEncoder()
data['Source'] = label_encoder.fit_transform(data['Source'])
data['Destination'] = label_encoder.fit_transform(data['Destination'])
data['Protocol'] = label_encoder.fit_transform(data['Protocol'])
# Select relevant columns
data = data[['Source', 'Destination', 'Protocol']]
# Use only the first 700,000 rows
# data_subset = data.iloc[:10000]
sequence_length = 50
# Step 2: Data Sequencing
sequences = []
targets = []
for i in range(len(data) - sequence_length):
seq = data.iloc[i:i+sequence_length].values # Extract sequence of length sequence_length
target = data.iloc[i+sequence_length]['Protocol'] # Next Protocol as target
sequences.append(seq)
targets.append(target)
X = np.array(sequences)
y = np.array(targets)
num_features = 3
epochs = 30
batch_size = 32
# Split the sequences and targets into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
all_protocols = np.concatenate((y_train, y_test), axis=None)
label_encoder.fit(all_protocols)
num_classes = len(label_encoder.classes_)
# Convert target variable to one-hot encoded format
y_train_encoded = label_encoder.transform(y_train)
y_test_encoded = label_encoder.transform(y_test)
#Model Architecture
model_lstm = Sequential()
model_lstm.add(LSTM(128, input_shape=(sequence_length, num_features),activation="relu")) # Add return_sequences=True for multiple layers
model_lstm.add(Dense(num_classes, activation='softmax'))
model_lstm.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model_lstm.fit(X_train, y_train_encoded, epochs=30, batch_size=32, validation_data=(X_test, y_test_encoded))
# Evaluation
lstm_loss, lstm_accuracy = model_lstm.evaluate(X_test, y_test_encoded)
print("LSTM Model Results:")
print(f"LSTM Loss: {lstm_loss}, LSTM Accuracy: {lstm_accuracy}")
# Visualize LSTM predictions
def visualize_lstm_predictions(model_lstm):
predictions_lstm = model_lstm.predict(X_test)
predicted_labels_lstm = np.argmax(predictions_lstm, axis=1)
actual_labels = label_encoder.inverse_transform(y_test_encoded)
predicted_labels_lstm = label_encoder.inverse_transform(predicted_labels_lstm)
plt.figure(figsize=(10, 6))
plt.plot(actual_labels, label='Actual', color='red')
plt.plot(predicted_labels_lstm, label='LSTM Predicted', color='black')
plt.title('LSTM Predicted vs Actual Protocols')
plt.xlabel('Sample')
plt.ylabel('Protocol')
plt.xticks(rotation=45)
plt.legend()
plt.show()
visualize_lstm_predictions(model_lstm)
有几件事需要注意。虽然这不太可能解决您的问题,但评论的文字太多。首先,你确定数据包数据是与时间相关的吗?当我想到网络流量时,我不确定是否可以仅通过了解数据包
x+1
到 0
的去向来确定数据包 x
。仅仅因为存在时间变量,并不意味着问题总是与时间相关。通常,您不会将编码器/缩放器安装在整个数据上,而仅安装在训练数据上。对 IP 地址进行标签编码也不是一个好主意。如果稍后出现一个全新的 IP 地址怎么办?你不会为它贴上标签。
我不确定这个主题,但我认为你应该扩展你的标签编码输入。但请注意,对非目标数据进行标签编码通常不是一个好主意。
接下来,正常的训练-测试分割对于时间序列数据来说是不可行的。训练数据永远不应该在时间尺度上的测试数据之后,通过随机的训练-测试分割,你就明白了。查看 sklearns TimeSeriesSplit。
对于网络,请查看关于 ReLU 激活的此答案。虽然它通常是一个很好的激活函数,但我不确定它是否能与 LSTM 配合良好。你应该测试一下这个。您还可以使用测试数据作为验证和测试数据。不要。
对于数据不平衡问题,请研究欠采样/过采样或对类进行加权(如此处所示)。我认为对于时间序列数据,您应该查看过采样不足的目标类。