jyamethyst21 님의 블로그

머신러닝 & 딥러닝 본문

보안 & IT 지식 🌺

머신러닝 & 딥러닝

jyamethyst21 2026. 1. 14. 16:47

비지도학습

- 정의: 정답이 없는 데이터를 기반으로 학습하는 머신러닝 방법

- 입력 데이터에 포함된 숨겨진 패턴이나 데이터의 구조를 파악하는데 초점을 맞춤

- 활용 분야: 군집화, 차원 축소, 이상치 탐지 등

- 지도학습 vs 비지도학습

군집화

- 군집화: 주어진 데이터에서 유사한 특성을 가진 데이터 포인트들을 그룹으로 묶는 것

- 각 그룹을 클러스터라고 하며, 데이터를 사전에 분류하지 않고 살펴보며 그룹 형성

- 유클리드 거리 사용

K-means

- K-means: 데이터 군집화에서 가장 널리 사용되는 알고리즘

- 주어진 데이터를 K개의 클러스터로 나누는 비지도 학습 방법

- 반복적이고 간단한 방식으로 데이터를 그룹화하며, 각 클러스터는 하나의 중심으로 설정

- 알고리즘 원리

  가) 초기 클러스터 중심 설정 : 클러스터의 개수 K를 사용자가 미리 설정하고 초기 클러스터 중심은 무작위로 설정하거나 데이터를 기반으로 선택

  나) 데이터 포인트 할당 : 각 데이터 포인트를 가장 가까운 클러스터 중심에 할당(가까운 중심에 속하는 데이터 포인트들이 하나의 클러스터를 형성), 데이터 포인트와 클러스터 중심 사이의 거리는 일반적으로 유클리드 거리를 사용하여 계산

  다) 클러스터 중심 재계산 : 각 클러스터에 속한 데이터 포인트들의 평균 위치를 계산하여 새로운 클러스터 중심으로 설정

  라) 반복

- K 값 선택 방법 : 엘보우 방법을 통해 최적의 K 값 선택

-> 여러 K값에 대해 K-means를 실행하고 각 경우의 클러스터 내 데이터의 거리 합을 계산, K 값에 따른 WCSS(클러스터 내 데이터의 거리 합)을 계산

-> K 값에 따른 WCSS를 그래프로 그려 그래프의 기울기가 급격히 완화되는 지점(엘보우 포인트)에서 최적의 K를 선택

# 라이브러리 불러오기
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# 데이터셋 생성
X, y = make_blobs(n_samples=300, centers=3, random_state=42)

# KMEANS 객체 생성
kmeans = KMeans(n_clusters=3, random_state=42)

# KMEANS 학습 및 예측
cluster_labels = kmeans.fit_predict(X)

# 그래프 작성
plt.scatter(X[:, 0], X[:, 1], cmap='viridis', c=cluster_labels)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', marker='X')

 

# 클러스터를 1부터 9까지 진행하며 최적의 군집 개수 찾기

result = []

for i in range(1, 10):
    kmeans_temp = KMeans(n_clusters=i, random_state=42)
    kmeans_temp.fit_predict(X)
    result.append(kmeans_temp.inertia_)

plt.plot(range(1,10), result, marker='o')

1과 2는 interia 값이 크므로 최적의 개수가 아니고, 2에서 3으로 넘어가면서 줄어들고 있기 때문에 3이 최적의 군집 개수라고 볼 수 있다.

클러스터링 결과 해석

- 데이터 응집도: 클러스터 내의 데이터가 얼마나 가까이 모여 있는지를 분석(가까이 모여있을수록 응집도가 높음)

- 데이터 분리도: 다른 클러스터와 얼마나 잘 분리되어 있는가?(클러스터 간 거리가 멀수록 분리도가 높음)

- 실루엣 점수 : 클러스터의 응집도와 분리도를 동시에 평가할 수 있는 강력한 지표(K-means 품질 판단하는데 유용)

--> 데이터 포인트가 자신의 클러스터와 얼마나 잘 응집되어 있고, 다른 클러스터와 얼마나 잘 분리되어 있는지 나타냄

--> 1에 수렴: 응집도와 분리도가 높음, 0에 수렴: 어느 클러스터에 속했어야 하는지 불확실, 음수: 잘못 속했을 가능성 높음

# 라이브러리 불러오기
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, silhouette_samples

# 전체 데이터의 평균 실루엣 점수
sil_avg = silhouette_score(X, cluster_labels)
print(sil_avg) # 결과: 0.8480303059596955

# 개별 데이터의 실루엣 점수
sil_values = silhouette_samples(X, cluster_labels)
print(sil_values) 
# 결과: 
[0.90593228 0.90295138 0.78292932 0.82801009 0.85347199 0.87164904
 0.87660124 0.87599826 0.87967189 0.85542272 0.8185558  0.87259676
 0.74387596 0.84157115 0.90743902 0.87272287 0.87580064 0.72626456
 0.86269038 0.78265318 0.78367684 0.88236857 0.86744598 0.91367619
 0.87177917 0.84973102 0.88991326 0.69411153 0.86247358 0.84701361
 0.85559028 0.86435444 0.88923506 0.81530708 0.84205606 0.84407722
 .
 .
 .]

# 시각화 시 위치 조정을 위해 변수 선언
y_lower = 10
# 각 클러스터에 대해 반복하며 차트 작성
for i in range(3):
    ith_cluster_silhouette_value = sil_values[cluster_labels == i]
    ith_cluster_silhouette_value.sort()
    size_clust_i = ith_cluster_silhouette_value.shape[0]
    y_upper = y_lower + size_clust_i
	# 클러스터별 막대 그리기
    plt.fill_between(np.arange(y_lower, y_upper), 0, ith_cluster_silhouette_value)
    plt.text(-0.05, y_lower+size_clust_i*0.5, str(i))
	# 다음 클러스터로 이동하기 위해 y_lower 변경
    y_lower = y_upper + 10
    plt.axvline(x=sil_avg, color='red', linestyle='--')

PCA

- 차원 축소: 데이터가 고차원일수록(피처의 개수가 많을수록) 모델을 학습시키거나 분석할 때 여러 제약이 존재함

-> 학습 속도 저하, 과적합, 데이터 희소 등의 문제가 발생

 

- PCA: 고차원 데이터를 저차원으로 축소하면서도 데이터의 중요한 정보를 최대한 보존하는 차원 축소 기법(데이터의 주요 특징을 파악하고, 노이즈를 제거하거나 시각화를 용이하게 함)

 

- 데이터를 선형 변환하여 새로운 축을 생성하는 과정

  가) 주성분: 데이터의 분산을 가장 잘 설명하는 새로운 축(데이터의 분산이 가장 큰 방향을 나타내는 축)

  나) 데이터의 주요 패턴: 데이터의 분산이 가장 큰 방향을 기준으로 데이터를 분석

  다) 축 변경: 기존의 좌표축을 새로운 주성분 축으로 변환  라) 차원 축소: 중요하지 않은 주성분을 제거하여 데이터의 차원을 줄임

 

- 작동 원리: 데이터를 새로운 좌표축으로 변환하여 주요 특징을 유지하면서 차원을 줄이는 데 있음 가) 처음에 여러 차원으로 구성 나) 각 차원의 분산을 측정하고, 분산이 가장 큰 방향을 찾음 다) 분산이 가장 큰 방향으로 데이터를 정렬하여 새로운 축 정의 라) 새로운 축을 기준으로 데이터를 변환하여 적은 차원에서도 데이터를 잘 설명할 수 있도록 처리

 

- 각 피처의 값이 서로 다른 범위를 갖고 있으면 결과에 영향을 미치므로 평균이 0이고 분산이 1인 데이터로 변환(정규화 또는 스케일링)

- 데이터의 분산을 최대화하는 방향을 찾아 새로운 좌표축을 정의하는데 이를 주성분이라고 함, 첫번째 주성분은 데이터의 분산이 가장 큰 방향이며 두번째 주성분은 첫번째 주성분에 수직한 축으로 두번째로 큰 분산을 설명하는 방향이다.

- 데이터의 차원 수와 동일한 수의 주성분이 존재함, 예를 들어 데이터가 4차원이면 4개의 주성분이 있음

 

- 데이터 투영: PCA의 핵심 작업 중 하나로 데이터를 기존의 좌표축 대신 주성분 축으로 변환하는 과정, 투영 후 새로운 축상에서 표현되며 불필요한 차원은 제거된다.

-> 중요한 정보만 유지, 차원 축소, 시각화를 위해 활용됨

# 라이브러리 불러오기
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler

# 1. Iris 데이터셋 로드
iris = load_iris()
X = iris.data # 특성 데이터 (4차원)
y = iris.target # 타깃 데이터 (0, 1, 2의 세 가지 클래스)

# 2. 데이터 정규화 (평균=0, 표준편차=1로 변환)
# - PCA는 데이터의 스케일에 민감하므로 정규화가 필수
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 3. PCA 객체 생성 및 적합
# - n_components=2로 설정하여 데이터를 2차원으로 축소
pca = PCA(n_components=2) # 2개의 주성분으로 축소
X_pca = pca.fit_transform(X_scaled)

# 4. PCA 결과 출력
# - 각 주성분이 데이터의 분산을 얼마나 설명하는지 출력
print("Explained variance ratio:", pca.explained_variance_ratio_)
# 결과: Explained variance ratio: [0.72962445 0.22850762]

# 5. PCA 결과 시각화
# - 두 개의 주성분을 사용해 데이터를 2D 플롯으로 시각화
plt.figure(figsize=(8, 6))
for target, color, label in zip([0, 1, 2], ['red', 'blue', 'green'],
iris.target_names):
    plt.scatter(X_pca[y == target, 0], # 첫 번째 주성분
    X_pca[y == target, 1], # 두 번째 주성분
    color=color, label=label, alpha=0.7)
plt.title('PCA on Iris Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.legend()
plt.grid()
plt.show()

 

오늘은 어제보다 내용이 좀 어려워서 몇번씩 회독하며 이해하려고 노력했다. 아직도 완벽하게 이해되지 않은 부분이 있는데 다른 자료 찾아보면서 익혀나가야겠다.

상기 설명을 좀 요약해서 아래에 다시 작성하겠다.


 

K-means 클러스터링

개념

K-means는 데이터를 비슷한 그룹(클러스터)으로 나누는 알고리즘
절차:

  1. 군집 개수 K를 정함
  2. K개의 중심점(centroid)을 랜덤하게 잡음
  3. 각 데이터를 가장 가까운 중심점에 할당
  4. 각 군집의 중심점을 새로 계산
  5. 3~4 반복, 중심점이 더 이상 변하지 않으면 종료

-> 중심점이 변하지 않거나, 군집 내 오차 제곱합(inertia)이 최소가 될 때 멈춤

from sklearn.cluster import KMeans
import numpy as np

# 예제 데이터
X = np.array([[1,2], [1,4], [1,0], [10,2], [10,4], [10,0]])

# K-means 모델 생성 (클러스터 2개)
kmeans = KMeans(n_clusters=2, random_state=0)
kmeans.fit(X)

# 각 데이터의 클러스터 번호 확인
print(kmeans.labels_)

# 군집 중심점 확인
print(kmeans.cluster_centers_)

-> K값은 엘보우 방법으로 결정함

-> K값이 너무 크면 과적합, 너무 작으면 군집이 잘 안 나눠짐

PCA (Principal Component Analysis)

개념

PCA는 데이터 차원을 줄이는 방법
데이터가 많으면 시각화나 분석이 어려운데, 주성분을 찾아서 중요 정보만 남기는 방식

   - 각 주성분은 데이터 분산이 가장 큰 방법

   - 2~3차원 정도로 줄이면 시각화 가능

from sklearn.decomposition import PCA

# 예제 데이터 (6x4)
X = np.array([[2.5, 2.4, 0.5, 1.2],
              [0.5, 0.7, 1.2, 0.3],
              [2.2, 2.9, 0.7, 1.5],
              [1.9, 2.2, 0.3, 0.9],
              [3.1, 3.0, 1.0, 1.7],
              [2.3, 2.7, 0.6, 1.1]])

# PCA로 2차원으로 차원 축소
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print(X_pca)

-> PCA는 데이터 스케일(정규화)에 민감함

-> 시각화할 때 유용하고, K-means 같은 클러스터링 전에 차원 줄이는데 사용하면 효율적임

 

'보안 & IT 지식 🌺' 카테고리의 다른 글

머신러닝 & 딥러닝  (0) 2026.01.16
머신러닝 & 딥러닝  (1) 2026.01.16
머신러닝 & 딥러닝  (0) 2026.01.13
머신러닝 & 딥러닝  (0) 2026.01.12
머신러닝 & 딥러닝  (0) 2026.01.09