1 이 포스트의 목적
Kokoszka & Reimherr (2017) Chapter 1은 FDA의 첫 단추를 끼우는 장이다. 기저 전개, 표본 통계량, EFPC, 실데이터 분석까지 핵심 도구를 모두 도입한다. 이 포스트는 Chapter 1의 연습문제(Problems 1.1~1.6)를 풀이하며, 단순히 답을 제시하는 것이 아니라 각 단계에서 “왜 그렇게 되는가”를 직관적으로 설명하는 데 초점을 맞춘다.
연습문제는 크게 세 유형으로 나뉜다:
| 유형 | 문제 | 핵심 역량 |
|---|---|---|
| 실데이터 탐색 | 1.1, 1.2, 1.3, 1.4 | R 코드로 기저 전개, 평균/공분산/EFPC 계산, 시각화 |
| 시뮬레이션 | 1.5 | Matern 과정 생성, 공분산 구조와 EFPC의 관계 |
| 수학적 유도 | 1.6 | 기저 전개 계수와 표본 통계량의 대수적 관계 |
2 Problem 1.1: Pinch Force 데이터
2.1 문제 요약
fda 패키지의 pinch 데이터는 151개 시점에서 측정된 20회 반복의 pinch force 곡선이다. (a) 15개 cubic B-spline으로 함수 객체 변환, (b) 점별 평균과 SD 계산, (c) 공분산 함수의 perspective/contour plot, (d) 처음 4개 EFPC와 90% 분산 설명에 필요한 성분 수를 구한다.
2.2 직관적 배경
Pinch force 실험은 “손가락으로 힘을 세게 주었다가 놓는” 동작을 20번 반복 측정한 것이다. 각 반복은 하나의 곡선이 된다. 핵심 질문은: “20개 곡선이 어떤 공통 패턴을 가지며, 개인차는 어디에서 나타나는가?” 이다.
2.3 (a) B-spline 기저를 이용한 함수 객체 변환
library(fda)
data(pinch)
# pinch: 151 x 20 행렬 (151 시점, 20 곡선)
time_points <- seq(0, 1, length.out = 151)
# 15개 cubic B-spline 기저 생성
# order = 4 (cubic), nbasis = 15
# nbreaks = nbasis - order + 2 = 13개 내부 매듭점(knots)
pinch_basis <- create.bspline.basis(
rangeval = c(0, 1),
nbasis = 15,
norder = 4
)
# 원시 데이터를 함수 객체로 변환
pinch_fd <- smooth.basis(
argvals = time_points,
y = pinch,
fdParobj = pinch_basis
)$fd
# 20개 평활 곡선 그리기
plot(pinch_fd, main = "Pinch Force: 20 Smoothed Curves",
xlab = "Normalized Time", ylab = "Force")왜 15개 기저인가? 151개 관측점에서 15개 기저를 사용하면 약 10:1의 압축이 이루어진다. Cubic B-spline(order 4)은 3차 다항식 조각을 매끄럽게 잇는 것이므로, pinch force 같은 “올라갔다 내려오는” 비주기적 곡선에 적합하다. 기저 수가 너무 적으면 피크를 놓치고, 너무 많으면 노이즈까지 따라간다. 15개는 대략 10~12개 시간 구간으로 나누는 것에 해당하며, pinch force의 상승-유지-하강 구조를 포착하기에 충분하다.
2.4 (b) 점별 평균과 표준편차
# 평균 함수
pinch_mean <- mean.fd(pinch_fd)
# 점별 SD 계산
pinch_eval <- eval.fd(time_points, pinch_fd) # 151 x 20 행렬
pinch_sd <- apply(pinch_eval, 1, sd)
# 그래프에 추가
plot(pinch_fd, col = "grey70",
main = "Pinch Force with Mean and SD Bands",
xlab = "Time", ylab = "Force")
lines(pinch_mean, lwd = 3, col = "blue")
# ± 1 SD 밴드
mean_vals <- eval.fd(time_points, pinch_mean)
lines(time_points, mean_vals + pinch_sd, lty = 2, col = "red", lwd = 2)
lines(time_points, mean_vals - pinch_sd, lty = 2, col = "red", lwd = 2)해석: 평균 곡선은 “전형적인 pinch 동작의 형태”를 보여준다 — 빠르게 힘이 증가하여 피크에 도달한 후 서서히 감소한다. SD 밴드가 피크 부근에서 가장 넓다면, 이는 “최대 힘의 크기”가 사람마다 가장 크게 다르다는 뜻이다. 반면 시작과 끝(힘 = 0)에서는 SD가 거의 0이다 — 모든 반복이 0에서 출발하고 0으로 돌아오기 때문이다.
2.5 (c) 표본 공분산 함수의 시각화
# 공분산 이변량 함수 계산
pinch_cov <- var.fd(pinch_fd)
# Perspective plot
# 공분산 함수 c(t,s)를 3D 곡면으로 시각화
surf <- eval.bifd(time_points, time_points, pinch_cov)
persp(time_points, time_points, surf,
theta = 30, phi = 30,
main = "Sample Covariance Surface",
xlab = "t", ylab = "s", zlab = "c(t,s)")
# Contour plot
contour(time_points, time_points, surf,
main = "Covariance Contour",
xlab = "t", ylab = "s")직관: 공분산 함수 \(\hat{c}(t,s)\) 는 “시점 \(t\) 에서의 곡선 값과 시점 \(s\) 에서의 곡선 값이 얼마나 함께 변하는가”를 나타내는 이변량 함수이다. 대각선 \(t = s\) 위의 값은 \(\hat{c}(t,t) = \text{Var}(X(t))\) , 즉 각 시점에서의 분산이다. 피크 시점 근처의 대각선 값이 가장 크다면, 최대 힘 시점에서 변동이 가장 크다는 뜻이다.
공분산이 대각선 밖에서도 높은 영역이 있다면, “피크에서 힘이 큰 곡선은 피크 직후에도 힘이 큰 경향이 있다”는 시간적 상관을 보여준다.
2.6 (d) EFPC 분석
# PCA 수행
pinch_pca <- pca.fd(pinch_fd, nharm = 4)
# 처음 4개 EFPC 시각화
par(mfrow = c(2, 2))
for (k in 1:4) {
plot(pinch_pca$harmonics[k],
main = paste0("EFPC ", k, " (",
round(pinch_pca$varprop[k] * 100, 1), "%)"),
xlab = "Time", ylab = "Loading")
abline(h = 0, lty = 2)
}
# 누적 분산 설명률
cumvar <- cumsum(pinch_pca$varprop)
cat("Components for 90% variance:", which(cumvar >= 0.90)[1], "\n")EFPC 해석의 원리: 각 EFPC \(\hat{v}_k(t)\) 는 “평균 곡선으로부터의 편차 중 \(k\) 번째로 큰 변동 패턴”이다. 구체적으로:
- EFPC 1: 보통 “전체적으로 힘이 크냐 작냐” — 양수이면 평균보다 전반적으로 강한 pinch
- EFPC 2: “피크가 빨리 오느냐 늦게 오느냐” 같은 타이밍 변동
- EFPC 3, 4: 점점 더 세밀한 형태 차이 (예: 피크 후 감소 속도의 차이)
90% 분산 설명에 2~3개 성분이면 충분하다면, pinch force의 개인 차이는 “강도”와 “타이밍” 두 가지 차원으로 대부분 설명된다는 뜻이다. 이는 20차원(20개 곡선)에서 2~3차원으로의 극적인 차원 축소를 의미한다.
3 Problem 1.2: US Federal Reserve 수익률 곡선
3.1 문제 요약
1982년 1월~2009년 6월의 미 재무부 채권 월간 금리(만기: 3, 6, 12, 60, 84, 120개월)를 함수 데이터로 변환하여 분석한다.
3.2 직관적 배경
수익률 곡선(yield curve) 은 “만기가 길수록 금리가 어떻게 변하는가”를 보여주는 곡선이다. 경제학에서 수익률 곡선의 형태는 경기 전망의 핵심 지표이다:
- 정상(normal): 만기가 길수록 금리 상승 → 경기 낙관
- 역전(inverted): 장기 금리가 단기보다 낮음 → 경기 침체 신호
- 평탄(flat): 만기 무관하게 비슷 → 전환기
3.3 (a) 1982년 1월 vs 2009년 6월 비교
library(fds)
library(fda)
yield <- FedYieldcurve
terms <- yield$x # 만기: 3, 6, 12, 60, 84, 120
# 1982년 1월 (첫 번째 열)과 2009년 6월 (마지막 열)
plot(terms, yield$y[, 1], pch = 15, ylab = "Yield (%)",
xlab = "Maturity (months)", ylim = c(0, 16),
main = "Yield Curve: Jan 1982 vs Jun 2009")
points(terms, yield$y[, 330], pch = 16, col = "red")
legend("topright", c("Jan 1982", "Jun 2009"),
pch = c(15, 16), col = c("black", "red"))해석: 1982년 1월은 볼커(Volcker)의 긴축 정책 시기로 금리가 14~16% 수준이었다. 2009년 6월은 금융 위기 직후 제로 금리 정책으로 단기 금리가 0~1%에 불과하다. 두 시점의 수익률 곡선은 수준(level) 에서 극단적 차이를 보이며, 기울기(slope) 도 다르다 — 2009년은 가파른 정상 곡선(단기 ≈ 0, 장기 ≈ 4%)이지만 1982년은 상대적으로 평탄하거나 역전될 수 있다.
3.4 (b) 평균 수익률 함수
# 4개 B-spline 기저로 함수 변환
# 관측점이 6개뿐이므로 기저 4개면 적절 (과적합 방지)
yield_basis <- create.bspline.basis(
rangeval = range(terms),
nbasis = 4,
norder = 4
)
# 330개월치 데이터를 함수 객체로 변환
yield_fd <- smooth.basis(
argvals = terms,
y = yield$y,
fdParobj = yield_basis
)$fd
# 평균 함수
yield_mean <- mean.fd(yield_fd)
plot(yield_mean, main = "Mean Yield Curve (1982-2009)",
xlab = "Maturity (months)", ylab = "Average Yield (%)")왜 기저 4개인가? 관측점이 6개(만기 3, 6, 12, 60, 84, 120개월)뿐이므로, 4개 기저면 자유도가 2밖에 남지 않는다. 이 제약이 자연스러운 평활화를 제공한다. 기저를 5~6개로 올리면 과적합 위험이 커진다.
평균 수익률 곡선의 해석: 1982~2009년 전체 평균으로 보면 수익률 곡선은 정상(우상향) 형태일 가능성이 높다. 이는 “평균적으로 장기 투자는 단기보다 높은 보상을 요구한다”는 기간 프리미엄(term premium)을 반영한다.
3.5 (c) 제1주성분
yield_pca <- pca.fd(yield_fd, nharm = 3)
# 제1주성분 시각화
plot(yield_pca$harmonics[1],
main = paste0("1st PC (",
round(yield_pca$varprop[1] * 100, 1), "%)"),
xlab = "Maturity (months)", ylab = "Loading")
abline(h = 0, lty = 2)
cat("Variance explained by PC1:",
round(yield_pca$varprop[1] * 100, 1), "%\n")해석: 수익률 곡선의 제1주성분은 보통 수준 이동(level shift) 을 나타낸다 — 모든 만기의 금리가 함께 오르거나 내리는 패턴이다. 이 성분이 90% 이상의 분산을 설명한다면, 수익률 곡선의 월별 변동 대부분은 “전반적 금리 수준의 변화”로 귀결된다는 뜻이다. 이는 거시경제학에서 잘 알려진 결과이며, Nelson-Siegel 모형의 “level” 팩터에 대응한다.
4 Problem 1.3: El Nino/La Nina SST 데이터
4.1 문제 요약
1950~2013년 태평양 NINO3 지역의 월별 해수면 온도(SST)를 연도별 함수(12개월 = 하나의 곡선)로 변환하여 El Nino/La Nina 연도를 시각화한다.
4.2 직관적 배경
El Nino는 적도 태평양의 해수면 온도가 비정상적으로 높아지는 현상이고, La Nina는 반대로 낮아지는 현상이다. 각 연도의 SST를 하나의 곡선으로 보면, El Nino 연도의 곡선은 평균 곡선 위에, La Nina 연도의 곡선은 아래에 위치할 것이다.
4.3 (a) Fourier 기저를 이용한 함수 변환
library(fda)
# 데이터 로드 (니뇨 3.4 인덱스)
nino <- read.csv("ninoSST.csv", header = TRUE)
year <- 1950:2013
month <- 1:12
# 64개 연도의 12개월 데이터를 행렬로 정리
SSTmat <- matrix(NA, nrow = 12, ncol = 64)
count <- 1
for (yr in year) {
tmp <- nino[which(nino$YEAR == yr), ]$NINO3
SSTmat[, count] <- tmp
count <- count + 1
}
# 5개 Fourier 기저 (주기적 데이터에 적합)
# 왜 Fourier? SST는 연간 주기성이 있다 (여름/겨울 패턴)
sst_basis <- create.fourier.basis(
rangeval = c(1, 12),
nbasis = 5
)
# 함수 객체 변환
sst_fd <- smooth.basis(
argvals = month,
y = SSTmat,
fdParobj = sst_basis
)$fd
# 64개 곡선 + 평균 곡선
plot(sst_fd, col = "grey70",
main = "NINO3 SST Curves (1950-2013)",
xlab = "Month", ylab = "SST (C)")
lines(mean.fd(sst_fd), col = "black", lwd = 3)왜 Fourier 기저인가? 12개월 주기의 온도 데이터는 본질적으로 주기적이다 — 1월의 기온과 12월의 기온은 연속적으로 이어져야 한다. Fourier 기저(sin, cos)는 이런 주기적 데이터의 자연스러운 표현이다. 5개 기저면 상수항 + sin/cos 2쌍으로, 연간 주기와 반년 주기를 포착한다.
4.4 (b) El Nino/La Nina 연도 강조
# El Nino 연도 (비정상적으로 따뜻한 해)
eln <- c(1965, 1972, 1982, 1997)
# La Nina 연도 (비정상적으로 차가운 해)
lan <- c(1955, 1973, 1975, 1988, 1999)
elnn <- match(eln, year)
lann <- match(lan, year)
# 기본 곡선 (회색)
plot(sst_fd, col = "grey80",
main = "El Nino (Red) vs La Nina (Blue)",
xlab = "Month", ylab = "SST (C)")
# El Nino 곡선 (빨간색, 두껍게)
lines(sst_fd[elnn], col = "red", lwd = 3)
# La Nina 곡선 (파란색, 두껍게)
lines(sst_fd[lann], col = "blue", lwd = 3)
# 평균 곡선 (검정)
lines(mean.fd(sst_fd), col = "black", lwd = 2, lty = 2)
legend("topright",
c("El Nino", "La Nina", "Mean"),
col = c("red", "blue", "black"),
lwd = c(3, 3, 2), lty = c(1, 1, 2))해석: El Nino 연도의 곡선은 평균 곡선 위에 분포하고, La Nina 연도는 아래에 분포한다. 흥미로운 것은 연중 어느 시기에 차이가 극대화되는가 이다. 전형적으로 El Nino/La Nina는 북반구 겨울(12~2월)에 가장 강하므로, 곡선의 끝부분에서 차이가 클 것이다.
이 시각화는 FDA의 핵심 가치를 보여준다: 개별 월의 온도 값보다 곡선 전체의 패턴(형태, 수준, 기울기)이 El Nino/La Nina를 더 명확하게 구별한다.
5 Problem 1.4: DJIA 누적 수익률의 함수적 상자그림
5.1 문제 요약
2013년 DJIA 30개 종목의 일별 종가에서 누적 수익률 곡선을 구하고, 함수적 상자그림(functional boxplot)으로 시각화한다.
5.2 직관적 배경
전통적 상자그림은 “단일 숫자의 분포”를 요약한다. 하지만 주가의 누적 수익률은 시간에 따른 곡선이다. 함수적 상자그림(functional boxplot) 은 “곡선 전체를 하나의 데이터 점으로 취급”하여 중앙 50% 곡선, 중앙 곡선(중위수), 이상 곡선을 식별한다.
5.3 (a) 누적 수익률 정의와 계산
누적 수익률의 정의:
\[ R_n = 100 \frac{P_n - P_1}{P_1}, \quad 1 \leq n \leq 252 \]
여기서 \(P_n\) 은 \(n\) 일차 종가이다. 이 정의는 “연초 대비 몇 % 올랐는가”를 백분율로 나타낸다.
library(fda)
d <- read.csv("Dow_companies_data.csv")
data <- d[, 2:31] # 252 x 30 가격 행렬
# Exxon Mobil (XOM) 종가
xom <- data$XOM
# 누적 수익률 계산
xom_return <- 100 * (xom - xom[1]) / xom[1]
plot(1:252, xom_return, type = "l",
main = "XOM Cumulative Return (2013)",
xlab = "Trading Day", ylab = "Return (%)")
abline(h = 0, lty = 2)
cat("XOM 2013 total return:", round(xom_return[252], 1), "%\n")직관: \(R_1 = 0\) (첫날은 기준점)이고, \(R_n > 0\) 이면 연초 대비 상승, \(R_n < 0\) 이면 하락이다. 이 곡선의 최종값 \(R_{252}\) 가 해당 종목의 연간 수익률이 된다.
5.4 (b) 30개 종목의 누적 수익률
# 모든 종목의 누적 수익률 행렬
cr <- matrix(NA, nrow = 252, ncol = 30)
for (j in 1:30) {
p <- data[, j]
cr[, j] <- 100 * (p - p[1]) / p[1]
}
# 전체 곡선 그리기
matplot(1:252, cr, type = "l", col = "grey70", lty = 1,
main = "DJIA 30 Stocks: Cumulative Returns (2013)",
xlab = "Trading Day", ylab = "Return (%)")
# 평균 곡선
lines(1:252, rowMeans(cr), col = "blue", lwd = 3)
# 중위수 곡선 (점별)
lines(1:252, apply(cr, 1, median), col = "red", lwd = 3)
legend("topleft", c("Mean", "Median"),
col = c("blue", "red"), lwd = 3)5.5 (c) 함수적 상자그림
# fbplot: 함수적 상자그림
fbplot(fit = t(cr), ylim = c(-20, 90),
xlab = "Trading Day", ylab = "Cumulative Return (%)",
main = "Functional Boxplot: DJIA 2013")함수적 상자그림의 핵심 원리:
전통적 상자그림에서 중앙값은 “데이터를 절반으로 나누는 점”이다. 함수적 상자그림에서는 band depth 개념을 사용한다: 한 곡선이 다른 곡선들 사이에 끼여 있는 정도가 높을수록 “중심적”이라 판단한다. 구체적으로:
- 검정 곡선 (중위수): band depth가 가장 큰 곡선 — 가장 “전형적인” 종목의 수익률 궤적
- 분홍/보라 영역 (중앙 50%): band depth 기준 상위 50%의 곡선이 차지하는 띠
- 빨간 점선 (이상 곡선): 중앙 영역에서 1.5 × IQR 이상 벗어난 곡선
전통적 상자그림과의 핵심 차이는 점별(pointwise) 아웃라이어가 아닌 곡선 전체(global) 아웃라이어를 식별한다는 것이다. 즉, “특정 하루만 이상한” 것이 아니라 “전체 궤적이 다른 종목과 질적으로 다른” 종목을 잡아낸다.
# 3단계 확률 수준의 함수적 상자그림
fbplot(fit = t(cr), ylim = c(-20, 90),
prob = c(0.30, 0.60, 0.90),
color = c("darkviolet", "mediumpurple", "lavender"),
xlab = "Trading Day", ylab = "Cumulative Return (%)",
main = "Functional Boxplot: 30/60/90% Bands")6 Problem 1.5: Matern 과정 시뮬레이션
6.1 문제 요약
Matern 공분산 함수를 가진 가우시안 과정을 \(\nu = 1/2, 2, 4\) 에서 시뮬레이션하고, 각각의 EFPC와 분산 설명률을 비교한다.
6.2 Matern 공분산 함수
\[ C(t, s) = \frac{\sigma^2}{\Gamma(\nu) 2^{\nu - 1}} \left( \frac{\sqrt{2\nu} |t - s|}{\rho} \right)^{\nu} K_{\nu} \left( \frac{\sqrt{2\nu} |t - s|}{\rho} \right) \]
여기서 \(\sigma^2 = 1\) (분산), \(\nu\) (매끄러움 모수), \(\rho = 1\) (범위 모수), \(K_{\nu}\) 는 제2종 수정 베셀 함수이다.
6.3 직관적 이해
Matern 과정에서 \(\nu\) 는 곡선의 매끄러움을 제어한다:
- \(\nu = 1/2\) : 연속이지만 미분 불가능 — 톱니 모양의 거친 궤적 (Ornstein-Uhlenbeck 과정)
- \(\nu = 2\) : 1회 미분 가능 — 부드럽지만 여전히 뾰족한 부분 있음
- \(\nu = 4\) : 3회 미분 가능 — 매우 매끄러운 곡선
- \(\nu \to \infty\) : 무한히 매끄러운 가우시안(squared exponential) 과정
비유하면: \(\nu = 1/2\) 은 “산악 지형의 스카이라인”, \(\nu = 4\) 는 “언덕의 부드러운 능선”과 같다.
6.4 시뮬레이션 코드
library(fda)
# Matern 공분산 함수 구현
matern_cov <- function(h, nu, sigma2 = 1, rho = 1) {
# h: 시점 간 거리 |t - s|
if (h == 0) return(sigma2)
arg <- sqrt(2 * nu) * h / rho
# K_nu: 제2종 수정 베셀 함수
coef <- sigma2 / (gamma(nu) * 2^(nu - 1))
result <- coef * arg^nu * besselK(arg, nu)
return(result)
}
# 시간 그리드 (50개 균등 점)
tgrid <- seq(0, 1, length.out = 50)
N <- 100 # 곡선 수
simulate_matern <- function(nu, tgrid, N) {
n_t <- length(tgrid)
# 공분산 행렬 구성
Sigma <- matrix(0, n_t, n_t)
for (i in 1:n_t) {
for (j in 1:n_t) {
Sigma[i, j] <- matern_cov(abs(tgrid[i] - tgrid[j]), nu)
}
}
# 촐레스키 분해로 다변량 정규 생성
L <- chol(Sigma + 1e-10 * diag(n_t)) # 수치 안정성
# N개 iid 곡선 생성: X = L^T Z (Z는 표준 정규)
Z <- matrix(rnorm(n_t * N), nrow = n_t, ncol = N)
X <- t(L) %*% Z
return(X)
}
# 세 값의 nu에 대해 시뮬레이션
par(mfrow = c(1, 3))
for (nu in c(0.5, 2, 4)) {
X <- simulate_matern(nu, tgrid, N = 100)
matplot(tgrid, X[, 1:20], type = "l", col = "grey60", lty = 1,
main = bquote(nu == .(nu)),
xlab = "t", ylab = "X(t)")
}왜 촐레스키 분해인가? \(N(0, \Sigma)\) 에서 표본을 생성하려면 \(\Sigma = LL^T\) 로 분해하고 \(X = Lz\) ( \(z \sim N(0, I)\) )로 변환한다. 이는 “상관된 다변량 정규 = 독립 정규 + 선형 변환” 원리이다.
6.5 EFPC 비교
par(mfrow = c(3, 4))
for (nu in c(0.5, 2, 4)) {
X <- simulate_matern(nu, tgrid, N = 100)
# 함수 객체 변환
basis <- create.bspline.basis(c(0, 1), nbasis = 20)
fd_obj <- smooth.basis(tgrid, X, basis)$fd
# PCA
pca_result <- pca.fd(fd_obj, nharm = 4)
for (k in 1:4) {
plot(pca_result$harmonics[k],
main = bquote(nu == .(nu) ~ ", PC" ~ .(k) ~
"(" ~ .(round(pca_result$varprop[k]*100,1)) ~ "%)"),
xlab = "t", ylab = "")
abline(h = 0, lty = 2)
}
}핵심 관찰:
| \(\nu\) | PC1 분산 설명률 | EFPC 형태 | 해석 |
|---|---|---|---|
| 0.5 | 낮음 (40~50%) | 빠르게 진동 | 거친 곡선은 많은 성분이 필요 |
| 2 | 중간 (60~70%) | 저주파 위주 | 적당히 매끄러운 곡선, 몇 개 성분으로 요약 가능 |
| 4 | 높음 (80~90%) | 매우 매끈 | 매끄러운 곡선은 1~2개 성분으로 거의 설명됨 |
직관: 매끄러운 곡선일수록 “가능한 형태의 다양성”이 제한된다. \(\nu\) 가 클수록 고유값이 빠르게 감소하여 소수 성분으로 대부분의 변동을 포착할 수 있다. 반대로 \(\nu = 1/2\) 의 거친 곡선은 “예측 불가능한 지점 변동”이 많아 차원 축소가 어렵다.
이는 실무적으로 중요한 교훈이다: 데이터가 매끄러울수록 FDA가 효과적이다. 잡음이 많은 원시 데이터에 평활화(smoothing)를 적용하는 이유가 여기에 있다 — 노이즈를 제거하면 유효 차원이 줄어들어 FPCA의 효율이 높아진다.
7 Problem 1.6: 기저 전개 계수의 유도
7.1 문제
각 곡선을 직교정규 기저로 전개할 때:
\[ x_n(t) = \sum_{m=1}^{M} c_{nm} B_m(t) \]
표본 평균 함수와 표본 공분산 함수를 같은 기저로 표현하면:
\[ \bar{x}_N(t) = \sum_{m=1}^{M} a_m B_m(t) \]
\[ \hat{c}(t, s) = \sum_{m=1}^{M} \sum_{k=1}^{M} b_{mk} B_m(t) B_k(s) \]
직교정규 조건 \(\int B_m(t) B_k(t) \, dt = \mathbf{1}_{m=k}\) 하에서 \(a_m\) 과 \(b_{mk}\) 를 구하라.
7.2 풀이: \(a_m\) 의 유도
Step 1: 표본 평균의 정의
\[ \bar{x}_N(t) = \frac{1}{N} \sum_{n=1}^{N} x_n(t) = \frac{1}{N} \sum_{n=1}^{N} \sum_{m=1}^{M} c_{nm} B_m(t) \]
Step 2: 합의 순서 교환
\[ \bar{x}_N(t) = \sum_{m=1}^{M} \left( \frac{1}{N} \sum_{n=1}^{N} c_{nm} \right) B_m(t) \]
Step 3: 계수 식별
\(\bar{x}_N(t) = \sum_{m=1}^{M} a_m B_m(t)\) 와 비교하면:
\[ \boxed{a_m = \frac{1}{N} \sum_{n=1}^{N} c_{nm} = \bar{c}_m} \]
직관적 해석: 평균 함수의 \(m\) 번째 기저 계수는, 모든 곡선의 \(m\) 번째 기저 계수의 산술 평균이다. 즉, 함수 공간에서의 평균은 계수 공간에서의 좌표별 평균과 동치이다.
이는 자연스럽다: 100개 곡선을 기저 전개하면 100개의 계수 벡터 \(\mathbf{c}_1, \ldots, \mathbf{c}_{100}\) 을 얻고, 이들의 좌표별 평균 \(\bar{\mathbf{c}}\) 를 구하면 그것이 곧 평균 곡선의 기저 계수가 된다.
왜 직교정규 조건이 필요한가? 비직교 기저에서는 \(a_m\) 을 식별하기 위해 양변에 \(B_m\) 을 곱하고 적분해도 교차항이 남아 단순한 평균이 되지 않는다. 직교정규성이 있어야 \(\langle \bar{x}_N, B_m \rangle = a_m\) 이 깔끔하게 성립한다.
7.3 풀이: \(b_{mk}\) 의 유도
Step 1: 표본 공분산의 정의
\[ \hat{c}(t, s) = \frac{1}{N-1} \sum_{n=1}^{N} \left[ x_n(t) - \bar{x}_N(t) \right] \left[ x_n(s) - \bar{x}_N(s) \right] \]
Step 2: 편차를 기저로 전개
\(x_n(t) - \bar{x}_N(t) = \sum_{m=1}^{M} (c_{nm} - \bar{c}_m) B_m(t)\) 이므로:
\[ \hat{c}(t, s) = \frac{1}{N-1} \sum_{n=1}^{N} \left[ \sum_{m=1}^{M} (c_{nm} - \bar{c}_m) B_m(t) \right] \left[ \sum_{k=1}^{M} (c_{nk} - \bar{c}_k) B_k(s) \right] \]
Step 3: 곱셈 전개 후 합의 순서 교환
\[ \hat{c}(t, s) = \sum_{m=1}^{M} \sum_{k=1}^{M} \left[ \frac{1}{N-1} \sum_{n=1}^{N} (c_{nm} - \bar{c}_m)(c_{nk} - \bar{c}_k) \right] B_m(t) B_k(s) \]
Step 4: 계수 식별
\[ \boxed{b_{mk} = \frac{1}{N-1} \sum_{n=1}^{N} (c_{nm} - \bar{c}_m)(c_{nk} - \bar{c}_k) = \widehat{\text{Cov}}(c_{\cdot m}, c_{\cdot k})} \]
직관적 해석: 공분산 함수의 \((m, k)\) 번째 기저 계수는, 계수 벡터들의 \(m\) 번째 좌표와 \(k\) 번째 좌표 사이의 표본 공분산이다.
이를 행렬로 표현하면 더 명쾌하다. \(N \times M\) 계수 행렬을 \(\mathbf{C}\) 라 하면:
\[ \mathbf{B} = [b_{mk}] = \frac{1}{N-1} \tilde{\mathbf{C}}^T \tilde{\mathbf{C}} \]
여기서 \(\tilde{\mathbf{C}}\) 는 각 열을 중심화(centering)한 행렬이다. 즉, 공분산 함수의 기저 계수 행렬은 중심화된 계수 행렬의 표본 공분산 행렬과 일치한다.
7.4 검증: 직교정규 조건의 역할
유도의 핵심은 기저가 직교정규이므로:
\[ \langle \hat{c}(\cdot, s), B_m \rangle = \int \hat{c}(t, s) B_m(t) \, dt = \sum_{k=1}^{M} b_{mk} B_k(s) \]
왼쪽에서 \(B_m(t)\) 를 곱하고 적분하면 \(\int B_m(t) B_{m'}(t) \, dt = \delta_{mm'}\) 에 의해 \(m'\) 번째 항만 살아남는다. 비직교 기저였다면 Gram 행렬 \(G_{mk} = \langle B_m, B_k \rangle\) 의 역행렬이 필요해진다:
\[ \mathbf{b} = \mathbf{G}^{-1} (\text{계수별 공분산}) \mathbf{G}^{-1} \]
직교정규 기저에서는 \(\mathbf{G} = \mathbf{I}\) 이므로 이 복잡함이 사라진다. 이것이 직교정규 기저가 이론적 유도에서 선호되는 이유이다.
7.5 실무적 의미
이 결과는 FDA의 계산적 효율성을 보장한다:
- 저장: \(N\) 개 곡선의 정보는 \(N \times M\) 계수 행렬 \(\mathbf{C}\) 에 모두 담긴다
- 표본 통계량: 평균 함수 = 열 평균, 공분산 함수 = 열 공분산 → 행렬 연산으로 즉시 계산
- PCA: 공분산 행렬 \(\mathbf{B}\) 의 고유값 분해가 곧 FPCA — \(M \times M\) 행렬의 SVD로 귀결
\(N = 1000\) 개 곡선, \(M = 25\) 개 기저라면, \(25 \times 25\) 행렬의 고유값 분해만으로 1000개 곡선의 주성분을 구할 수 있다. 원래 데이터가 각 곡선 200개 관측점이었다면 \(1000 \times 200\) 문제가 \(25 \times 25\) 문제로 축소된 것이다.
8 종합 정리
| 문제 | 핵심 개념 | 핵심 교훈 |
|---|---|---|
| 1.1 | B-spline, EFPC | 비주기 곡선에 B-spline, EFPC는 변동 패턴의 계층 구조 |
| 1.2 | 수익률 곡선, FPCA | 경제 데이터의 차원 축소: 수준/기울기/곡률 3요인 |
| 1.3 | Fourier, 기후 분류 | 주기 데이터에 Fourier 기저, 곡선 패턴으로 이벤트 탐지 |
| 1.4 | 함수적 상자그림 | 점별이 아닌 전역적 이상치 식별, band depth |
| 1.5 | Matern, 매끄러움 | 곡선 매끄러움 \(\nu\) 와 유효 차원의 역관계 |
| 1.6 | 계수 대수 | 함수 통계량 = 계수의 다변량 통계량, 직교정규의 계산적 이점 |
이 연습문제들이 전달하는 핵심 메시지는: FDA는 무한 차원의 함수를 유한 차원의 계수로 축소하고, 그 계수에 기존의 다변량 통계를 적용하는 프레임워크라는 것이다. 기저 선택(B-spline vs Fourier)과 성분 수 결정(\(M\), 주성분 수)이 그 축소의 질을 결정한다.
9 관련 주제
선행 지식
후속 주제