본문 바로가기
공부/정보과학

[예제] 시계열 Data로부터 Mutual Information 구하기

by 죠옹 2018. 8. 18.

 지난번 글에 정보 엔트로피를 공부에 이어, Mutual Information을 구하는 예제를 작성해보고자 한다.



 Mutual Information은 두 확률 변수의 관계를 통해 압축될 수 있는 정보량이다.

 간단히 복습해보자. 확률변수 X, Y가 있을 때 Mutual Information I(X;Y)는 다음과 같다.

Joint Entropy H(X,Y)는 X, Y가 독립일 때 H(X)+H(Y)의 값을 가진다. 고로, Mutual Information은 X, Y가 독립일 때보다 감소한 불확실성을 나타낸다.



 Mutual Information은 확률변수 X와 Y를 엮을 수 있는 모든 상황에서 사용이 가능하다. 그 중 대표적인 것은 시계열 Data이다. 시계열 문제는 "시각 t 에 측정된 측정값 x, y 값의 관계"로 표현할 수 있다. 구하는 방법은 다음과 같다


시계열 Data로부터 Mutual Information 구하는 방법


 시각 t에 해당하는 측정값 x, y를 joint distribution에 맵핑하기 위해 확률변수 X, Y의 영역을 (i x j)행렬로 미리 나눠 놓는다. (이 행렬을 편의상 M이라고 부르겠다)

 

 시각 0 ~ T 에 해당하는 측정값들을 행렬 M의 해당 범위에 차곡차곡 누적 하여 행렬을 완성시킨다. 행렬 M은 분해능 i x j 의 joint distribution에 해당한다.


 Mutual Information의 확률p를 개수 N에 관한 식으로 변환한다. (N: 총 데이터 개수(T))

 

 

 행렬M의 모든 칸에 대해 위 계산을 수행한다. 끝!



 예제



 시각 0~9999의 측정값 X, Y는 독립적이며, 정규분포를 따른다고 가정하자. 이 때 u라는 값을 도입하여 X와 관계를 갖는 변수 Y_new를 만들어보자

 u가 클수록 Y_new는 독립성을 띄고, u가 작을 수록 X와 큰 관계를 가질 것이다. 이를 위의 방법대로 joint distribution을 구한 후, Mutual Information을 구한 결과가 다음과 같다. u가 클 수록 Mutual Information(MI)가 감소하는 것을 볼 수 있다. 또한 Joint distribution이 선형에서 독립관계로 변화해가는 것을 볼 수 있다.


 코드


import matplotlib.pyplot as plt
import numpy as np

X = np.random.randn(10000)
Y = np.random.randn(10000)
fig = plt.figure(figsize=(14, 7))
for cnt in range(10):
""" Random Value 설정 """
V1 = X.copy()
u = 0.1 * cnt
Y_new = (1 - u) * X + u * Y # u가 클수록 Y_new는 X와 독립적인 성질을 나타냄
V2 = Y_new.copy()

q1 = np.linspace(min(V1), max(V1), 51) # min ~ max 까지 50개의 영역 생성
q2 = np.linspace(min(V2), max(V2), 51) # min ~ max 까지 50개의 영역 생성

""" Matrix 생성 """ # 같은 타이밍에 X, Y의 특징에 따라 Matrix M 에 갯수 누적
N = 10000
M = np.zeros((50, 50)) # X, Y 개수를 누적 할 50 x 50 Joint distribution 행렬 생성
for step in range(N):
x = V1[step]
y = V2[step]
for i in range(50):
if (x >= q1[i]) and (x < q1[i+1]):
break
for j in range(50):
if (y >= q2[j]) and (y < q2[j+1]):
break
M[i, j] += 1

""" Mutual Information """
""" MI = p(x,y) * log ( p(x,y) / p(x) / p(y) ) """
""" MI = N_xy / N * log ( N_xy / N_x / N_y * N) """
MI = 0
N = M.sum()
for i in range(M.shape[0]):
for j in range(M.shape[1]):
N_x = M[i].sum()
N_y = M[:, j].sum()
N_xy = M[i, j]
if N_xy != 0:
MI += N_xy / N * np.log(N_xy * N / N_x / N_y)
print(MI)

subplot = fig.add_subplot(2, 5, cnt+1)
plt.imshow(M)
plt.title('u: ' + str(round(u,1)) + ' MI: ' + str(round(MI, 5)))
plt.suptitle('N: 10000 ; X,Y: Gausian distribution ; X vs (1-u)X+uY Mutual Information')
plt.show(block=False)





 기존의 Pearson 상관계수와 같은 Correlation coefficient가 Joint distribution의 선형적 관계를 분석하고, Mutual Information은 Joint distribution의 농도의 집중도(불확실성)을 분석한다. 그래서 선형적이지 않은 Data의 상관관계를 유추하는데 용이하다. 

 예) 절대값


 예) 제곱

 또, 측정 값을 통해 높은 정확도의 Joint distribution을 재현 가능한 Big data에서 이용하기에 유리하다. 상관관계를 정보엔트로피를 통해 정량화 하므로, 여러 상관관계 간의 정량적 비교가 가능하다. 


 허나, Mutual Information은 Correlation coefficient와 마찬가지로 X가 증가하면 Y가 증가한다와 같은 표현이 아니므로, 명확한 상관관계를 목적으로 두는 분석(인과관계 탐색)에는 추천하지 않는다. 또한 Data 수가 적다면 Joint distribution을 제대로 구현하기 힘들기 때문에 실제로 Mutual Information을 구하고 나서도 그 해석의 신빙성을 입증하기 곤란하다.


반응형

댓글