代码之家  ›  专栏  ›  技术社区  ›  GENERALE

协议预测实现中的LSTM/GRU模型准确性问题

  •  -1
  • GENERALE  · 技术社区  · 1 年前

    我有一个特定的模型要创建。我将在下面详细介绍

    1. 我有一个wireshark cap文件,从中我生成了一个1.4行的csv文件(不是整个cap文件而是它的一个示例)
    2. 我想在我的模型中使用的信息是 源、目标、协议 列和 LSTM 我实现的模型应该理解源/目的地/协议字段和 对协议字段进行预测 .
    3. 问题来了。。。协议字段中的协议为 不平衡的 约有100万个TCP和20万个UDP实例,其余为其他协议
    4. 我创建的模型达到了0.8-0.85的精度,这仅仅是TCP预测

    我试着调整 序列长度、时期、批量大小只占数据集的一小部分(这会导致更糟糕的预测) 我还尝试对协议进行一些权重平衡,default_weight库使每个协议的精度为0.3/0.4,但由于示例的主要协议是TCP,因此总体精度为0.2

    任何关于我可以更改以提高欠采样协议准确性的建议都是非常受欢迎的!

    import pandas as pd
    import numpy as np
    from sklearn.model_selection import TimeSeriesSplit
    from sklearn.feature_extraction import FeatureHasher
    from sklearn.preprocessing import LabelEncoder
    from keras.models import Sequential
    from keras.layers import LSTM, Dense
    from keras.utils import to_categorical
    import matplotlib.pyplot as plt
    
    
    # Load and preprocess the data
    data = pd.read_csv('paketa.csv')
    data = data.dropna()
    data = data[(data['Protocol'] != 'IPv6') & (data['Protocol'] != 'MPTCP')]
    unique_classes = data['Protocol'].unique()
    print("Unique Class Indices:", unique_classes)
    # Extract subset of the data
    #subset_start_index = 0
    #subset_end_index = 200000
    #subset_data = data.iloc[subset_start_index:subset_end_index]
    
    # Preprocess categorical features using FeatureHasher
    # Convert 'Source' and 'Destination' to lists of strings
    source_strings = data['Source'].astype(str).apply(lambda x: x.split('.')).values
    destination_strings = data['Destination'].astype(str).apply(lambda x: x.split('.')).values
    
    hasher_source = FeatureHasher(n_features=10, input_type='string')
    hashed_source = hasher_source.transform(source_strings)
    hashed_destination = hasher_source.transform(destination_strings)
    
    # One-hot encode the 'Protocol' feature
    protocol_onehot = pd.get_dummies(data['Protocol'])
    
    # Combine the preprocessed features
    hashed_features_array = np.concatenate([hashed_source.toarray(), hashed_destination.toarray(), protocol_onehot], axis=1)
    
    # Continue with the rest of your code
    sequence_length = 10
    sequences = []
    targets = []
    
    for i in range(len(hashed_features_array) - sequence_length):
        seq = hashed_features_array[i:i+sequence_length]
        target = data.iloc[i+sequence_length]['Protocol']
        sequences.append(seq)
        targets.append(target)
    
    X = np.array(sequences)
    y = np.array(targets)
    print(X)
    print(X.shape)
    print(y.shape)
    
    # Convert target labels to numerical indices
    unique_labels = np.unique(y)
    label_encoder = LabelEncoder()
    label_encoder.fit(unique_labels)
    y_indices = np.array([label_encoder.transform([label])[0] for label in y])
    
    # Convert target indices to one-hot encoded vectors
    y_onehot = to_categorical(y_indices, num_classes=len(unique_labels))
    
    # Build LSTM model
    num_classes = len(unique_labels)
    num_features = hashed_features_array.shape[1]
    
    model = Sequential()
    model.add(LSTM(128, input_shape=(sequence_length, num_features)))
    model.add(Dense(num_classes, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    
    # Use TimeSeriesSplit for train-test split
    tscv = TimeSeriesSplit(n_splits=2)
    
    for train_index, test_index in tscv.split(X):
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y_onehot[train_index], y_onehot[test_index]
    
        # Train the model without class weights
        model.fit(X_train, y_train, epochs=5, batch_size=32)
    
        # Evaluate the model
        loss, accuracy = model.evaluate(X_test, y_test)
        print("Model Results:")
        print(f"Loss: {loss}, Accuracy: {accuracy}")
    
    0 回复  |  直到 1 年前
        1
  •  1
  •   mhenning    1 年前

    有几件事需要注意。虽然这不太可能解决你的问题,但评论起来太多了。首先,你确定数据包数据是依赖时间的吗?当我想到网络流量时,我不确定数据包 x+1 只需知道数据包在哪里就可以确定 0 x 正在进行。仅仅因为有一个时间变量,并不意味着问题总是与时间相关的。
    对于这些功能,您可以查看一个热编码,但看起来它只适用于协议功能。虽然一种热编码有其缺点,但标签编码为该功能带来了秩序,而您不希望出现这种情况。标记为0的协议将比协议1“小”,协议1和3的平均值为协议2,依此类推。IP地址也是分类数据。我曾经处理过IP地址数据,我们使用 feature hashing 这并不是说这是唯一的(或通常是好的)方式,但它带来了一些专业人士。

    通常,编码器/缩放器不适合整个数据,只适合训练数据。对IP地址进行标签编码也不是一个好主意。如果稍后出现一个全新的IP地址怎么办?你不会有标签的。
    我不确定这个主题,但我认为你应该缩放你的标签编码输入。但请注意,对非目标数据进行标签编码通常不是一个好主意。

    其次,对于时间序列数据,正常的列车测试分割是不可行的。训练数据永远不应该在时间尺度上的测试数据之后,通过随机的训练测试分割,你会得到这一点。看看sklearns TimeSeriesSplit .

    对于网络,请查看 this answer 关于ReLU激活。虽然它通常是一个很好的激活函数,但我不确定它是否能很好地与LSTM配合使用。你应该测试一下。您还可以将测试数据用作验证和测试数据。不要。

    至于您的数据不平衡问题,请研究类的欠采样/过采样或加权(如已完成 here ). 我认为对于时间序列数据,您应该查看过采样不足的目标类。