2023年3月25日土曜日

ネットワークログの分析2 : ネットワークログから推移確率作成まで

今回は前回最後に集計したファイルを使って、そこから推移確率行列を作成していきます。前回作成したファイルは 
・netflow_day-02_sum.csv  (どのホストで通信があったかを集計したもの)
・netflow_day-02_device.csv  (ホストの集合、Src、Dstで和集合をとったもの)
の2つを利用していきます。
[2023/05/02 修正]
デバイス集合を和集合から積集合に変更したので、netflow_day-XX_device_intersection.csvを使うように変更します。

1. 推移確率行列作成のための元情報作成
推移確率行列は行和が1となる正規化されたものです。いきなりそれを作成する前に、一度どのくらいの量(カウント、通信バイト量など)があったかを推移確率の形で集計します。つまり、行はFromのホストが並び、列はToのホストが並びます。推移確率行列は正方行列のため、FromとToは同じホストが並びます。これは上記のnetflow_day-02_device.csvを使います。必要なライブラリを取り込み、ファイルを取り込みます。-> 変更 netflow_day-02_device_intersection.csv

この後、推移量をまとめるための2次元配列を用意します。

今回は元データにある、通信回数、通信時間、パケット数(fron, to)、バイト量(from, to)で作成しています。

保存されるcsvファイルはデータ量が大きいので注意が必要です。回数や通信時間は整数型なので、1.94GB、その他の実数型は6.79GBとなっています。計算は数分で終わると思いますが、保存に時間がかかります。

ここまでで各推移量の集計は完了です。
ここまでのソースコード
!pip3 install pandas
!pip3 install numpy
!pip3 install matplotlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
file = './netflow_day-02_sum.csv'
df = pd.read_csv(file, index_col=0)
df
file = './netflow_day-02_device.csv'
df_device = pd.read_csv(file)
df_device
transition_count = np.zeros((len(df_device), len(df_device)))
transition_duration = np.zeros((len(df_device), len(df_device)))
transition_from_packets = np.zeros((len(df_device), len(df_device)))
transition_to_packets = np.zeros((len(df_device), len(df_device)))
transition_from_bytes = np.zeros((len(df_device), len(df_device)))
transition_to_bytes = np.zeros((len(df_device), len(df_device)))
transition_count
device_list = df_device['Device'].tolist()
index = 0
for i in df.itertuples():
idx1 = device_list.index(i[1])
idx2 = device_list.index(i[2])
transition_count[idx1, idx2] = i.count
transition_duration[idx1, idx2] = i.duration
transition_from_packets[idx1, idx2] = i.from_packets
transition_to_packets[idx1, idx2] = i.to_packets
transition_from_bytes[idx1, idx2] = i.from_bytes
transition_to_bytes[idx1, idx2] = i.to_bytes
#print('{0}%処理済み'.format(index / len(df) * 100))
index += 1
np.savetxt('transition_count.csv', transition_count, fmt='%d', delimiter=',')
np.savetxt('transition_duration.csv', transition_duration, fmt='%d', delimiter=',')
np.savetxt('transition_from_packets.csv', transition_from_packets, fmt='%.4f', delimiter=',')
np.savetxt('transition_to_packets.csv', transition_to_packets, fmt='%.4f', delimiter=',')
np.savetxt('transition_from_bytes.csv', transition_from_bytes, fmt='%.4f', delimiter=',')
np.savetxt('transition_to_bytes.csv', transition_to_bytes, fmt='%.4f', delimiter=',')
view raw gistfile1.txt hosted with ❤ by GitHub

2. 推移確率行列への正規化
1で作成した推移量を使って、推移確率行列に正規化します。推移確率行列は行和が1なので、推移量のそれぞれの行和を求めて、割り算すればいいのですが、今回のdevice_listはSrcもDstもまとめた集合になっています。つまり、DstにしかなかったホストもSrcになりうる可能性があり、当然その行は通信がないので、行和が0となってしまいます。そのため、行和が0となるホストを集合から取り除いていきます。
行和が0となるホストの抽出->推移量とDevice_listから対象ホストを削除->行和が0となるホストの抽出->推移量とDevice_listから対象ホストを削除->...を繰り返していきます。今回はわかりやすくループでは実施していませんが、本来はループで一気に実施します。
今回は回数に注目してやっていきます。改めて保存したcsvファイルを取り込んでからやっていきます。
(1) 1回目 : 行和が0になるホストを削除(行と列を削除する) -> toにしかないホストを削除
行和が0となるホストのリストを作成して、推移量行列から削除していきます。

この処理で31,142×31,142の推移量行列だったものが、25,847×25,847に減りました。
(2) (1)でのホストをDevice_listから削除
Device_listからも(1)で選択された行和0のホストを削除します。
この(1)、(2)を行和0となるホストがなくなるまで繰り返します。
2回目

3回目

4回目
4回目では行和0のホストは検出されず、3回で終了です。
念の為、ここまでの推移量の行和0となった情報とホスト集合をcsvに保存しておきます。
最後に行和で割って、推移確率行列として、「transition_count_non0_rate.csv」として保存します。
transition_count_non0_rate.csvは実数型なので、データ量が少し大きくなるので注意してください。また今回のような回数(整数型)は行和で割るときに、キャストが必要です。

ひとまず、ここまでの流れを実施するには、下記の2つのソースファイルを利用しましょう。

0 件のコメント:

コメントを投稿