1 왜 로그정규 분포인가
데이터 과학에서 가장 흔히 마주치는 분포 중 하나가 로그정규 분포(log-normal distribution)이다. 로그를 취하면 정규 분포가 되는 양의 실수 분포로, 다음 세 상황에서 자연스럽게 등장한다.
- 곱셈적 성장: 소득, 주식 가격, 세균 집락 크기처럼 “일정 비율로” 변동하는 양은 로그정규를 따르는 경향이 있다. 정규 분포가 덧셈의 극한이라면, 로그정규 분포는 곱셈의 극한이다.
- 양의 데이터 + 우편향: \(X > 0\) 이고 분포가 오른쪽으로 길게 늘어진 형태라면 로그정규 적합이 우선 후보가 된다. 정규 분포를 직접 적용하면 음수 예측이 발생하는 문제를 피할 수 있다.
- 정규 이론의 활용: \(\log X \sim N(\mu, \sigma^2)\) 이므로 \(\log X\) 에 대해 정규 이론(MLE, 신뢰구간, 검정)을 그대로 적용할 수 있다.
2 정의
확률변수 \(X > 0\) 가 \(\log X \sim N(\mu, \sigma^2)\) 이면 \(X \sim \text{LogNormal}(\mu, \sigma^2)\).
PDF는 \(Y = \log X\) 의 변수변환(야코비안 \(|dx/dy| = e^y = x\))으로 유도된다:
\[ f(x \mid \mu, \sigma^2) = \frac{1}{\sqrt{2\pi}\,\sigma\, x} \exp\!\left(-\frac{(\log x - \mu)^2}{2\sigma^2}\right), \quad x > 0 \]
- \(\mu \in \mathbb{R}\): 로그 척도 위치 모수 (\(\log X\) 의 평균)
- \(\sigma^2 > 0\): 로그 척도 분산 모수 (\(\log X\) 의 분산)
주의: \(\mu\) 와 \(\sigma^2\) 은 \(X\) 의 평균·분산이 아니다. 이들은 \(\log X\) 의 평균·분산이다.
정규화 검증: \(Y = \log X\) 로 변환하면 \(Y \sim N(\mu, \sigma^2)\) 이고 \(\int_0^\infty f_X(x)\, dx = \int_{-\infty}^\infty f_Y(y)\, dy = 1\).
\(Y = \log X\) 변수변환에서 야코비안은 \(|dy/dx| = 1/x\) 이다. 따라서 \(f_X(x) = f_Y(\log x) \cdot |dy/dx| = f_Y(\log x) / x\) 이다. 분모의 \(x\) 가 바로 이 야코비안이다.
직관적으로: 로그 척도에서 같은 간격(예: \(\log x\) 가 1 증가)이 원래 척도에서는 매우 다른 간격에 대응된다. \(x\) 가 작은 영역에서는 \(\log x\) 의 변화에 따른 \(x\) 의 변화량이 작아 밀도가 압축되어 높아진다. 분모의 \(x\) 가 이 압축을 교정하여 전체 적분이 1이 되게 한다.
분모에 \(x\) 가 없으면 (\(x = 0\) 근방에서 정규 PDF를 그대로 쓰면) \(x \to 0^+\) 에서 밀도가 폭발하여 적분이 발산한다. \(x\) 항이 이 발산을 막는 감쇠 역할을 한다.
3 적률 — 정규 MGF 활용
로그정규 분포의 적률은 \(Y = \log X \sim N(\mu, \sigma^2)\) 임을 이용하면 적분 없이 우아하게 구한다 (Casella & Berger, 2002, Ch.3.3).
\[ E[X^n] = E[e^{nY}] = M_Y(n) = e^{n\mu + n^2\sigma^2/2} \]
여기서 \(M_Y(t) = e^{\mu t + \sigma^2 t^2/2}\) 는 \(N(\mu, \sigma^2)\) 의 MGF이다.
\(X = e^Y\) 이므로 \(X^n = (e^Y)^n = e^{nY}\) 이다. \(n\) 차 적률 \(E[X^n]\) 은 곧 \(Y\) 의 적률생성함수(MGF) \(M_Y(t)\) 를 \(t = n\) 에서 평가한 값이다.
이 트릭의 핵심은 \(X\) 의 적률 계산을 \(Y\) 의 MGF 평가로 변환한다는 점이다. \(Y \sim N(\mu, \sigma^2)\) 의 MGF \(e^{\mu t + \sigma^2 t^2/2}\) 는 닫힌 형식이 알려져 있으므로, 복잡한 적분 없이 \(t = n\) 을 대입하면 \(n\) 차 적률이 바로 나온다.
만약 \(Y\) 의 MGF가 없었다면 (예: \(Y\) 가 코시 분포라면) 이 트릭을 쓸 수 없다. 로그정규 분포가 정규 이론의 자산을 그대로 활용할 수 있는 이유가 바로 이 \(\log\) 변환과 MGF 트릭이다.
\(n=1\) (평균):
\[ E[X] = e^{\mu + \sigma^2/2} \]
\(e^x\) 는 볼록(convex) 함수이므로 Jensen 부등식에 의해 \(E[e^Y] \geq e^{E[Y]} = e^\mu\) 이다. 즉 평균은 항상 중앙값 \(e^\mu\) 보다 크다.
\(\sigma^2/2\) 의 추가 항은 이 볼록성에 의한 “위쪽 편향”의 정확한 크기이다. \(\sigma^2\) 이 클수록 분포가 넓게 퍼지고 우편향이 심해진다. \(\sigma^2 = 0\) 이면 \(X\) 가 상수 \(e^\mu\) 가 되므로 평균 = 중앙값이다.
소득 예시: \(\mu = 10.5\), \(\sigma = 0.8\) 이면 중앙값은 \(e^{10.5} \approx 3{,}631\) 만원이지만 평균은 \(e^{10.5 + 0.32} \approx 5{,}101\) 만원이다. 소수의 고소득자가 평균을 끌어올리는 구조이다. “평균 소득이 중앙값보다 높다”는 현실의 소득 통계를 로그정규 분포가 자연스럽게 포착한다.
\(n=2\):
\[ E[X^2] = e^{2\mu + 2\sigma^2} \]
분산:
\[ \text{Var}(X) = E[X^2] - (E[X])^2 = e^{2\mu + 2\sigma^2} - e^{2\mu + \sigma^2} = e^{2\mu + \sigma^2}(e^{\sigma^2} - 1) \]
\(e^{2\mu+\sigma^2}\) 은 평균의 제곱 \((E[X])^2 = (e^{\mu+\sigma^2/2})^2 = e^{2\mu+\sigma^2}\) 과 같다.
\((e^{\sigma^2}-1)\) 항은 “상대 변동성”이다. 변동계수(CV)의 제곱 \(= \text{Var}(X)/(E[X])^2 = e^{\sigma^2}-1\) 이다. \(\sigma^2\) 이 작으면 \(e^{\sigma^2}-1 \approx \sigma^2\) 으로 근사되어, 로그 척도의 분산이 원래 척도의 상대 분산(CV\(^2\))과 근사적으로 같다.
\(\sigma^2 = 1\) 이면 CV \(= \sqrt{e-1} \approx 1.31\) 이다. 즉 표준편차가 평균의 131%로, 매우 큰 분산이다. \(\sigma^2\) 이 클수록 분포의 꼬리가 두꺼워지고 극단값이 자주 발생하며, 분산이 폭발적으로 증가한다.
최빈값(mode):
\[ \text{mode}(X) = e^{\mu - \sigma^2} \]
중앙값(median):
\[ \text{median}(X) = e^{\mu} \]
로그정규 분포는 오른쪽으로 치우쳐 있어 세 대표값의 순서가 다음과 같다:
\[ \text{mode} < \text{median} < \text{mean} \]
\[ e^{\mu - \sigma^2} < e^{\mu} < e^{\mu + \sigma^2/2} \]
\(\sigma^2\) 이 클수록 이 세 값의 차이가 커지고 분포의 우편향이 심해진다.
성질 요약:
| 성질 | 값 |
|---|---|
| 지지 | \((0, \infty)\) |
| 모수 | \(\mu \in \mathbb{R}\), \(\sigma^2 > 0\) |
| \(E[X]\) | \(e^{\mu + \sigma^2/2}\) |
| \(\text{Var}(X)\) | \(e^{2\mu + \sigma^2}(e^{\sigma^2} - 1)\) |
| 중앙값 | \(e^\mu\) |
| 최빈값 | \(e^{\mu - \sigma^2}\) |
| MGF | 미존재 |
| 특성함수 | 존재 (닫힌 형식 없음) |
| 지수족 여부 | 아니오 |
MGF 미존재 이유: \(E[e^{tX}] = E[e^{t e^Y}]\) 인데 \(e^{tY}\) 의 적분과 달리 \(e^{te^Y}\) 는 \(t > 0\) 일 때 발산한다.
4 분포 형태와 모수의 역할
로그정규 분포의 형태는 \(\sigma^2\) 에 의해 주로 결정된다.
| \(\sigma^2\) | 형태 | 편향 |
|---|---|---|
| 작음 (\(\sigma^2 \ll 1\)) | 거의 대칭, 종 모양 | 약한 우편향 |
| 중간 (\(\sigma^2 \approx 1\)) | 명확한 우편향, 두꺼운 오른쪽 꼬리 | 중간 |
| 큼 (\(\sigma^2 \gg 1\)) | 매우 강한 우편향, 거의 모든 질량이 왼쪽 | 강한 우편향 |
\(\mu\) 는 분포를 스케일 축으로 이동시킨다. \(e^\mu\) 가 중앙값이므로, \(\mu\) 가 클수록 분포 전체가 오른쪽으로 이동한다.
5 곱셈 중심극한정리 (Multiplicative CLT)
\(X_1, \ldots, X_n \overset{\text{iid}}{\sim} F\) (단, \(E[\log X_i] = \mu\), \(\text{Var}(\log X_i) = \sigma^2 < \infty\))이면:
\[ \left(\prod_{i=1}^n X_i\right)^{1/n} \xrightarrow{d} \text{LogNormal}(\mu, \sigma^2/n) \quad \text{as } n \to \infty \]
더 정확하게는, \(\log\) 를 취한 형태에서 CLT가 작동한다:
\[ \frac{\frac{1}{n}\sum_{i=1}^n \log X_i - \mu}{\sigma/\sqrt{n}} \xrightarrow{d} N(0,1) \]
해석: 많은 독립 요인들의 곱으로 결정되는 양은 자연스럽게 로그정규를 따른다.
- 소득: 기본 임금 × 연봉 상승률₁ × 연봉 상승률₂ × … (비율의 곱)
- 세균 수: 초기 개체수 × 세대별 증식률₁ × 증식률₂ × …
- 주가: 초기 가격 × 일별 수익률₁ × 일별 수익률₂ × …
각 요인이 독립적이고 충분히 많다면, 그 곱은 로그정규로 수렴한다.
6 정규 분포와의 변환 관계
로그정규와 정규 분포는 지수 함수 \(x = e^y\) 로 연결된다:
\[ X \sim \text{LogNormal}(\mu, \sigma^2) \iff \log X \sim N(\mu, \sigma^2) \]
이 관계를 활용하면: - 확률 계산: \(P(X \leq x) = P(\log X \leq \log x) = \Phi\!\left(\dfrac{\log x - \mu}{\sigma}\right)\) - 분위수: \(Q_X(p) = e^{\mu + \sigma \cdot z_p}\), 여기서 \(z_p = \Phi^{-1}(p)\) - 추정: \(\hat\mu = \overline{\log x_i}\), \(\hat\sigma^2 = \frac{1}{n}\sum(\log x_i - \hat\mu)^2\) (MLE)
7 실무에서의 로그 변환 판단
로그정규 가정의 적절성을 판단하는 실용적 체크리스트:
| 체크 | 질문 |
|---|---|
| 지지 | \(X > 0\) 인가? |
| 분포 형태 | 히스토그램이 우편향인가? |
| 로그 변환 | \(\log X\) 의 히스토그램이 대칭 종 모양인가? |
| Q-Q 플롯 | \(\log X\) 의 정규 Q-Q 플롯이 직선인가? |
| Shapiro-Wilk | \(\log X\) 에 대한 정규성 검정이 통과하는가? |
하나라도 실패하면 로그정규 외에 감마 분포, 와이블 분포, 파레토 분포도 고려한다.
8 코드 예시
8.1 Step 1: 순수 Python — PDF 직접 계산과 적률 검증
import math
def lognormal_pdf(x, mu=0, sigma=1):
"""LogNormal(μ, σ²) PDF"""
if x <= 0:
return 0.0
return math.exp(-0.5 * ((math.log(x) - mu) / sigma) ** 2) / \
(math.sqrt(2 * math.pi) * sigma * x)
def lognormal_mean(mu, sigma):
return math.exp(mu + sigma**2 / 2)
def lognormal_var(mu, sigma):
return math.exp(2*mu + sigma**2) * (math.exp(sigma**2) - 1)
def lognormal_median(mu, sigma):
return math.exp(mu)
def lognormal_mode(mu, sigma):
return math.exp(mu - sigma**2)
# 정규화 검증 (수치 적분)
def integrate_pdf(mu=0, sigma=1, n=100_000, x_max=50):
dx = x_max / n
return sum(lognormal_pdf(i * dx + dx/2, mu, sigma) * dx for i in range(n))
print("=== PDF 정규화 검증 ===")
for mu, sig in [(0, 0.5), (1, 1), (0, 1.5)]:
area = integrate_pdf(mu, sig)
print(f"LogNormal(μ={mu}, σ={sig}): ∫f dx ≈ {area:.6f}")
# 적률 검증
print("\n=== 적률 공식 검증 ===")
print(f"{'(μ, σ)':>12} | {'E[X] 이론':>10} | {'Var 이론':>12} | {'median 이론':>12} | {'mode 이론':>10}")
print("-" * 65)
for mu, sig in [(0, 0.5), (0, 1), (1, 0.5)]:
m = lognormal_mean(mu, sig)
v = lognormal_var(mu, sig)
med = lognormal_median(mu, sig)
mod = lognormal_mode(mu, sig)
print(f"({mu:4.1f}, {sig:4.1f}) | {m:>10.4f} | {v:>12.4f} | {med:>12.4f} | {mod:>10.4f}")
# mode < median < mean 확인
print("\n=== mode < median < mean 순서 확인 ===")
for mu, sig in [(0, 0.5), (0, 1.0), (0, 1.5)]:
mod = lognormal_mode(mu, sig)
med = lognormal_median(mu, sig)
m = lognormal_mean(mu, sig)
print(f"σ={sig}: mode={mod:.4f} < median={med:.4f} < mean={m:.4f} "
f"| 차이 배율: {m/med:.3f}x")=== PDF 정규화 검증 ===
LogNormal(μ=0, σ=0.5): ∫f dx ≈ 0.999997
LogNormal(μ=1, σ=1): ∫f dx ≈ 0.999994
LogNormal(μ=0, σ=1.5): ∫f dx ≈ 0.999983
=== 적률 공식 검증 ===
(μ, σ) | E[X] 이론 | Var 이론 | median 이론 | mode 이론
-----------------------------------------------------------------
( 0.0, 0.5) | 1.1331 | 0.3624 | 1.0000 | 0.7788
( 0.0, 1.0) | 1.6487 | 4.6708 | 1.0000 | 0.3679
( 1.0, 0.5) | 3.0802 | 2.6793 | 2.7183 | 2.1170
=== mode < median < mean 순서 확인 ===
σ=0.5: mode=0.7788 < median=1.0000 < mean=1.1331 | 차이 배율: 1.133x
σ=1.0: mode=0.3679 < median=1.0000 < mean=1.6487 | 차이 배율: 1.649x
σ=1.5: mode=0.1054 < median=1.0000 < mean=3.0802 | 차이 배율: 3.080x
8.2 Step 2: scipy.stats — 로그정규 적합과 곱셈 CLT 검증
import numpy as np
from scipy import stats
np.random.seed(42)
N = 100_000
# ── 확률 계산: 정규 CDF 활용 ─────────────────────────────────────
mu, sigma = 10.5, 0.8 # log-scale 모수 (소득 예시: 단위 만원)
dist = stats.lognorm(s=sigma, scale=np.exp(mu))
mean_X = dist.mean()
median_X = dist.median()
p80 = dist.ppf(0.80) # 80번째 백분위수
prob_above = 1 - dist.cdf(np.exp(10.5 + 1.28 * 0.8)) # 상위 10%
print("=== 소득 분포 (LogNormal) 분석 ===")
print(f"모수: μ={mu}, σ={sigma}")
print(f"평균 소득: {mean_X/10000:.0f}만원")
print(f"중앙값 소득: {median_X/10000:.0f}만원")
print(f"80번째 백분위수: {p80/10000:.0f}만원")
print(f"평균/중앙값 비율: {mean_X/median_X:.3f} (우편향 지표)")
# ── 곱셈 CLT 검증 ─────────────────────────────────────────────
print(f"\n=== 곱셈 CLT: 독립 요인 곱의 수렴 ===")
true_mu, true_sig = 0.1, 0.3 # 각 요인의 log-scale 모수
for n in [5, 20, 100, 500]:
# n개 독립 로그정규 요인의 기하 평균 (곱의 n제곱근)
log_factors = np.random.normal(true_mu, true_sig, (N, n))
log_product_mean = log_factors.mean(axis=1) # 로그 합의 평균
# CLT: log_product_mean ~ N(μ, σ²/n)
mu_hat = np.mean(log_product_mean)
sigma_hat = np.std(log_product_mean)
sigma_theory = true_sig / np.sqrt(n)
print(f"n={n:3d}: E[log-gm]={mu_hat:.4f}(이론:{true_mu:.4f}), "
f"std={sigma_hat:.4f}(이론:{sigma_theory:.4f})")
# ── 로그정규 MLE 추정 ─────────────────────────────────────────
print(f"\n=== MLE 추정: log-변환 후 정규 MLE 적용 ===")
true_mu2, true_sig2 = 2.5, 0.6
data = stats.lognorm.rvs(s=true_sig2, scale=np.exp(true_mu2), size=500, random_state=1)
log_data = np.log(data)
mu_mle = log_data.mean()
sigma_mle = log_data.std(ddof=0) # MLE (n 나눔)
sigma_unb = log_data.std(ddof=1) # 비편향 추정 (n-1 나눔)
print(f"진짜 모수: μ={true_mu2}, σ={true_sig2}")
print(f"MLE: μ̂={mu_mle:.4f}, σ̂_MLE={sigma_mle:.4f} (n 나눔)")
print(f"비편향: σ̂_unb={sigma_unb:.4f} (n-1 나눔)")
# ── Gamma vs LogNormal 비교 적합 ────────────────────────────────
print(f"\n=== Gamma vs LogNormal 비교 적합 ===")
income_data = stats.lognorm.rvs(s=0.8, scale=np.exp(10.5), size=1000, random_state=5)
# LogNormal fit (로그 변환 후 정규 MLE)
log_inc = np.log(income_data)
mu_fit = log_inc.mean()
sig_fit = log_inc.std(ddof=1)
ks_ln, p_ln = stats.kstest(income_data, 'lognorm', args=(sig_fit, 0, np.exp(mu_fit)))
# Gamma fit
a_fit, loc_fit, scale_fit = stats.gamma.fit(income_data, floc=0)
ks_g, p_g = stats.kstest(income_data, 'gamma', args=(a_fit, loc_fit, scale_fit))
print(f"LogNormal KS p-value = {p_ln:.4f} {'(합격)' if p_ln>0.05 else '(기각)'}")
print(f"Gamma KS p-value = {p_g:.4f} {'(합격)' if p_g>0.05 else '(기각)'}")=== 소득 분포 (LogNormal) 분석 ===
모수: μ=10.5, σ=0.8
평균 소득: 5101만원
중앙값 소득: 3631만원
80번째 백분위수: 6064만원
평균/중앙값 비율: 1.405 (우편향 지표)
=== 곱셈 CLT: 독립 요인 곱의 수렴 ===
n= 5: E[log-gm]=0.1000(이론:0.1000), std=0.1342(이론:0.1342)
n= 20: E[log-gm]=0.0999(이론:0.1000), std=0.0671(이론:0.0671)
n=100: E[log-gm]=0.1001(이론:0.1000), std=0.0300(이론:0.0300)
n=500: E[log-gm]=0.1000(이론:0.1000), std=0.0134(이론:0.0134)
=== MLE 추정: log-변환 후 정규 MLE 적용 ===
진짜 모수: μ=2.5, σ=0.6
MLE: μ̂=2.4984, σ̂_MLE=0.5945 (n 나눔)
비편향: σ̂_unb=0.5951 (n-1 나눔)
=== Gamma vs LogNormal 비교 적합 ===
LogNormal KS p-value = 0.7831 (합격)
Gamma KS p-value = 0.0923 (합격)
9 로그정규 vs 감마 분포 — 실무 선택 기준
두 분포 모두 \((0, \infty)\) 위에 정의되고 우편향 형태를 가진다. 선택 기준:
| 기준 | 로그정규 | 감마 |
|---|---|---|
| 생성 메커니즘 | 곱셈적 과정 | 덧셈적 사건 대기 |
| 꼬리 두께 | 감마보다 두꺼운 편 | 지수적 꼬리 |
| 해석 편의 | 로그 변환 후 정규 이론 | 모수(형상·척도) 직관적 |
| MGF | 미존재 | 존재 |
| 응용 | 소득, 주가, 오염 물질 농도 | 대기 시간, 수명, 강수량 |
10 응용 분야
| 분야 | 활용 | 구체적 예시 |
|---|---|---|
| 경제학 | 소득·재산 분포 | 개인소득의 우편향 분포 |
| 금융 | 주가 모델 (Black-Scholes) | 로그 수익률 정규 가정 → 주가 로그정규 |
| 역학 | 병원체 농도 | 식품 중 세균 수, 공기 중 오염물질 |
| 의학 | 생체 측정값 | 혈중 약물 농도, 항체 역가 |
| 환경 | 오염물질 | 토양 오염물질 농도 분포 |
| 신뢰성 | 수명 분포 | 전자 부품 수명 (로그가 정규를 따를 때) |
| 딥러닝 | 가중치 초기화 | 로그정규 분포 기반 초기화 연구 |
11 성질 요약
| 성질 | 값 |
|---|---|
| 지지 | \((0, \infty)\) |
| 모수 | \(\mu \in \mathbb{R}\) (log 위치), \(\sigma^2 > 0\) (log 분산) |
| \(E[X]\) | \(e^{\mu + \sigma^2/2}\) |
| \(\text{Var}(X)\) | \(e^{2\mu + \sigma^2}(e^{\sigma^2} - 1)\) |
| 중앙값 | \(e^\mu\) |
| 최빈값 | \(e^{\mu - \sigma^2}\) |
| CDF | \(\Phi\!\left(\dfrac{\log x - \mu}{\sigma}\right)\) |
| MGF | 미존재 |
| 지수족 여부 | 아니오 |
| 핵심 관계 | \(\log X \sim N(\mu, \sigma^2)\) |
12 관련 주제
선행 지식
- 정규 분포 (Normal Distribution) — 로그정규는 정규의 지수 변환
- 확률변수 함수의 분포 — 변수변환법 — PDF 유도
- 적률과 적률생성함수 — MGF로 \(E[X^n]\) 계산
후속 주제
- 라플라스 분포 (Laplace Distribution)
- 분포 가족 개요 — 지수족 분류
관련 개념
- 코시 분포 (Cauchy Distribution) — 비교: MGF 미존재 분포들
- 감마 분포 (Gamma Distribution) — 유사한 우편향 분포
- 연속 분포 개요