본문 바로가기

DevOps & Cloud

9. 인공지능 모델 학습

728x90
반응형

연구실 프로젝트 Season1 Ep9

모델을 선정하고 학습한다.

이상감지 모델에는 Isolation Forest라는 머신러닝 알고리즘이 많이 활용된다고 한다.

따라서 해당 알고리즘을 사용해서 모델을 만들고자 한다.

기본적으로 해당 알고리즘은 노드 구조를 굉장히 많이 반복해서 트리를 여러개 이어 붙인 것과 같다.

해당 알고리즘을 고른 이유는 feature가 많더라도 성능이 좋기 때문이다. 또한 비지도학습 이기 때문에 별도의 라벨링이 필요 없다.

 

참고: https://velog.io/@vvakki_/Isolation-Forest-미완성

 

Isolation Forest

[Post No.002] Isolation Forest 개념

velog.io

 

# 학습코드

import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import IsolationForest
import joblib
import numpy as np

# Load the data from a CSV file #빈칸은 nan으로
data = pd.read_csv('/content/drive/MyDrive/train.csv', na_values="nan")


# List of features to be used in the model
features = [
    'IP_source',
    'IP_destination',
    'l4_TCP_source_port',
    'l4_TCP_destination_port',
    'l4_TCP_flags_ACK',
    'source_identity',
    'destination_identity',
    'destination_labels_0',
    'destination_labels_1',
    'destination_labels_2',
    'destination_labels_3',
    'destination_labels_4',
    'Type',
    'traffic_direction',
    'trace_observation_point',
    'event_type_type',
    'Summary'
]

# Create a LabelEncoder object
le = LabelEncoder()

# Iterate through the features that need to be encoded
for feature in features:
    # Encode the feature values
    data[feature] = le.fit_transform(data[feature])

# Create a MinMaxScaler object
scaler = MinMaxScaler()

# Iterate through the features that need to be scaled
for feature in features:
    # Scale the feature values
    data[feature] = scaler.fit_transform(data[feature].values.reshape(-1,1))

# Create an Isolation Forest model
model = IsolationForest(random_state=0)

# Extract the feature values for the current row
feature_values = data[features].values

# Train the model on the current feature values
model.fit(feature_values)

# Save the model to a file
joblib.dump(model, "model_new.joblib")

우선 sklearn인 사이킷런에서 기본적으로 알고리즘을 제공해 준다. 

 

해당 알고리즘은 numerical data 즉 실수 데이터로 정보를 모두 바꿔서 판단한다. 따라서 string 형태의 데이터를 실수로 바꿔줘야 한다.

그때 유용한 게 LabelEncoder()이다. 

https://teddylee777.github.io/scikit-learn/labelencoder-사용법

 

카테고리형 데이터를 수치형으로 변환하기 (LabelEncoder와 type Category)

LabelEncoder를 사용하여 원핫(one-hot-encoding) 쉽게 하는 방법에 대하여 알아보겠습니다.

teddylee777.github.io

그리고 MinMaxScaler()로 0~1 사이로 변환한다.

 

# 파이프라인 + 모델 호출 및 사용

from pymongo import MongoClient
from pymongo.errors import PyMongoError
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import IsolationForest
import joblib
import numpy as np

# Connect to MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["logs"]
collection = db["network_flows"]

#모델 호출
model = joblib.load("model.joblib")

features = [
    'IP_source',
    'IP_destination',
    'l4_TCP_source_port',
    'l4_TCP_destination_port',
    'l4_TCP_flags_ACK',
    'source_identity',
    'destination_identity',
    'destination_labels_0',
    'destination_labels_1',
    'destination_labels_2',
    'destination_labels_3',
    'destination_labels_4',
    'Type',
    'traffic_direction',
    'trace_observation_point',
    'event_type_type',
    'Summary'
]

# Create a LabelEncoder object
le = LabelEncoder()

# Create a MinMaxScaler object
scaler = MinMaxScaler()

# Set up change stream to listen for new insertions
while 1:
    try:
        change_stream = collection.watch()
        for change in change_stream:
            if change["operationType"] == "insert":
                new_data = change["fullDocument"]

                feature_values = [new_data.get(feature, "nan") for feature in features]

                # Encode the feature values with the appropriate labelEncoder
                for i in range(len(feature_values)):
                    feature_values[i] = le.transform([feature_values[i]])[0]

                # Scale the feature values with the appropriate MinMaxScaler
                for i in range(len(feature_values)):
                    feature_values[i] = scaler.transform([[feature_values[i]]])[0][0]

                # Reshape the new feature values into a 2D array with a single row
                feature_values = np.array(feature_values).reshape(1, -1)

                # Use the predict method to detect outliers
                prediction = model.predict(feature_values)

                # check the prediction, if it is -1, it means the new data is an outlier
                if prediction[0] == -1:
                    print("The new data is an outlier")
                else:
                    print("The new data is not an outlier")

    except PyMongoError as e:
        print(e)

1차 시도(실패): 80000개 정도의 데이터로 학습시킨 모델을 사용해 봤으나 모든 새로운 네트워크 플로우 데이터를 -1 즉 이상탐지로 감지한다. 모델의 학습과정에서 오류를 확인하고 데이터의 양을 늘리기 위해 5초에 한 번씩 네트워크 플로우를 수집하도록 바꿨다.

728x90
반응형