Переглянути джерело

모든 NTM Set의 PrefixSpan을 돌려보는 코드. 2900만 가지.

master
Hwanu 4 роки тому
джерело
коміт
d7f44f49f8
1 змінених файлів з 251 додано та 0 видалено
  1. 251
    0
      HwanWooCode/prefix_span.py

+ 251
- 0
HwanWooCode/prefix_span.py Переглянути файл

@@ -0,0 +1,251 @@
1
+#!/usr/bin/env python
2
+# coding: utf-8
3
+
4
+# In[1]:
5
+
6
+
7
+import pandas as pd
8
+import numpy as np
9
+from mlxtend.preprocessing import TransactionEncoder
10
+from mlxtend.frequent_patterns import association_rules, fpgrowth
11
+from prefixspan import PrefixSpan
12
+
13
+
14
+
15
+df = pd.read_csv("ts_data_accident-2020_sample.csv", low_memory=False, encoding='ISO-8859-1')
16
+pd.set_option('display.max_columns',None)
17
+df=df[['RISK_V2','INST_NM','DRULE_ATT_TYPE_CODE1','TW_ATT_IP','TW_ATT_PORT','TW_DMG_IP','TW_DMG_PORT','ACCD_DMG_PROTO_NM','TW_ATT_CT_NM','ACCD_FIND_MTD_CODE','DRULE_NM']].dropna()
18
+len(df)
19
+##################### NTM section #####################
20
+NTM_df=df[df['ACCD_FIND_MTD_CODE']==1]
21
+NTM_df
22
+
23
+# Pick out it in order to get the asset, risk, intent, black IP out
24
+RISK_V2=NTM_df['RISK_V2']
25
+RISK_V2_FILTERED=RISK_V2.dropna()
26
+## 결측값 제거.
27
+
28
+import json
29
+from pandas import json_normalize
30
+
31
+# modified
32
+def get_asset_desc(asset_field):
33
+    if asset_field == 'ASSETS_VAL_1':
34
+        return '공인-전체IP대역(유선)'
35
+    elif asset_field == 'ASSETS_VAL_2':
36
+        return '공인-전체IP대역(무선)'
37
+    elif asset_field == 'ASSETS_VAL_3':
38
+        return '공인-WEB서버'
39
+    elif asset_field == 'ASSETS_VAL_4':
40
+        return '공인-내부응용서버'
41
+    elif asset_field == 'ASSETS_VAL_5':
42
+        return '공인-DB서버'
43
+    elif asset_field == 'ASSETS_VAL_6':
44
+        return '공인-패치서버'
45
+    elif asset_field == 'ASSETS_VAL_7':
46
+        return '공인-네트워크'
47
+    elif asset_field == 'ASSETS_VAL_8':
48
+        return '공인-보안'
49
+    elif asset_field == 'ASSETS_VAL_9':
50
+        return '공인-업무용PC'
51
+    elif asset_field == 'ASSETS_VAL_10':
52
+        return '공인-비업무용PC'
53
+    elif asset_field == 'ASSETS_VAL_11':
54
+        return '공인-기타'
55
+    elif asset_field == 'ASSETS_VAL_12':
56
+        return '사설-전체IP대역(유선)'
57
+    elif asset_field == 'ASSETS_VAL_13':
58
+        return '사설-전체IP대역(무선)'
59
+    elif asset_field == 'ASSETS_VAL_14':
60
+        return '사설-WEB서버'
61
+    elif asset_field == 'ASSETS_VAL_15':
62
+        return '사설-내부응용서버'
63
+    elif asset_field == 'ASSETS_VAL_16':
64
+        return '사설-DB서버'
65
+    elif asset_field == 'ASSETS_VAL_17':
66
+        return '사설-패치서버'
67
+    elif asset_field == 'ASSETS_VAL_18':
68
+        return '사설-네트워크'
69
+    elif asset_field == 'ASSETS_VAL_19':
70
+        return '사설-보안'
71
+    elif asset_field == 'ASSETS_VAL_20':
72
+        return '사설-업무용PC'
73
+    elif asset_field == 'ASSETS_VAL_21':
74
+        return '사설-비업무용PC'
75
+    elif asset_field == 'ASSETS_VAL_22':
76
+        return '사설-기타'
77
+    else:
78
+        return ''
79
+
80
+def get_intent_desc(intent_field):
81
+    if intent_field == 'INTENT_VAL_1':
82
+        return '파괴'
83
+    elif intent_field == 'INTENT_VAL_2':
84
+        return '유출'
85
+    elif intent_field == 'INTENT_VAL_3':
86
+        return '지연'
87
+    elif intent_field == 'INTENT_VAL_4':
88
+        return '잠복'
89
+    elif intent_field == 'INTENT_VAL_5':
90
+        return '단순침입'
91
+    elif intent_field == 'INTENT_VAL_6':
92
+        return 'MD5'
93
+    elif intent_field == 'INTENT_VAL_0':
94
+        return 'Default'
95
+    else:
96
+        return ''
97
+
98
+def get_source_desc(source_field):
99
+    if source_field=='SOURCE_VAL_1':
100
+        return '북한IP'
101
+    if source_field=='SOURCE_VAL_3':
102
+        return 'ECSC Black IP'
103
+    else:
104
+        return ''    
105
+# New assets column
106
+
107
+## ASSETS_VAL을 아예 JSON항목으로 만들어서 새로운 데이터프레임으로 생성.
108
+risk_df = pd.DataFrame()
109
+for risk in RISK_V2_FILTERED:
110
+    risk = risk.replace("'", "\"") #json으로 만들려고.
111
+    json_string = json.loads(risk)
112
+    json_df = json_normalize(json_string)
113
+    risk_df = pd.concat([risk_df,json_df],ignore_index=True)    #DataFrame 합쳐주기. ignore_index = True를 해야 index가 재구성 된다.
114
+risk_df_column_names = risk_df.columns
115
+
116
+assets_df = []
117
+intents_df = []
118
+sources_df = []
119
+def filter_all(risk):
120
+    for i in range(0,len(risk)):
121
+        risks=[]
122
+        intents=[]
123
+        sources=[]
124
+        for column in risk_df_column_names:
125
+            # filter_asset
126
+            if 'ASSETS_VAL_' in column and risk.iloc[i][column]:
127
+                risk_key_desc = 'RISK_V2.' + column + '=' + get_asset_desc(column)
128
+                risks.append(risk_key_desc)
129
+            
130
+            # filter_intent
131
+            if 'INTENT_VAL_' in column and risk.iloc[i][column]:
132
+                intent_key_desc = 'RISK_V2.' + column + '=' + get_intent_desc(column)
133
+                intents.append(intent_key_desc)
134
+                
135
+            if 'SOURCE_VAL_' in column and risk.iloc[i][column]:
136
+                source_key_desc='RISK_V2.' + column + '=' + get_source_desc(column)
137
+                sources.append(source_key_desc)
138
+        
139
+        assets_df.append(risks)
140
+        intents_df.append(intents)
141
+        sources_df.append(sources)
142
+        
143
+filter_all(risk_df)
144
+## 여기까지 내가 만든 것.
145
+
146
+## ASSETS_VAL 확인
147
+NTM_df['ASSETS_VAL'] = assets_df
148
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].astype(str)
149
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].str.replace('[','',regex=True)
150
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].str.replace(']','',regex=True)
151
+# NTM_df['ASSETS_VAL']
152
+
153
+NTM_df['INTENT_VAL'] = intents_df
154
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].astype(str)
155
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].str.replace('[','',regex=True)
156
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].str.replace(']','',regex=True)
157
+# NTM_df['INTENT_VAL']
158
+
159
+NTM_df['SOURCE_VAL'] = sources_df
160
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].astype(str)
161
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].str.replace('[','',regex=True)
162
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].str.replace(']','',regex=True)
163
+# NTM_df['SOURCE_VAL']
164
+
165
+NTM_df.drop(columns=['RISK_V2'], inplace=True)
166
+
167
+##################### 여기서부터 진행하시면 됩니다. #####################
168
+##################### 아래 12개 아이템(12. 장비 ACCD_FIND_MTD_CODE 제외)에 대해서 모든 아이템 조합에 알고리즘 적용하기#####################
169
+
170
+# It should be 13 columns in total
171
+
172
+# 1. 기관 INST_NM
173
+# 2. 공격 DRULE_ATT_TYPE_CODE1
174
+# 3. 자산 ASSETS_VAL
175
+# 4. 위협공격ip TW_ATT_IP
176
+# 5. 위협공격port TW_ATT_PORT
177
+# 6. 위협피해ip TW_DMG_IP
178
+# 7. 위협피해port TW_DMG_PORT
179
+# 8. 위협피해프로토콜 ACCD_DMG_PROTO_NM
180
+# 9. 공격국가 TW_ATT_CT_NM
181
+# 10. 의도(7개) INTENT_VAL
182
+# 11. IP/URL 가중치 SOURCE_VAL
183
+# 12. 장비 ACCD_FIND_MTD_CODE
184
+# 13. 탐지규칙명 DRULE_NM
185
+
186
+NTM_df.isna().sum()
187
+
188
+# Change the Nan to zero
189
+NTM_df['ACCD_DMG_PROTO_NM']=NTM_df['ACCD_DMG_PROTO_NM'].replace(np.nan,'')
190
+NTM_df['INST_NM']=NTM_df['INST_NM'].replace(np.nan,'')
191
+NTM_df['DRULE_ATT_TYPE_CODE1']=NTM_df['DRULE_ATT_TYPE_CODE1'].replace(np.nan,'')
192
+NTM_df['TW_ATT_IP']=NTM_df['TW_ATT_IP'].replace(np.nan,0)
193
+NTM_df['TW_ATT_PORT']=NTM_df['TW_ATT_PORT'].replace(np.nan,0)
194
+NTM_df['TW_DMG_IP']=NTM_df['TW_DMG_IP'].replace(np.nan,0)
195
+NTM_df['TW_DMG_PORT']=NTM_df['TW_DMG_PORT'].replace(np.nan,0)
196
+NTM_df['TW_ATT_CT_NM']=NTM_df['TW_ATT_CT_NM'].replace(np.nan,'')
197
+NTM_df['ASSETS_VAL']=NTM_df['ASSETS_VAL'].replace(np.nan,0)
198
+NTM_df['INTENT_VAL']=NTM_df['INTENT_VAL'].replace(np.nan,0)
199
+NTM_df['SOURCE_VAL']=NTM_df['SOURCE_VAL'].replace(np.nan,0)
200
+NTM_df['DRULE_NM']=NTM_df['DRULE_NM'].replace(np.nan,'')
201
+
202
+# Check NaN out again
203
+NTM_df.isna().sum()
204
+
205
+# # Merge all
206
+
207
+# # Make one string from all of elements
208
+NTM_df['Combined']=NTM_df['INST_NM'].astype(str)+' '+NTM_df['TW_ATT_IP'].astype(str)+' '+NTM_df['TW_ATT_PORT'].astype(str)+' '+NTM_df['TW_DMG_IP'].astype(str)+' '+NTM_df['TW_DMG_PORT'].astype(str) +' '+NTM_df['ACCD_DMG_PROTO_NM'].astype(str)+' '+NTM_df['TW_ATT_CT_NM']+' '+NTM_df['ASSETS_VAL']+' '+NTM_df['INTENT_VAL']+' '+NTM_df['SOURCE_VAL']+' '+NTM_df['DRULE_ATT_TYPE_CODE1']+' '+NTM_df['DRULE_NM']
209
+
210
+NTM_com=NTM_df['Combined']
211
+## 내가 만든 컴바인
212
+## 모든 조합을 돌릴거면, [1,2,3,4,5] 처럼 배열의 원소로 만들어서 넣는게 가장 베스트 아닌가.
213
+## 그런데 순서를 다 바꿔줘야 하는데, 그건 어떻게 할 것인지 내일 물어보자.
214
+
215
+data_len = len(NTM_df)
216
+hwan_list = []
217
+for i in range(0,data_len):
218
+    accd_dmg_proto_nm = NTM_df.loc[i]['ACCD_DMG_PROTO_NM']
219
+    inst_nm = NTM_df.loc[i]['INST_NM']
220
+    drule_att_type_code1 = NTM_df.loc[i]['DRULE_ATT_TYPE_CODE1']
221
+    tw_att_ip = NTM_df.loc[i]['TW_ATT_IP']
222
+    tw_att_port = NTM_df.loc[i]['TW_ATT_PORT']
223
+    tw_dmg_ip = NTM_df.loc[i]['TW_DMG_IP']
224
+    tw_dmg_port = NTM_df.loc[i]['TW_DMG_PORT']
225
+    tw_att_ct_nm = NTM_df.loc[i]['TW_ATT_CT_NM']
226
+    assets_val = NTM_df.loc[i]['ASSETS_VAL']
227
+    intent_val = NTM_df.loc[i]['INTENT_VAL']
228
+    source_val = NTM_df.loc[i]['SOURCE_VAL']
229
+    drule_nm = NTM_df.loc[i]['DRULE_NM']
230
+    null_check_list = [accd_dmg_proto_nm, inst_nm, drule_att_type_code1, tw_att_ip, tw_att_port,
231
+            tw_dmg_ip, tw_dmg_port, tw_att_ct_nm, assets_val, intent_val, source_val, drule_nm]
232
+    not_null_arr = []
233
+    ## 리스트안에 빈 값을 빼버리자.
234
+    for item in null_check_list:
235
+        if item and item != '[]':
236
+            not_null_arr.append(item)
237
+    hwan_list.append(not_null_arr)
238
+
239
+new_ps = PrefixSpan(hwan_list)
240
+# new_ps : hwan_list안에 순서대로 null값을 제외한 모든값들이 [1,2,3,4,5,6] 이런식으로 들어가 있는데,
241
+# 이 값을 PrefixSpan 수행한 코드.
242
+
243
+## 여기도 내 코드
244
+test_ntm = new_ps.frequent(1)
245
+test_ntm_df = pd.DataFrame(test_ntm)
246
+test_ntm_df.rename(columns={0:'Frequency', 1:'Cause'}, inplace=True)
247
+print(test_ntm_df)
248
+test_sort_values = test_ntm_df.sort_values(by=['Frequency'],ascending=False,ignore_index=True)
249
+##
250
+
251
+# test_sort_values : PrefixSpan을 수행하여  Frequency가 나온 값. Frequency 를 기준으로 정렬했는데, 2900만가지나 된다. 

Завантаження…
Відмінити
Зберегти