이런 식으로 html_code와 악성 사이트 의심 여부가 있다고 하자. Beautifulsoup를 사용해 html_code로부터 악성 사이트 여부를 알아내는 모델을 만들어 보자.
1. html 에서 <script>...</script> 길이 계산
우리가 해야 하는 사항은 다음과 같다.
- BeautifulSoup으로 html소스를 python 객체로 변환
- 이걸 함수로 구현하기
- float으로 return 받기
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup
from urllib.parse import urlparse
#
def html_script_characters(soup):
# soup > script
html_len = str(soup.script) # soup 객체에서 <script> 태그를 문자열로 변환
return float(len(html_len.replace(' ', ''))) # 공백 제거 후 문자열 길이 반환
script_len = [] # 먼저 script 길이 리스트 생성
for index, row in df.iterrows(): # iterrows 로 df의 인덱스와 열 내용을 series 형태로 반환
soup = BeautifulSoup(row.html_code, 'html.parser') # row의 html_code를 'html.parser' 형태로 변환
# soup 객체 생성
script_len.append(html_script_characters(soup))
# script_len 리스트에 하나씩 길이 추가
df['html_script_characters'] = script_len # 열 추가, 피처 생성
이렇게 데이터 정리.
2. html 에서 공백 수 계산하기
def html_num_whitespace(soup):
try:
# soup > body > text 로 들어가서 안에 공백이 얼마나 있는지 확인
NullCount = soup.body.text.count(' ')
return float(NullCount)
except:
return 0.0
num_whitespace = [] # 리스트 생성
for index, row in df.iterrows():
soup = BeautifulSoup(row.html_code,'html.parser')
num_whitespace.append(html_num_whitespace(soup))
df['html_num_whitespace'] = num_whitespace
3. html 에서 body 길이 계산
def html_num_characters(soup):
try:
#soup > body > text
bodyLen = len(str(soup.body.text))
return float(bodyLen)
except:
return 0.0
html_body = []
for index, row in df.iterrows():
soup = BeautifulSoup(row.html_code, 'html.parser')
html_body.append(html_num_characters(soup))
df['html_body_len'] = html_body
대충 이렇게 나온다.
4. script 에서 scr, href 속성을 가진 태그 수
def html_link_in_script(soup):
numOfLinks = len(soup.findAll('script', {"src": True}))
numOfLinks += len(soup.findAll('script', {"href": True}))
return float(numOfLinks)
html_script_link_num = []
for index, row in df.iterrows():
soup = BeautifulSoup(row.html_code, 'html.parser')
html_script_link_num.append(html_link_in_script(soup))
df['html_script_link_num'] = html_script_link_num
이렇게 전처리를 계속 해 준다.
5. Confusion Matrix 만들기
from sklearn.metrics import classification_report as creport
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score
def plot_confusion_matrix(ax, matrix, labels = ['malicious','benign'], title='Confusion matrix', fontsize=9):
ax.set_xticks([x for x in range(len(labels))])
ax.set_yticks([y for y in range(len(labels))])
# Place labels on minor ticks
ax.set_xticks([x + 0.5 for x in range(len(labels))], minor=True)
ax.set_xticklabels(labels, rotation='90', fontsize=fontsize, minor=True)
ax.set_yticks([y + 0.5 for y in range(len(labels))], minor=True)
ax.set_yticklabels(labels[::-1], fontsize=fontsize, minor=True)
# Hide major tick labels
ax.tick_params(which='major', labelbottom='off', labelleft='off')
# Finally, hide minor tick marks
ax.tick_params(which='minor', width=0)
# Plot heat map
proportions = [1. * row / sum(row) for row in matrix]
ax.pcolor(np.array(proportions[::-1]), cmap=plt.cm.Blues)
# Plot counts as text
for row in range(len(matrix)):
for col in range(len(matrix[row])):
confusion = matrix[::-1][row][col]
if confusion != 0:
ax.text(col + 0.5, row + 0.5, int(confusion),
fontsize=fontsize,
horizontalalignment='center',
verticalalignment='center')
# Add finishing touches
ax.grid(True, linestyle=':')
ax.set_title(title, fontsize=fontsize)
ax.set_xlabel('prediction', fontsize=fontsize)
ax.set_ylabel('actual', fontsize=fontsize)
plt.show()
6. Decision Tree 모델링
# 1. import
from sklearn.tree import DecisionTreeClassifier
# 2. 선언
dtc = DecisionTreeClassifier()
# 3. fit()
dtc.fit(train_x,train_y)
# 4. predict()
dtc_pred = dtc.predict(val_x)
# train 및 val 데이터 정확도 확인 : score()
dtc.score(train_x, train_y), dtc.score(val_x, val_y)
#Confusion Matrix 확인
confusion = confusion_matrix(val_y, dtc_pred)
fig, ax = plt.subplots(figsize=(10,3))
plot_confusion_matrix(ax, confusion, fontsize=30)
plt.figure(figsize=(20,12))
plt.barh(y=Train_Data.columns[:-1],
width = dtc.feature_importances_)
plt.show()
6. 앙상블(Ensemble) - Random Forest
# 1. import
from sklearn.ensemble import RandomForestClassifier
# 2.선언
rfc = RandomForestClassifier()
# 3. fit()
rfc.fit(train_x,train_y)
# 4. predict()
rfc_pred = rfc.predict(val_x)
# train 및 val 데이터 정확도 확인 :score()
rfc.score(train_x,train_y), rfc.score(val_x, val_y)
# Confusion Matrix 확인
confusion = confusion_matrix(val_y, rfc_pred)
fig, ax = plt.subplots(figsize=(10,3))
plot_confusion_matrix(ax, confusion, fontsize=30)
# feature_importances_ 활용 Feature별 가중치 확인
plt.figure(figsize=(20,12))
plt.barh(y=Train_Data.columns[:-1],
width = rfc.feature_importances_)
rfc.feature_importances_)
plt.show()
7. AdaBoost 모델
: 약한 학습기(weak learner)의 오류 데이터에 가중치를 부여하면서 부스팅을 수행하며 학습
# 1. import
from sklearn.ensemble import AdaBoostClassifier
# 2.선언
abc = AdaBoostClassifier()
# 3. fit()
abc.fit(train_x,train_y)
# 4. predict()
abc_pred = abc.predict(val_x)
# train 및 val 데이터 정확도 확인 : score()
abc.score(train_x, train_y), abc.score(val_x, val_y)
#Confusion Matrix 확인
confusion = confusion_matrix(val_y, abc_pred)
fig, ax = plt.subplots(figsize=(10,3))
plot_confusion_matrix(ax, confusion, fontsize=30)
# feature_importances_ 활용 Feature별 가중치 확인
plt.figure(figsize=(20,12))
plt.barh(y=Train_Data.columns[:-1],
width = abc.feature_importances_)
plt.show()
8. Gradient Boost 모델
: 이전 예측기가 만든 잔여오차에 새로운 예측기를 학습
# 1. import
from sklearn.ensemble import GradientBoostingClassifier
# 2.선언
gbc = GradientBoostingClassifier()
# 3. fit()
gbc.fit(train_x,train_y)
# 4. predict()
gbc_pred = gbc.predict(val_x)
# train 및 val 데이터 정확도 확인 : score()
gbc.score(train_x, train_y), gbc.score(val_x,val_y)
#Confusion Matrix 확인
confusion = confusion_matrix(val_y, gbc_pred)
fig, ax = plt.subplots(figsize=(10,3))
plot_confusion_matrix(ax, confusion, fontsize=30)
# feature_importances_ 활용 Feature별 가중치 확인
plt.figure(figsize=(20,12))
plt.barh(y=Train_Data.columns[:-1],
width = gbc.feature_importances_)
plt.show()
9. 최적화
RandomForest GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
param_grid = [ {'n_estimators':[30,40,50,60,100], 'max_depth':[30,40,50,60,100]}]
rfc = RandomForestClassifier()
rfc_grid = GridSearchCV(rfc,
param_grid, #
cv=2,
scoring='accuracy', # Classification일때 'accuracy','f1' ...
# Regression 일때 'neg_mean_squared_error','r2'...
n_jobs=-1,
verbose=1 # Log 출력 Level 조정
)
rfc_grid.fit(train_x, train_y)
rfc_model = rfc_grid.best_estimator_
print('최적의 파라미터 값 : ', rfc_grid.best_params_)
print('최고의 점수 : ', rfc_grid.best_score_)
rfc_grid_pred = rfc_model.predict(val_x)
# train 및 val 데이터 정확도
rfc_model.score(train_x, train_y), rfc_model.score(val_x, val_y)
'데이터 분석' 카테고리의 다른 글
가입 고객 유형 예측 모델링 (0) | 2024.11.15 |
---|---|
네비게이션 도착시간 예측 모델링 (0) | 2024.11.15 |
데이터 전처리 python 코드 (0) | 2024.11.14 |