관리 메뉴

너와 나의 스토리

Computer Network Traffic - kaggle 실습 / RNN 본문

Data Analysis/Machine learning

Computer Network Traffic - kaggle 실습 / RNN

노는게제일좋아! 2019. 7. 25. 15:36
반응형

kaggle(https://www.kaggle.com/crawford/computer-network-traffic)에 있는 데이터 셋으로 실습하였습니다.

 

<”odd” activity> 

Date: IP  => 08-24(235): 1 / 09-04(246): 5 / 09-18(260): 4 / 09-26(268): 3, 6

          

* kernels을 참조

 

 

 

 

RNN(Recurrent Neural Network) 미리 공부하고 보기!

 

 

1. import & data load

import numpy as np  #linear algebra
import pandas as pd  #data processing, csv file I/O
import matplotlib.pyplot as plt
import seaborn as sns
from subprocess import check_output 

df = pd.read_csv('./input/cs448b_ipasn.csv')

 

2. date별로 그룹 묶기

df['date']= pd.to_datetime(df['date'])
df = df.groupby(['date','l_ipn'],as_index=False).sum()  #date와 l_ipn별로 합을 구함

as_index: 이 그룹을 인덱스로 지정할 것인지 여부

df['date']: 빠른 날짜부터 인덱싱됨

 

df['yday'] = df['date'].dt.dayofyear
df['wday'] = df['date'].dt.dayofweek

dayofweek: 월요일=0, 일요일=6 이런식으로 매핑한 후, 빠른 날짜부터 인덱싱 됨

                여기서 날짜(2006-07-01) 대신 5(토요일)로 기록됨

dayofyeark: 0~365

 

 

 

3. 그래프 그리기 

 

3-1 l_ipn를 기준으로 그룹 묶기

l_ipn: local IP (0~9)

f: flows (count of connections for that day)

 

l_ipn가 0인 것끼리, 1인 것끼리, ... 묶기

 

3-2 그래프 그리기 - 데이터 파악

 

● ip별 f(날짜별 connection 수)의 분포도

ip별로 히스토그램 만들기 -> cv2.calcHist()와 np.histogram() 함수 사용 가능

division: bin에 대해 자동으로 계산된 경계

count: 각 bin 내의 모집단

f, axarray = plt.subplots(5,2,figsize=(15,20))  # 5X2로 10개의 flow를 보일 것이다
count,division = np.histogram(ip0['f'],bins=10) # bins는 x축의 간격
g= sns.barplot(x=division[0:len(division)-1],y=count,ax=axarray[0,0]) #(0,0) 위치에 그래프를 넣을 것이다.
axarray[0,0].set_title("Local IP 0 Flow")

count, division = np.histogram(ip1['f'],bins=10)
sns.barplot(x=division[0:len(division)-1],y=count,ax=axarray[0,1])
axarray[0,1].set_title("Local IP 1 Flow")

.
.
.

 

● 일년에서 날짜별 connection 수 흐름

f,axarray = plt.subplots(5,2,figsize=(15,20))
axarray[0,0].plot(ip0['yday'],ip0['f'])
axarray[0,0].plot(ip0['yday'], [ip0['f'].mean() + 3*ip0['f'].std()]*len(ip0['yday']),color='g')
axarray[0,0].set_title("Local IP 0 Flow")
<...>

- .std(): 표준편차(분산의 제곱근)

 

 

4. 예측하기 - RNN

4-1 keras 함수들을 사용하기 위해 import

import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import GRU
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error

4-2 정규화

fv =[float(v)/float(max0) for v in ip0['f'].values]
ip0.loc[:,'f'] =np.array(fv).reshape(-1,1)
fv =[float(v)/float(max1) for v in ip1['f'].values]
ip1.loc[:,'f'] =np.array(fv).reshape(-1,1)
.
.

 

4-3 create_dataset

feature 리스트와 우리 모델의 target을 만든다

def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back)].values
        dataX.append(a)
        dataY.append(dataset['f'].iloc[i + look_back])
    return np.array(dataX), np.array(dataY)

look_back 변수: 지금으로부터 이전에 몇 개의 데이터를 볼지 결정

 

 

4-4 trainModel

RNN 훈련시킴

def trainModel(data):
    data['f'] = data['f'].astype('float32')
    train = data[0:look_back*5].copy()
    trainX, trainY = create_dataset(train, look_back)
    trainX = np.reshape(trainX, (trainX.shape[0], look_back, 2))
    model = Sequential()
    model.add(GRU(64,input_shape=(trainX.shape[1], trainX.shape[2]),
               return_sequences=True))
    model.add(GRU(32))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='sgd')
    model.fit(trainX, trainY, epochs=100, batch_size=16, verbose=0)
    return model

- Sequential(): model(NN) 초기화

- Dense(1): 출력 뉴런 수=1, 입력 뉴런 수를 따로 지정 안해주면 이전 입력된 수 그대로 이번 입력 뉴런 수로 설정됨 

- GRU(): LSTM이랑 비슷한 것(참고)

 

 

4-5 predictFlow

훈련된 모델로 예측 수행

예측: 

def predictFlow(_model,data):
    ypred=[0]*look_back
    for k in range(len(data)-look_back):
        pattern = data[k:k+look_back].values
        x = np.reshape(pattern, (1, len(pattern), 2))
        ypred.append(_model.predict(x)[0][0])  #ypred=[v*_max for v in ypred]
    return ypred

 

 

4-6 예측 결과 보기

$m_{i}$: 훈련된 모델

$ypred_{i}$: 예측된 값

$max_{i}$: $ip_{i}$['f']에서 최대값

m0 = trainModel(ip0[['f','wday']].copy())
m1 = trainModel(ip1[['f','wday']].copy())
<...>

f,axarray = plt.subplots(5,2,figsize=(15,20))

ypred0 = np.multiply(predictFlow(m0,ip0[['f','wday']].copy()),max0)
ip0f = np.multiply(ip0['f'],max0)
ypred1 = np.multiply(predictFlow(m1,ip1[['f','wday']].copy()),max1)
<...>

axarray[0,0].plot(ip0['yday'],ip0f)
axarray[0,0].plot(ip0['yday'],ypred0,color='r')
axarray[0,0].set_title("Local IP 0 Flow and prediction")

axarray[0,1].plot(ip1['yday'], ip1f)
axarray[0,1].plot(ip1['yday'], ypred1,color='r',alpha=1)
axarray[0,1].set_title("Local IP 1 Flow and prediction")
<...>

상관 관계 분석

#ipNf: 실제 값, ypredN: 예측 값
corr0 = pd.Series(ip0f).corr(pd.Series(ypred0))  
corr1 = pd.Series(ip1f).corr(pd.Series(ypred1))
<...>
corrdf = pd.DataFrame({'corr0':[corr0],
                       'corr1':[corr1],
                       'corr2':[corr2],
                       'corr3':[corr3],
                       'corr4':[corr4],
                       'corr5':[corr5],
                       'corr6':[corr6],
                       'corr7':[corr7],
                       'corr8':[corr8],
                       'corr9':[corr9]})
corrdf

 

 

 

5. Approximate Entropy - 참고

Time series entroy 계산

 

5-1 ApEn 정의(알고리즘)

def ApEn(U, m, r):

    def _maxdist(x_i, x_j):
        return max([abs(ua - va) for ua, va in zip(x_i, x_j)])

    def _phi(m):
        x = [[U[j] for j in range(i, i + m - 1 + 1)] for i in range(N - m + 1)]
        C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
        return (N - m + 1.0)**(-1) * sum(np.log(C))

    N = len(U)

    return abs(_phi(m + 1) - _phi(m))

5-2 평가

m=2
r = 3
e0 = ApEn(np.multiply(ip0['f'].values,1),m,r)
e1 = ApEn(np.multiply(ip1['f'].values,1),m,r)
<...>

* entropy가 낮을수록 변동이 작아 예측이 쉬움

반응형
Comments