Non-Identifiability는 Model Parameter를 고유하게 식별할 수 없는 현상입니다.

Non-Identifiability는 Model Parameter를 고유하게 식별할 수 없는 현상입니다.
Photo by Diane Picchiottino / Unsplash

Non Identifiability

  • Non-Identifiability는 주어진 데이터와 모델에 대해 특정 파라미터를 고유하게 식별할 수 없는 상황을 의미합니다. 즉, 여러 파라미터 값들이 동일한 데이터를 생성할 수 있으며, 이로 인해 특정 파라미터 값을 확정적으로 추정하기 어렵게 됩니다.
  • 베이지안 추론에서 Non-Identifiability는 사후 분포가 특정 파라미터 값에 대해 명확하게 수렴하지 않고, 여러 값들에 대해 비슷한 확률을 할당하게 되는 경우에 발생합니다. 이는 모델의 복잡성이나 데이터의 부족으로 인해 생길 수 있습니다.

발생원인

  1. 모델의 복잡성: 너무 많은 파라미터를 포함한 모델은 파라미터 간의 상호작용이 복잡해져, 파라미터 간 구분이 어려워질 수 있습니다. 특히 상호 상관관계가 높은 파라미터가 있을 경우 Non-Identifiability가 자주 발생합니다
  2. 데이터의 부족: 충분한 데이터를 확보하지 못한 경우, 데이터만으로는 특정 파라미터를 고유하게 식별하기 어려울 수 있습니다. 데이터가 부족할수록 사후 분포가 불확실해지며, 여러 파라미터 값들이 비슷한 확률을 가질 수 있습니다.
  3. 잘못된 사전 분포: 비현실적인 사전 분포를 사용하거나, 사전 분포가 너무 넓게 설정된 경우 Non-Identifiability 문제가 발생할 수 있습니다. 이 경우, 데이터에 기반한 사후 분포가 명확히 특정 파라미터 값을 제시하지 못합니다.

왜 문제가 되는가?

  1. 모델 불확실성 증가: 파라미터 값이 고유하게 식별되지 않으면, 사후 분포는 여러 파라미터 값에 대해 높은 확률을 할당하게 되어 모델의 불확실성이 증가합니다. 이는 모델 예측의 신뢰도를 떨어뜨리게 됩니다.
  2. 해석의 어려움: 파라미터 간의 상호작용이 복잡해지면, 모델 결과를 해석하는 데 어려움이 발생할 수 있습니다. 파라미터들이 서로 영향을 주고받는 경우, 각 파라미터가 실제로 어떤 역할을 하는지 명확히 알기 어렵습니다.
  3. 추론의 비효율성: Non-Identifiability 문제는 베이지안 추론의 수렴을 더디게 만들고, 계산 비용을 증가시킬 수 있습니다. 파라미터 공간에서 확률이 균등하게 분포된 경우, MCMC(Markov Chain Monte Carlo) 알고리즘은 수렴하기 어려워질 수 있습니다.

대안

  1. 모델 단순화: 모델의 복잡성을 줄이는 것이 첫 번째 해결책입니다. 파라미터 수를 줄이거나, 상관관계가 높은 파라미터들을 통합하여 모델을 간소화하면 Non-Identifiability 문제를 완화할 수 있습니다.
  2. 추가 데이터 수집: 데이터가 부족한 경우, 더 많은 데이터를 수집함으로써 파라미터를 고유하게 식별할 수 있습니다. 데이터가 많아질수록 파라미터 간의 구분이 명확해지며, 사후 분포가 특정 파라미터 값에 집중될 가능성이 높아집니다.
  3. 사전 정보 강화: 적절한 사전 분포를 설정하는 것도 중요한 해결책입니다. 사전 지식이나 외부 정보를 활용하여 더 구체적인 사전 분포를 설정하면, Non-Identifiability 문제를 줄일 수 있습니다.
  4. 식별 가능한 파라미터 변환: 모델에서 식별이 어려운 파라미터를 식별 가능하게 변환하는 것도 한 가지 방법입니다. 예를 들어, 로그 변환이나 비율로 변환하면 파라미터 간의 구분이 명확해질 수 있습니다.

코드

  • 기울기와 절편 간 상관관계가 존재하면, 사후 분포에서 기울기가 커질수록 절편이 작아지는 등의 관계가 보일 수 있습니다. 이는 파라미터가 서로를 보정하는 형태로 나타나므로, Non-Identifiability 문제가 발생하는 것입니다.
  • pm.plot_posterior()에서 볼 수 있듯이 기울기와 절편이 특정한 값으로 집중되지 않고, 여러 값에 대해 비슷한 확률을 가진다면 Non-Identifiability가 발생한 것입니다. 이는 파라미터의 고유한 값을 결정하기 어렵다는 의미입니다.
import numpy as np  
import pymc as pm  
import matplotlib.pyplot as plt  
  
# 데이터 생성 (노이즈가 있는 선형 모델)  
np.random.seed(42)  
n = 100  
x = np.linspace(0, 10, n)  
true_slope = 2  
true_intercept = 1  
y = true_slope * x + true_intercept + np.random.normal(0, 1, n)  
  
# 베이지안 모델 정의  
with pm.Model() as model:  
    slope = pm.Normal('slope', mu=0, sigma=10)  
    intercept = pm.Normal('intercept', mu=0, sigma=10)  
    sigma = pm.HalfNormal('sigma', sigma=1)  
  
    # 선형 모델  
    mu = slope * x + intercept  
      
    # 관측 데이터  
    y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed=y)  
      
    # MCMC 샘플링  
    trace = pm.sample(1000, return_inferencedata=True)  
  
# 사후 분포 시각화  
pm.plot_posterior(trace, var_names=['slope', 'intercept'])  
plt.show()

  • Trace Plot: MCMC(Markov Chain Monte Carlo) 추정에서 Trace Plot을 보면, 각 파라미터의 샘플 값이 얼마나 수렴하고 있는지 시각적으로 확인할 수 있습니다. 만약 Non-Identifiability가 발생하면, 특정 파라미터 값이 명확하게 수렴하지 않고 다양한 값에 걸쳐 변동할 수 있습니다.
    • Trace Plot이 안정적으로 수렴하지 않으면 Non-Identifiability 가능성이 있습니다.
  • 정량적 기준: **Gelman-Rubin 통계량 (R-hat)**을 사용하여, 파라미터의 샘플링이 잘 수렴했는지 확인할 수 있습니다. R-hat 값이 1에 가까울수록 수렴이 잘 된 것이며, 값이 크면 수렴이 불완전하고 Non-Identifiability 문제가 있을 수 있습니다.
    • R-hat 값이 1에 가까우면 수렴이 잘 된 것이고, 그렇지 않으면 Non-Identifiability의 가능성을 고려할 수 있습니다.
# Trace plot  
pm.plot_trace(trace)  
plt.show()  
  
# R-hat 통계량 계산  
print(pm.rhat(trace))

  • 파라미터들이 서로 상호작용하여 상관관계가 매우 높으면 Non-Identifiability가 발생할 가능성이 큽니다. 예를 들어, 기울기(slope)와 절편(intercept) 같은 파라미터는 서로 보완하는 관계에 있을 때 식별이 어렵습니다.
  • 파라미터 간 상관관계를 측정하여 Non-Identifiability의 가능성을 확인할 수 있습니다. 상관계수가 1에 가까울수록 두 파라미터가 매우 밀접하게 연관되어 있으며, 독립적으로 식별하기 어렵다는 신호입니다.
    • 정량적 기준: 상관계수가 0.9 이상일 경우 Non-Identifiability가 발생할 가능성이 높습니다.
  • 쌍대 시각화는 여러 파라미터 간의 상관관계를 시각적으로 파악하는 데 유용합니다. 두 파라미터가 함께 움직이면서 동일한 형태의 데이터를 생성할 수 있는 경우, Non-Identifiability가 발생할 가능성이 큽니다.
import seaborn as sns  
import pandas as pd  
  
# 사후 분포에서 파라미터 값을 추출하는 방법  
posterior = trace.posterior  
  
# slope와 intercept 추출  
slope_values = posterior['slope'].values.flatten()  
intercept_values = posterior['intercept'].values.flatten()  
  
# 파라미터 값을 DataFrame으로 변환  
params = pd.DataFrame({'slope': slope_values, 'intercept': intercept_values})  
  
# 쌍대 시각화 (Pair Plot)sns.pairplot(params)  
plt.show()  
  
# 상관계수 계산  
correlation = params.corr()  
print(correlation)