・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となっています。計算は数分で終わると思いますが、保存に時間がかかります。
ここまでで各推移量の集計は完了です。
ここまでのソースコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!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=',') |
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となるホストがなくなるまで繰り返します。4回目
4回目では行和0のホストは検出されず、3回で終了です。念の為、ここまでの推移量の行和0となった情報とホスト集合をcsvに保存しておきます。
最後に行和で割って、推移確率行列として、「transition_count_non0_rate.csv」として保存します。
transition_count_non0_rate.csvは実数型なので、データ量が少し大きくなるので注意してください。また今回のような回数(整数型)は行和で割るときに、キャストが必要です。全体のソースコード(TransitionMartix.py)
ひとまず、ここまでの流れを実施するには、下記の2つのソースファイルを利用しましょう。
0 件のコメント:
コメントを投稿