곡선 정렬과 탐색적 FDA 확장

Curve Alignment, Registration, and Further Reading

함수형 데이터의 위상 변동(phase variation)을 제거하기 위한 곡선 정렬(curve alignment) 기법을 다룬다. 시간 뒤틀림 함수(time warping function), 랜드마크 등록(landmark registration), 연속 등록(continuous registration), 진폭-위상 분산 분해(amplitude-phase decomposition)를 상세히 설명하고, FDA의 추가 연구 방향(분류, 군집화, 매니폴드)을 정리한다.

Statistics
Functional Data Analysis
저자

Kwangmin Kim

공개

2026년 04월 29일

1 왜 곡선 정렬이 필요한가

함수형 데이터에서 개별 곡선들의 형태(shape)는 유사하지만, 시간 축을 따라 좌우로 이동(shift)되어 있는 경우가 빈번하다. 이때 정렬 없이 표본 평균을 구하면 다음과 같은 문제가 발생한다:

  • 평균 함수의 진폭(amplitude)이 개별 곡선보다 작아진다
  • 평균 함수의 지지(support)가 개별 곡선보다 넓어진다
  • 주성분 분석 시 실제 구조가 아닌 시간 이동 효과가 주성분으로 잡힌다

직관적으로 생각하면, 같은 모양의 종을 여러 개 겹치되 봉우리 위치가 각각 다르면, 평균은 “납작하고 퍼진 종”이 된다. 이는 원래 종의 특성을 전혀 반영하지 못한다.

핵심 관찰: 사인 곡선 예제

5개의 동일한 사인 곡선이 서로 다른 위상으로 이동된 경우를 생각하자. 정렬 전에는 3개의 주성분이 전체 변동의 55%, 39%, 5%를 각각 설명한다. 그러나 정렬 후에는 5개 곡선이 동일해지므로, 단 1개의 주성분이 100%를 설명한다. 이것이 정렬의 효과이다 (Kokoszka, 2017, Ch.2).

2 진폭 변동과 위상 변동

함수형 표본의 변동성(variability)은 두 가지 근원으로 분해된다:

변동 유형 정의 예시
진폭 변동(Amplitude Variation) 곡선의 높이·크기 차이 키 큰 소녀 vs 키 작은 소녀
위상 변동(Phase Variation) 시간 축을 따른 특징점의 이동 사춘기 성장 급등 시점의 개인차

대부분의 실제 데이터에서는 두 변동이 동시에 존재한다. 예를 들어 산간 하천의 봄철 수위 곡선은:

  • 진폭 변동: 겨울 총 적설량에 따라 수위 최대값이 다름
  • 위상 변동: 봄 기온 패턴에 따라 눈 녹는 시점이 다름

정렬(registration)이란 위상 변동을 제거하여 순수한 진폭 변동만 남기는 전처리 단계이다. 위상 변동이 제거되면 FPCA, 회귀 등 후속 분석의 해석력이 크게 향상된다.

3 시간 뒤틀림 함수

곡선 정렬의 수학적 기반은 시간 뒤틀림 함수(time warping function) \(h_n(t)\) 이다. 각 개체 \(n\) 에 대해, 물리적 시간 \(t\) 를 개체 고유의 내부 시간 \(h_n(t)\) 로 변환하는 단조 증가 함수를 설정한다.

정의: 시간 뒤틀림 모형

관측된 곡선 \(X_n(t)\) 는 정렬된 곡선 \(X_n^*(t)\) 의 시간 변환으로 표현된다:

\[ X_n(t) = X_n^*\bigl(h_n(t)\bigr) \]

따라서 정렬된 곡선은 역변환으로 복원된다:

\[ X_n^*(t) = X_n\bigl(h_n^{-1}(t)\bigr) \]

직관적 해석: \(h_n(t)\) 는 “개체 \(n\) 의 생물학적 시계”에 해당한다. 예를 들어 한 소녀의 사춘기 급등이 물리적 시간 \(t_a\) 에 일어나고, 다른 소녀는 \(t_b > t_a\) 에 일어난다고 하자. 물리적 시간은 다르지만 \(h_n(t_a) = h_n(t_b)\) 로 내부 시간은 동일하다. 즉, 두 소녀 모두 “생물학적으로 같은 시점”에 급등을 경험한 것이다.

\(h_n(t)\) 에 요구되는 성질:

  • 단조 증가(monotonically increasing): 시간이 역전되면 안 된다
  • 경계 보존: \(h_n(0) = 0\), \(h_n(T) = T\) — 관측 구간의 시작과 끝은 고정
  • 매끄러움(smoothness): 시간 변환이 급격히 꺾이면 비물리적

4 랜드마크 등록

랜드마크 등록(Landmark Registration) 은 사용자가 직접 각 곡선에서 특징점(landmark)을 식별하고, 모든 곡선의 특징점이 같은 시간에 오도록 뒤틀림 함수를 구성하는 방법이다.

4.1 알고리즘

성장 곡선 예제에서 “가장 빠르게 성장하는 시점” \(t_n\) 을 랜드마크로 사용한다고 하자. \(t_a = \frac{1}{N}\sum_{n=1}^N t_n\) 은 표본 평균 랜드마크 시점이다.

뒤틀림 함수 구성 조건:

  1. \(h_n(0) = 0\) — 구간 시작 고정
  2. \(h_n(t_n) = t_a\) — 개인 랜드마크가 평균 시점으로 이동
  3. \(h_n(T) = T\) — 구간 끝 고정

이 세 점 \((0, 0)\), \((t_n, t_a)\), \((T, T)\) 을 지나는 유일한 포물선(parabola)이 \(h_n(t)\) 가 된다. 포물선 보간은 세 점에 대해 2차 다항식의 계수를 결정하므로 해가 유일하다.

등록된 곡선은 다음과 같이 정의된다:

\[ X_n^{\mathrm{reg}}(t) = X_n\bigl(h_n^{-1}(t)\bigr) \]

4.2 검증

가속도 곡선 \(X_n\)\(X_n(t_n) = 0\) 을 만족한다면 (즉, 가장 빠른 성장 시점에서 가속도가 0으로 교차):

\[ X_n^{\mathrm{reg}}(t_a) = X_n\bigl(h_n^{-1}(t_a)\bigr) = X_n(t_n) = 0 \]

모든 등록된 곡선이 시점 \(t_a\) 에서 동시에 0을 통과한다. 이는 정렬이 의도대로 작동했음을 확인하는 검증 기준이다.

4.3 장단점

장점 단점
직관적이고 해석이 명확 랜드마크를 수동 식별해야 함 (locator())
물리적 의미가 분명한 정렬 곡선 수가 많으면 비현실적
구현이 단순 랜드마크 선택이 모호한 경우 적용 불가

5 연속 등록

연속 등록(Continuous Registration) 은 이산적 랜드마크 대신, 목표 함수(target function)와의 근접성을 최적화하여 뒤틀림 함수를 자동으로 결정하는 방법이다.

5.1 핵심 아이디어

R의 register.fd 함수는 기본적으로 등록된 곡선들이 그들의 평균에 가까워지도록 단조 증가 뒤틀림 함수 \(h_n\) 을 계산한다. 목표 함수(target)를 평균 이외의 함수로 지정할 수도 있다.

직관적으로, 연속 등록은 “모든 곡선을 부드럽게 늘이거나 줄여서, 전체적인 모양이 가능한 한 비슷해지게 만드는” 자동화된 절차이다.

5.2 랜드마크 등록과의 비교

비교 항목 랜드마크 등록 연속 등록
자동화 수동 자동
랜드마크 필요 필수 불필요
해석 가능성 높음 (특정 사건 기반) 상대적으로 낮음
적용 범위 특징점 명확한 경우 범용
R 함수 locator() + 직접 구현 register.fd()

5.3 여자 성장 곡선 적용 예

54명 여자아이의 가속도 곡선(2차 미분)에 연속 등록을 적용한다:

# 가속도 곡선 계산
accelUnreg <- deriv.fd(heightSmooth$fd, 2)

# 연속 등록 수행
regList <- register.fd(yfd = accelUnreg)
accelReg <- regList$regfd

# 등록된 곡선 시각화
plot(accelReg, xlab = "Age", ylab = "Acceleration", ylim = c(-4, 3))

등록 후 가속도 곡선들은 위상 변동이 현저히 줄어들어, 사춘기 급등 시점이 더 좁은 범위에 모인다.

6 진폭-위상 분산 분해

Kneip and Ramsay (2008) 는 비등록 곡선의 총 분산을 진폭 성분과 위상 성분으로 분해하는 이론을 개발하였다.

6.1 총 분산

\[ \mathrm{MSE}_{\mathrm{total}} = \frac{1}{N} \sum_{n=1}^{N} \int \bigl[X_n(t) - \bar{X}(t)\bigr]^2 \, dt \]

이는 비등록 곡선 \(X_n\) 과 표본 평균 \(\bar{X}\) 사이의 적분 제곱 편차의 평균이다.

6.2 분해

\[ \mathrm{MSE}_{\mathrm{total}} = \mathrm{MSE}_{\mathrm{amp}} + \mathrm{MSE}_{\mathrm{pha}} \]

  • \(\mathrm{MSE}_{\mathrm{amp}}\): 등록 남아 있는 곡선 간 차이 — 순수 진폭 변동
  • \(\mathrm{MSE}_{\mathrm{pha}}\): 등록 과정에서 제거된 변동 — 위상 변동

직관: 등록은 곡선들을 시간 축을 따라 “정돈”하는 작업이다. 정돈 후에도 남아 있는 차이는 곡선의 본질적 크기(진폭) 차이이고, 정돈 과정에서 사라진 차이는 시간 이동(위상) 때문이었다.

주의: 분해는 등록 방법에 의존

\(\mathrm{MSE}_{\mathrm{amp}}\)\(\mathrm{MSE}_{\mathrm{pha}}\) 의 값은 단순히 표본의 고유 성질이 아니라, 어떤 등록 방법을 사용했느냐에도 달려 있다. 더 공격적인 등록은 \(\mathrm{MSE}_{\mathrm{pha}}\) 를 크게 만들고 \(\mathrm{MSE}_{\mathrm{amp}}\) 를 작게 만든다.

6.3 위상 변동 비율

위상 변동이 전체 변동에서 차지하는 비율은 다음과 같이 정의된다:

\[ R^2_{\mathrm{pha}} = \frac{\mathrm{MSE}_{\mathrm{pha}}}{\mathrm{MSE}_{\mathrm{total}}} \]

6.4 여자 성장 곡선 결과

# 뒤틀림 함수 추출
warpFunctions <- regList$warpfd

# 진폭-위상 분해
APList <- AmpPhaseDecomp(xfd = accelUnreg, yfd = accelReg, hfd = warpFunctions)

APList$RSQR
# [1] 0.3900585

APList$MS.amp
# [1] 5.917859

APList$MS.pha
# [1] 3.784479

해석:

  • \(\mathrm{MSE}_{\mathrm{amp}} = 5.92\): 등록 후 남은 순수 진폭 차이
  • \(\mathrm{MSE}_{\mathrm{pha}} = 3.78\): 등록이 제거한 위상 차이
  • \(R^2_{\mathrm{pha}} \approx 0.39\): 전체 변동의 약 39%가 위상 변동에 기인

즉, 54명 여자아이의 가속도 곡선 변동 중 약 2/5는 “사춘기 급등이 언제 일어나는가”라는 타이밍 차이에서 비롯되고, 나머지 3/5는 “급등의 크기가 얼마나 큰가”라는 진폭 차이에서 비롯된다.

7 FDA의 확장 연구 방향

§2.4 (Kokoszka, 2017, Ch.2) 는 FDA의 추가 연구 방향을 개관한다.

7.1 곡선 정렬의 최신 발전

  • Marron et al. (2015): 곡선 정렬 방법론의 포괄적 리뷰
  • Earls and Hooker (2016): 베이지안 관점의 곡선 정렬 — 불확실성 정량화 가능
  • Ramsay et al. (2007): 미분방정식에 스무딩 방법론을 적용하는 연구

7.2 함수형 데이터의 분류와 군집화

문제 유형 정의 머신러닝 대응어
분류(Classification) 사전 정의된 그룹에 새 곡선을 할당 지도학습(Supervised Learning)
군집화(Clustering) 표본 내 자연 그룹을 발견 비지도학습(Unsupervised Learning)

핵심 참고 문헌:

  • Wang et al. (2016), Cuevas (2014): 함수형 분류·군집화 개론
  • Gorecki et al. (2015): 함수형 분류 방법론
  • Jacques and Preda (2014): 함수형 군집화
  • Delaigle and Hall (2012): 함수형 분류 이론 — 다변량 분류와의 근본적 차이

다변량 데이터의 분류와 함수형 데이터의 분류는 단순히 차원 확장이 아니다. Delaigle and Hall (2012) 은 함수 공간에서의 분류가 본질적으로 다른 이유를 이론적으로 밝힌다: 무한 차원에서는 최적 분류 규칙의 구조가 유한 차원과 질적으로 다르다.

7.3 매니폴드 위의 함수형 데이터

함수의 정의역이 1차원 구간이 아닌 매니폴드(manifold)인 경우가 있다:

  • 시간 뒤틀림으로 생긴 매니폴드: 뒤틀림 함수 자체가 매니폴드 구조를 가짐
  • 물리적 매니폴드: 뇌 표면, 혈관 등 생체 구조 위에서 정의된 데이터
  • Ettinger et al. (2016): 매니폴드 위 함수형 데이터의 최신 연구

7.4 서로 다른 정의역을 가진 함수

기본적으로 FDA는 모든 함수가 동일한 정의역 \([0, T]\) 에서 정의된다고 가정한다. 그러나 현실에서는:

  • 환자마다 관측 기간이 다른 임상 데이터
  • 길이가 다른 음성 신호
  • 시작/종료 시점이 다른 센서 데이터

Liebl (2013) 은 정의역이 서로 다른 함수형 데이터의 분석 방법을 제안한다.

8 곡선 정렬의 실무 적용

8.1 적용 사례

분야 데이터 위상 변동 원인
생물학 성장 곡선 사춘기 시점 개인차
RT-PCR 증폭 곡선 초기 DNA 양에 따른 Ct 이동
기상학 계절 수위 눈 녹는 시점 차이
음성인식 음소 파형 발화 속도 차이
제조업 배치 프로세스 곡선 반응 시작 시점 차이

8.2 R 코드: 완전한 워크플로우

library(fda)

# Step 1: 데이터 로드 및 스무딩
age <- growth$age
heightBasis <- create.bspline.basis(c(1, 18), 35, 6, age)
heightPar <- fdPar(heightBasis, 3, 10^(-0.5))
heightSmooth <- smooth.basis(age, growth$hgtf, heightPar)

# Step 2: 가속도 곡선 계산 (2차 미분)
accelUnreg <- deriv.fd(heightSmooth$fd, 2)

# Step 3: 연속 등록 수행
regList <- register.fd(yfd = accelUnreg)
accelReg <- regList$regfd

# Step 4: 진폭-위상 분해
warpFunctions <- regList$warpfd
APList <- AmpPhaseDecomp(xfd = accelUnreg, yfd = accelReg, hfd = warpFunctions)

# 결과 해석
cat("위상 변동 비율:", round(APList$RSQR, 3), "\n")
cat("진폭 MSE:", round(APList$MS.amp, 3), "\n")
cat("위상 MSE:", round(APList$MS.pha, 3), "\n")

8.3 Python 참고 구현

import numpy as np
from scipy.interpolate import CubicSpline

def landmark_registration(curves, landmarks, target_time, T):
    """
    랜드마크 등록의 원리를 보여주는 순수 Python 구현.
    
    Parameters
    ----------
    curves : list of callables
        원본 곡선 함수들
    landmarks : array of float
        각 곡선의 랜드마크 시점 t_n
    target_time : float
        목표 랜드마크 시점 t_a (보통 landmarks의 평균)
    T : float
        관측 구간의 끝점
    
    Returns
    -------
    registered : list of callables
        등록된 곡선 함수들
    """
    registered = []
    for curve, t_n in zip(curves, landmarks):
        # 3점 (0,0), (t_n, t_a), (T, T)을 지나는 포물선 h_n(t) 구성
        # h_n(t) = at^2 + bt + c with c=0 (h_n(0)=0)
        # 연립방정식: a*t_n^2 + b*t_n = target_time
        #             a*T^2 + b*T = T
        A = np.array([[t_n**2, t_n], [T**2, T]])
        rhs = np.array([target_time, T])
        a, b = np.linalg.solve(A, rhs)
        
        # h_n(t) 및 역함수 h_n^{-1}(t)
        def h(t, a=a, b=b):
            return a * t**2 + b * t
        
        # 수치적 역함수: t_grid에서 h 값을 계산하고 보간
        t_grid = np.linspace(0, T, 1000)
        h_grid = np.array([h(t) for t in t_grid])
        h_inv = CubicSpline(h_grid, t_grid)
        
        # 등록된 곡선: X_n^reg(t) = X_n(h_n^{-1}(t))
        def reg_curve(t, curve=curve, h_inv=h_inv):
            return curve(h_inv(t))
        
        registered.append(reg_curve)
    
    return registered

9 관련 주제

선행 지식

후속 주제

관련 개념

Subscribe

Enjoy this blog? Get notified of new posts by email: