Notice
Recent Posts
Recent Comments
Link
헬창 개발자
em클러스터링 본문
EM 클러스터링: 이론과 실습
1. EM 클러스터링이란?
EM 클러스터링은 통계적 기법 중 하나로, 데이터의 숨겨진 구조를 찾기 위해 사용하는 알고리즘입니다. EM(Expectation-Maximization) 알고리즘은 데이터가 숨겨진 잠재 변수를 가지고 있을 때 그 변수들을 추정하고, 이를 통해 데이터의 클러스터를 식별합니다.
2. 기본 개념
- Expectation (E-단계): 현재의 파라미터를 기반으로 데이터의 잠재 변수(또는 클러스터의 분포)를 추정합니다. 이 단계에서는 현재의 파라미터 추정을 사용하여 각 데이터 포인트가 각 클러스터에 속할 확률을 계산합니다.
- Maximization (M-단계): E-단계에서 계산된 확률을 사용하여 모델의 파라미터를 업데이트합니다. 즉, 데이터 포인트가 각 클러스터에 속할 확률을 최대화하는 방향으로 파라미터를 조정합니다.
이 과정은 수렴할 때까지 반복되며, 최종적으로 클러스터의 경계와 중심을 결정합니다.
3. 알고리즘 설명
- 초기화: 클러스터의 초기 중심을 설정합니다.
- E-단계: 각 데이터 포인트가 각 클러스터에 속할 확률을 계산합니다.
- M-단계: 클러스터의 중심을 업데이트하여 최대화합니다.
- 반복: E-단계와 M-단계를 반복하여 알고리즘이 수렴할 때까지 진행합니다.
4. 소스코드
import numpy as np
import math
from scipy.stats import norm
class EMClustering:
def __init__(self):
# 파라미터 초기화
self.weight = 0.2 # 가중치
self.means = np.array([30, 20]) # 평균
self.bias = np.array([4, 3]) # 표준편차
# 정규 분포를 통한 입력 데이터 생성, k=2
self.c1 = np.random.normal(7, 3, size = 10) # 평균 7, 표준편차 3, 데이터 개수 10
self.c2 = np.random.normal(20, 3, size = 10) # 평균 20, 표준편차 3, 데이터 개수 10
self.x = np.append(self.c1, self.c2) # 입력 데이터 생성
print("초기 클러스터 파라미터")
print("c1 클러스터\t", "가중치:", self.weight, " 평균:", self.means[0], " 표준편차:", self.bias[0])
print(np.round(self.c1, 2))
print("c2 클러스터\t", "가중치:", 1-self.weight, " 평균:", self.means[1], " 표준편차:", self.bias[1])
print(np.round(self.c2, 2))
print('--'*40)
def E_step(self): # E-step: xi의 기대값 P(C_j|X_i) 계산
expected_values = [[] for _ in range(2)] # 2개의 클러스터 기대값 저장할 리스트 생성
for xi in self.x: # 입력 데이터를 순차적으로 xi에 반환
N1 = norm(loc = self.means[0], scale = self.bias[0]) # 평균=30, 표준편차=4인 정규 분포 객체 생성
N2 = norm(loc = self.means[1], scale = self.bias[1]) # 평균=20, 표준편차=3인 정규 분포 객체 생성
wp1 = self.weight * N1.pdf(xi) # 가중치 * n1객체의 확률밀도함수
wp2 = (1-self.weight) * N2.pdf(xi) # 가중치(가중치의 합은 1) * n2객체의 확률밀도함수
den = wp1 + wp2 # 분모
c1 = wp1 / den # P(C_1|x_i)의 값
c2 = wp2 / den # P(C_2|x_i)의 값
expected_values[0].append(c1) # c1 기대값 추가
expected_values[1].append(c2) # c2 기대값 추가
return expected_values # 기대값 리스트 반환
def M_step(self, expected_value): # M-step: 클러스터 가중치, 클러스터의 평균과 표준편차 업데이트
for j in range(2):
# 클러스터의 가중치 업데이트
self.weight = 1 / len(expected_value[j]) * sum(expected_value[j]) # 1/n * sum(P(C_j|x_i))
# 클러스터의 정규분포 평균 업데이트
self.means[j] = np.sum(self.x * expected_value[j])/np.sum(expected_value[j]) # sum(x_i * P(C_j|x_i)) / sum(P(C_j|x_i))
# 클러스터의 정규분포 표준편차 업데이트
self.bias[j] = math.sqrt(np.sum((self.x - self.means[j])**2 * expected_value[j]) / np.sum(expected_value[j])) # sum((x_i - 평균)^2 * sum(P(C_j|x_i)) / sum(P(C_j|x_i))
def result(self): # 출력 함수
print("10번째 클러스터 파라미터")
print("c1 클러스터\t", "가중치:", self.weight, " 평균:", self.means[0], " 표준편차:", self.bias[0])
print(np.round(self.c1, 2))
print("c2 클러스터\t", "가중치:", 1-self.weight, " 평균:", self.means[1], " 표준편차:", self.bias[1])
print(np.round(self.c2, 2))
def run(self): # 실행 함수
for _ in range(10):
# E-step
exp = self.E_step()
# M -step
self.M_step(exp)
self.result()
if __name__=='__main__':
aaaaaaaaa = EMClustering()
aaaaaaaaa.run()
'데이터 분석' 카테고리의 다른 글
밀도기반 클러스터링 DBSCAN [파이썬] (0) | 2022.05.01 |
---|---|
7. 시계열 데이터를 다뤄보자 (0) | 2022.04.27 |
KNN 최근접 이웃 [파이썬] (0) | 2022.04.23 |
코사인 유사도, 코사인 거리 구현[파이썬] (0) | 2022.04.23 |
자카드 유사도, 거리 [파이썬] (0) | 2022.04.23 |
Comments