7 분 소요

☀️공지 사항☀️ 해당 게시글은 SK 쉴더스 루키즈, 생성형AI 활용 사이버보안 전문인력 양성과정 을 수업을 듣고 정리한 글입니다. 자세한 교육 정보는 SK 쉴더스 홈페이지 를 확인해주세요.

# 학습 내용 요약 (25/11/06)

이번 학습은 Python의 핵심 데이터 과학 라이브러리인 Matplotlib, Pandas, NumPy, Seaborn을 통합적으로 사용하여 데이터를 시각화하고 분석하는 실질적인 방법을 다루었다. 특히, 정형 데이터 분석의 기본 원리부터 시작하여, 보안 분야에서 필수적인 이상치 탐지 기법(IQR, Box Plot), 그리고 최신 AI 트렌드(LLM, RAG)의 배경 지식까지 연계하여 실무적인 분석 역량을 강화하는 데 중점을 둔다.


1. Matplotlib 시각화 기본 구조와 효율적인 배치

Matplotlib을 활용한 시각화는 Figure(그림판)와 Axes(좌표 영역)라는 두 가지 핵심 객체를 이해하는 것에서 출발한다.

1.1. Figure와 Axes: 시각화의 두 축

모든 차트의 기본이 되는 Figure는 그림판 역할을 하며, 실제 차트(플롯)가 그려지는 영역은 Axes 객체이다.

용어 설명 Matplotlib 함수
Figure 전체 도화지. 크기와 전체 배경을 설정하는 최상위 컨테이너이다. plt.figure(figsize=...)
Axes (Ax) 실제 데이터가 표현되는 차트 영역 (좌표축). fig.add_subplot() 또는 plt.plot()

예시 코드 (Figure 생성 및 크기 지정):

import matplotlib.pyplot as plt

# 1. 그림판(Figure) 생성 및 크기 지정 (가로 20, 세로 7)
plt.figure(figsize=(20, 7)) 

# 2. 여기에 차트 생성 명령을 추가한다 (plt.plot, plt.bar 등)

# 3. 그림판 출력 및 자원 해제
plt.show()
plt.close()

1.2. 서브플롯(Subplots) 활용법

서브플롯은 하나의 Figure 내에 여러 개의 독립적인 Axes 영역을 생성하여 효율적으로 그래프를 배치하는 방법이다. 이는 다양한 각도에서 데이터를 동시에 비교 분석할 때 유용하다.

예시 코드 (1행 3열 서브플롯 배치):

# Figure 객체를 생성하고 fig 변수에 할당한다
fig = plt.figure(figsize=(15, 5))

# fig.add_subplot(행의 수, 열의 수, 포지션)
# 1행 3열 중 첫 번째 위치에 Axes 영역(ax01) 생성
ax01 = fig.add_subplot(1, 3, 1) 
# ax01.plot(...) # ax01 영역에 독립적인 차트를 그린다

# 1행 3열 중 두 번째 위치에 영역(ax02) 생성
ax02 = fig.add_subplot(1, 3, 2)
# ax02.bar(...) # ax02 영역에 독립적인 차트를 그린다

1.3. Subplot 객체 설정 유의사항 (Set 프리픽스)

서브플롯을 생성하여 반환받은 Axes 객체(예: ax01)를 이용해 제목이나 축 레이블을 설정할 때는 일반 plt 함수 대신 반드시 set_ 프리픽스가 붙은 메서드를 사용해야 한다.

일반 PLT 함수 (Figure 전체) 서브플롯 영역 객체 (ax) 설명
plt.title() ax.set_title() Axes 영역의 제목 설정
plt.xlabel() ax.set_xlabel() Axes 영역의 X축 레이블 설정
plt.grid() ax.grid() 축이 아닌 영역의 속성 설정에는 set_가 붙지 않을 수 있다.

2. 데이터 준비 및 범주형 분석 (막대 차트)

데이터 시각화는 데이터의 종류(범주형 vs. 연속형)에 따라 적합한 차트와 전처리 방식이 달라진다.

2.1. 차트별 데이터 요구사항

범주별 합계나 빈도를 비교하는 막대 차트는 X축이 반드시 범주형 데이터로 구성되어야 한다.

차트 종류 Matplotlib 함수 주요 용도 데이터 요구사항
라인 차트 plt.plot() 시간 경과에 따른 변화, 추이 분석 (연속성) 연속형 데이터 (시간, 온도, 주가 등)
막대 차트 plt.bar() 그룹별 비교, 빈도, 그룹별 합계 X축은 반드시 범주형(Categorical) 데이터여야 한다.

2.2. Pandas GroupBy를 이용한 데이터 집계

막대 차트를 구현하기 위해 원본 데이터를 범주별로 집계(Aggregation)하는 과정이 필수적이다. 이때 Pandas의 groupby() 메서드를 사용한다.

예시 코드 (선실 등급별 생존자 합계 계산):

import pandas as pd
# 가정: df_titanic에 데이터가 로드되어 있다고 가정

# Pclass(선실 등급)를 기준으로 그룹화하고 Survived(생존 여부)의 합계를 구한다
survival_sum_by_pclass = df_titanic.groupby('Pclass')['Survived'].sum() 

# GroupBy 결과는 Series 형태로, 인덱스(Pclass)가 X축, 값(Sum)이 Y축이 된다.
# print(survival_sum_by_pclass)
# Pclass
# 1    136
# 2     87
# 3    119
# Name: Survived, dtype: int64

2.3. 막대 차트 구현 및 X축 설정

범주형 데이터의 경우, X축 틱(Tick)이 데이터의 범주를 정확히 반영하도록 설정해주는 과정이 필요하다.

예시 코드 (GroupBy 결과를 시각화):

# 1. GroupBy 결과에서 인덱스(X)와 값(Y) 추출
X_data = survival_sum_by_pclass.index  
Y_data = survival_sum_by_pclass.values 

plt.figure(figsize=(10, 5)) 

# 2. 막대 차트 그리기
plt.bar(X_data, Y_data) 

# 3. X축 틱 설정: X_data 값(1, 2, 3)이 정확히 표시되도록 지정
plt.xticks(X_data) 
plt.title("선실 등급별 생존자 수 비교")
plt.show()

3. 모의 보안 로그 데이터셋 생성 실습

보안 분석 환경을 모방하기 위해 NumPy와 Pandas를 사용하여 타임스탬프와 사용자 활동, 상태 정보를 포함하는 DataFrame을 생성한다.

3.1. Time Series 및 랜덤 데이터 생성

시간 데이터(date_range)와 지정된 확률을 따르는 범주형 랜덤 데이터(np.random.choice)를 생성하여 실제 로그의 특성을 재현한다.

예시 코드 (시간 및 랜덤 데이터 생성):

import pandas as pd
import numpy as np

# 2024년 11월 6일부터 100개의 데이터를 시간(H) 간격으로 생성
time_data = pd.date_range(start='2024-11-06', periods=100, freq='H') 

# 사용자 데이터 (복원 추출)
user_list = ['admin', 'super_user', 'guest', 'analyst']
user_data = np.random.choice(user_list, size=100)

# 상태 데이터 (성공 60%, 실패 40% 확률 적용)
status_data = np.random.choice(
    ['Success', 'Fail'], 
    size=100, 
    p=[0.6, 0.4]  
)

# 응답 지연 시간 (연속형 난수 생성: 20ms ~ 800ms)
latency_data = np.random.randint(20, 800, size=100) 

3.2. 최종 DataFrame 구성

생성된 데이터들을 딕셔너리로 묶어 최종 DataFrame을 구성한다.

예시 코드 (최종 DataFrame 생성):

data_dict = {
    'Time': time_data,
    'User': user_data,
    'Status': status_data,
    'Latency_ms': latency_data
}

security_frame = pd.DataFrame(data_dict)
print(security_frame.head())
# Time                User   Status  Latency_ms
# 0 2024-11-06 00:00:00  analyst  Success         456
# 1 2024-11-06 01:00:00  analyst     Fail         789
# 2 2024-11-06 02:00:00    admin  Success          55
# ...

4. 데이터 분포 분석과 AI/보안 인사이트

데이터의 분포 형태를 분석하는 것은 잠재적인 문제점(예: AI 모델의 편향)을 파악하고 이상 징후를 탐지하는 데 핵심적인 단계이다.

4.1. 히스토그램: 연속형 데이터의 분포 확인

히스토그램은 연속형 데이터를 특정 구간(Bin)으로 나누어 빈도를 시각화하며, 데이터가 어느 지점에 집중되어 있는지 파악하게 해준다.

예시 코드 (지연 시간의 분포 확인):

# 연속형 데이터인 지연 시간('Latency_ms')의 분포를 확인
plt.hist(security_frame['Latency_ms'], bins=20) 
plt.xlabel("지연 시간 (ms)")
plt.ylabel("프리퀀시 (횟수)")
plt.title("로그인 지연 시간 분포")
plt.show() 

💡 AI 관점: 데이터 분포가 정규분포(대칭적인 종 모양)에서 크게 벗어날 경우(Skewness), AI 모델 학습 시 특정 데이터에 치우쳐 성능이 저하되는 편향(Bias)이나 오버피팅(Overfitting) 문제를 유발할 수 있다.

4.2. (심화) LLM의 신뢰성을 높이는 RAG 아키텍처

최근 LLM이 가진 정보의 최신성 및 신뢰성 문제를 해결하기 위해 RAG(검색 증강 생성) 아키텍처가 중요하게 부각되고 있다.

개념 설명 역할 및 문제 해결
LLM 대규모 언어 모델. 학습된 방대한 데이터를 기반으로 텍스트를 생성한다. 학습 데이터의 제약으로 최신 정보 반영이 어렵고, 허위 정보를 생성(Hallucination)할 수 있다.
RAG (검색 증강 생성) 외부의 신뢰할 수 있는 벡터 데이터베이스에서 필요한 정보를 검색한 후, 이를 LLM에 프롬프트로 제공하여 답변을 생성하게 한다. 별도의 모델 재학습(파인튜닝) 없이 모델의 신뢰성과 최신성을 획기적으로 높인다.
LangChain LLM과 RAG 파이프라인(검색기, 임베딩, 데이터베이스 등)을 효율적으로 연결하고 구성하는 환경을 제공하는 프레임워크이다. 복잡한 AI 워크플로우를 자동화하고 체인화하는 역할을 한다.

5. 이상치 탐지 (Outlier Detection)와 Box Plot

보안 분석에서 이상치 탐지는 비정상적인 접근, 시스템 부하, 또는 공격 시도를 찾아내는 데 가장 기본적인 방법이다. IQR(사분위 범위)은 이상치를 수학적으로 판정하는 표준 기준이 된다.

5.1. IQR 기반 이상치 탐지 기준

용어 설명 공식
Q1 (1사분위) 데이터의 25% 지점 값이다. df.quantile(0.25)
Q3 (3사분위) 데이터의 75% 지점 값이다. df.quantile(0.75)
IQR (Interquartile Range) 데이터의 중심 50%가 퍼진 정도이다. $Q3 - Q1$
Lower Bound (하한선) 이보다 작은 데이터는 이상치로 간주된다. $Q1 - 1.5 \times IQR$
Upper Bound (상한선) 이보다 큰 데이터는 이상치로 간주된다. $Q3 + 1.5 \times IQR$

5.2. IQR 계산 및 이상치 필터링

IQR 공식을 사용하여 연속형 데이터에서 이상치 판정 경계를 계산하고, 경계를 벗어난 데이터를 필터링한다.

예시 코드 (이상치 기준 계산 및 탐지):

# 가정: box_frm에 'Delay_MS' 데이터가 있다고 가정
delay_series = box_frm['Delay_MS']

# 1. Q1 및 Q3 계산
Q1 = delay_series.quantile(0.25)
Q3 = delay_series.quantile(0.75)

# 2. IQR 계산
IQR = Q3 - Q1

# 3. 상한선(Upper Bound) 계산
upper_bound = Q3 + (1.5 * IQR)

print(f"이상치 상한 기준 (Upper Bound): {upper_bound:.2f}")

# 4. 상한선을 초과하는 이상치 데이터 필터링
outliers = box_frm[box_frm['Delay_MS'] > upper_bound]
# print(outliers) # 비정상적으로 지연 시간이 긴 로그들

5.3. 박스 플롯 시각화

Seaborn 라이브러리는 박스 플롯을 더 직관적이고 깔끔하게 시각화하는 데 유리하며, 박스 외부에 점으로 표시된 것이 IQR 기준으로 탐지된 이상치이다.

예시 코드 (Seaborn 박스 플롯):

import seaborn as sns
# 가정: box_frm에 'Delay_MS' 데이터가 있다고 가정

plt.figure(figsize=(10, 4))
sns.boxplot(x='Delay_MS', data=box_frm, color='skyblue')
plt.title('로그인 지연시간 이상치 탐지')

# 박스 플롯 외부에 점으로 표시되는 데이터가 이상치(Outlier)이다.
plt.show() 

6. 변수 관계 분석 및 보안 위험도 탐지

데이터를 심층적으로 분석하기 위해서는 두 개 이상의 변수 간의 관계(상관관계)를 파악해야 한다.

6.1. Count Plot을 활용한 범주형 패턴 분석

Count Plot은 범주형 데이터의 빈도를 시각화하며, hue 옵션을 사용하여 두 범주형 변수 간의 복합적인 패턴을 한눈에 비교할 수 있다.

예시 코드 (사용자별 성공/실패 패턴):

# security_frame을 사용하여 User별 Status 비율을 시각화한다
sns.countplot(data=security_frame, x='User', hue='Status', palette='coolwarm')
plt.title('사용자별 로그인 성공/실패 비율')
plt.show() 

# 보안 인사이트: 
# 만약 'guest' 계정의 성공(Success) 대비 실패(Fail) 비율이 비정상적으로 높다면, 
# 이는 해당 계정을 대상으로 한 사전 공격(Dictionary Attack)이나 무작위 대입 공격 시도로 해석될 수 있다.

6.2. 산점도(Scatter Plot)를 이용한 위험 사용자 군집 분석

산점도는 두 연속형 변수 간의 관계를 점의 분포로 보여주며, 보안 분석에서는 여러 지표를 조합하여 사용자의 위험도 군집을 시각적으로 파악하는 데 활용된다.

축/속성 분석 변수 보안 해석
X축 평균 로그인 지연 시간 클수록 서버 부하 혹은 네트워크 공격 가능성이 높다.
Y축 실패율 높을수록 무작위 대입 공격 등 공격 시도 가능성이 높다.
도트 크기 (S) 총 로그인 시도 횟수 클수록 집중적인 공격 행위로 간주될 수 있다.

산점도를 통해 우측 상단에 크기가 큰 점으로 나타나는 사용자는 “지연 시간도 길고, 실패율도 높으며, 시도 횟수도 많은” 가장 위험한 비정상 행위자로 즉시 탐지될 수 있다.

공부 후기

금번 파이썬 데이터 시각화 및 보안 분석 통합 학습은 매우 실용적이고 유익했습니다. Matplotlib의 Figure와 Axes 구조를 명확히 이해하고, 서브플롯을 효율적으로 사용하는 방법을 익힐 수 있었습니다. 특히, 단순히 예쁜 그래프를 그리는 것을 넘어, 데이터의 분포 형태(히스토그램)가 AI 학습의 편향(Bias)으로 연결될 수 있다는 관점이나, RAG 아키텍처와 같은 최신 AI 트렌드를 시각화 맥락에서 함께 다룬 점이 좋았습니다.

보안 관점에서는 np.random.choice를 활용해 의도적으로 성공/실패 확률을 부여하여 모의 데이터를 생성하는 과정이 흥미로웠습니다. IQR 기반의 이상치 탐지 기준과 박스 플롯을 통해 비정상적인 시스템 지연 시간이나 공격 시도를 어떻게 즉각적으로 시각화할 수 있는지 깨달았습니다.

앞으로 생성된 모의 데이터를 기반으로 Count Plot이나 Scatter Plot에서 발견한 위험 사용자 그룹에 대해 더욱 깊이 있는 보안 필터링 및 조치 분석 과정을 연계 학습하겠습니다. 실무에 바로 적용 가능한 역량을 쌓는 데 큰 도움이 되는 강의였습니다. 감사합니다.

댓글 남기기