1 왜 이 글이 Math 카테고리에 있는가
전처리 후 모델을 피팅하는 파이프라인, 앙상블 모델, 딥러닝의 end-to-end 학습 — 이 모든 구조의 차이는 결국 함수의 합인가, 합성인가라는 수학적 구분에서 출발한다. 이 구분을 명확히 하면, “파라미터를 따로 추정하는 것”과 “동시에 추정하는 것”이 왜 다른 결과를 내는지가 수식 한 줄로 설명된다. 특정 도메인(PCR 신호, 추천 시스템, NLP 파이프라인 등)에 적용하기 전에, 이 수학적 뼈대를 먼저 잡아야 한다.
2 일상 비유로 먼저 잡기
개념을 수식으로 보기 전에, 식당 비유로 차이를 잡아 보자.
함수의 합 = 뷔페
손님(입력 \(x\))이 들어오면, 한식 코너(\(f\))와 양식 코너(\(g\))에서 각각 독립적으로 음식을 받아 한 접시에 담는다. 한식 코너가 양식 코너에 영향을 주지 않는다. 둘 다 같은 손님을 본다.
\[\text{접시} = f(\text{손님}) + g(\text{손님})\]
합성함수 = 코스 요리
손님(입력 \(x\))이 들어오면, 먼저 전채(\(f\))를 먹고, 그 결과(배 상태, 입맛)가 메인 코스(\(g\))에 전달된다. 메인 코스는 전채 없이는 성립하지 않는다. 순서가 있다.
\[\text{메인} = g(f(\text{손님}))\]
뷔페는 코너를 바꿔도 다른 코너에 영향이 없다. 코스 요리는 전채가 바뀌면 메인의 경험이 달라진다. 이 차이가 병렬 vs 직렬, 그리고 나중에 나올 Sequential vs Joint 추정의 출발점이다.
3 함수의 합 vs 합성함수
3.1 함수의 합: \(f(x) + g(x)\)
같은 입력 \(x\) 를 각 함수에 독립적으로 넣고, 결과를 더한다:
\[h(x) = f(x) + g(x)\]
- 입력: \(x\)
- 출력: \(f(x)\) 와 \(g(x)\) 를 각각 계산 → 더함
- 구조: 병렬(parallel) — 두 함수가 같은 입력을 독립적으로 처리
예시: \(f(x) = x^2\), \(g(x) = 2x\) 일 때
\[f(x) + g(x) = x^2 + 2x\]
3.2 합성함수: \(g(f(x))\)
먼저 \(f(x)\) 를 계산하고, 그 결과를 다시 \(g\) 에 넣는다:
\[h(x) = g(f(x))\]
- 입력: \(x\)
- 흐름: \(x \rightarrow f(x) \rightarrow g(\cdot)\)
- 구조: 직렬(serial) — 한 함수의 출력이 다음 함수의 입력
예시: \(f(x) = x^2\), \(g(x) = 2x\) 일 때
\[g(f(x)) = g(x^2) = 2x^2\]
3.3 핵심 구분 기준
“\(g\) 가 \(f\) 의 출력에 의존하는가?”
| 답 | 구조 | 함수 형태 |
|---|---|---|
| NO — 독립적 | 병렬 | \(f(x) + g(x)\) |
| YES — 의존적 | 직렬 | \(g(f(x))\) |
3.4 직관적 비교
| 구분 | 의미 | 구조 | 데이터 사이언스 대응 |
|---|---|---|---|
| \(f(x)+g(x)\) | 결과를 더함 | 병렬 | feature aggregation, 앙상블 |
| \(g(f(x))\) | 한 함수의 출력이 다른 함수의 입력 | 직렬 | transformation pipeline |
3.5 숫자로 직접 확인
\(f(x) = x^2\), \(g(x) = 2x\) 일 때, \(x = 3\) 을 넣어 보자.
함수의 합:
\[f(3) + g(3) = 9 + 6 = 15\]
\(f\) 와 \(g\) 는 각각 \(x=3\) 을 받아 독립적으로 계산한다.
합성함수:
\[g(f(3)) = g(9) = 18\]
\(f\) 가 먼저 \(3 \rightarrow 9\) 로 변환하고, \(g\) 는 원래 입력 \(3\) 이 아닌 \(f\) 의 출력 \(9\) 를 받는다.
결과가 \(15\) vs \(18\) 로 다르다. 같은 \(f\), \(g\), \(x\) 인데 연산 구조가 다르면 결과가 다르다. 이것이 핵심이다.
\(f(g(3)) = f(6) = 36\) 이다. \(g(f(3)) = 18\) 과 다르다. 합성함수는 순서가 바뀌면 결과도 바뀐다 (교환법칙이 성립하지 않는다). 반면 함수의 합은 \(f(x) + g(x) = g(x) + f(x)\) 로 순서에 무관하다.
4 “파라미터를 따로 추정”하면 더하기인가?
자주 발생하는 오해가 있다. 전처리 함수 \(f\) 와 모델 \(g\) 가 있을 때, 파라미터를 따로 추정하면 “더하기 구조”라고 착각하기 쉽다.
결론: 아니다. 구조와 학습 방식은 분리해서 봐야 한다.
4.1 구조 (Function Form)
전처리 후 모델을 넣는 순간 구조는 이렇게 고정된다:
\[y = g(f(x))\]
- \(f\): 스케일링, 인코딩, feature engineering
- \(g\): 모델 (회귀, 분류 등)
이것은 파라미터를 어떻게 추정하든 합성함수다.
4.2 학습 방식 (Parameter Estimation)
파라미터를 추정하는 방식은 구조와 독립적이다:
| 학습 방식 | 설명 | 함수 구조 |
|---|---|---|
| Sequential | \(f\) 파라미터 먼저 고정 → \(g\) 학습 | \(g(f(x))\) |
| Joint (end-to-end) | \(f\), \(g\) 파라미터 동시 학습 | \(g(f(x))\) |
둘 다 여전히 \(g(f(x))\) 이다. 차이는 구조가 아니라 최적화 방식에 있다.
4.3 “더하기”가 되는 진짜 경우
더하기 구조는 이런 형태다:
\[y = g_1(x) + g_2(x)\]
- 두 함수가 같은 입력 \(x\) 를 독립적으로 처리
- 결과를 합침
대표적 예시를 하나씩 살펴보자.
4.3.1 Residual Fitting (잔차 학습)
“더하기 구조”의 가장 핵심 원리다. 먼저 이것을 이해해야 Gradient Boosting이 보인다.
아이디어: 첫 번째 모델이 못 맞춘 부분을 두 번째 모델이 따로 학습해 더한다.
\[\hat{y} = h_1(x) + h_2(x)\]
- \(h_1(x)\): 처음 모델이 \(x\) 로 예측한 값
- 잔차(residual): \(r = y - h_1(x)\) — 첫 번째 모델이 틀린 양
- \(h_2(x)\): \(h_1\) 의 출력이 아닌 원래 \(x\) 를 받아, 잔차 \(r\) 을 예측
이 구조가 더하기인 이유:
\[\hat{y} = h_1(x) + h_2(x)\]
\(h_2\) 는 \(h_1(x)\) 를 입력으로 받지 않는다. 둘 다 원래 \(x\) 를 독립적으로 입력받고, 그 출력을 더한다.
\(h_2\) 의 학습 목표가 잔차이므로, 학습 중에 \(h_1\) 의 결과를 참조하는 것 같다. 하지만 구조는 \(h_2(h_1(x))\) 가 아니라 \(h_1(x) + h_2(x)\) 다.
- \(h_2(h_1(x))\): \(h_2\)의 입력이 \(h_1\)의 출력 — 합성함수
- \(h_1(x) + h_2(x)\): \(h_2\)의 입력이 여전히 \(x\) — 함수의 합
학습 방식이 이전 단계에 의존하더라도, 예측 구조는 더하기다.
숫자 예시:
\(y = 10\), 입력 \(x = 3\)
- \(h_1(3) = 7\) → 잔차 \(r = 10 - 7 = 3\)
- \(h_2(3) = 3\) (\(x=3\) 을 받아 잔차 \(3\) 을 예측)
- 최종 예측: \(h_1(3) + h_2(3) = 7 + 3 = 10\) ✓
\(h_2\) 의 입력은 \(h_1(3) = 7\) 이 아니라 원래 \(x = 3\) 이다.
4.3.2 Gradient Boosting
Residual Fitting을 반복하는 구조다.
\[y = h_1(x) + h_2(x) + h_3(x) + \cdots + h_T(x)\]
- \(h_1\): 원래 \(x\) 로 \(y\) 를 예측 → 잔차 \(r_1 = y - h_1(x)\)
- \(h_2\): 원래 \(x\) 로 잔차 \(r_1\) 을 예측 → 잔차 \(r_2 = r_1 - h_2(x)\)
- \(h_3\): 원래 \(x\) 로 잔차 \(r_2\) 를 예측 → …
- 모든 \(h_t\) 가 받는 입력: 항상 원래 \(x\)
이렇게 T번 반복하면 최종 예측:
\[\hat{y} = \sum_{t=1}^{T} h_t(x)\]
각 \(h_t\) 는 같은 \(x\) 를 독립적으로 처리하고, 결과를 모두 더한다. 전형적인 함수의 합이다.
구조를 그림으로 보면:
x ─────┬──→ h₁(x) ─┐
├──→ h₂(x) ─┤
├──→ h₃(x) ─┤──→ Σ → ŷ
└──→ ... ─┘
모든 \(h_t\) 가 같은 \(x\) 를 받고, 출력이 마지막에 합산된다.
만약 합성함수였다면 이런 구조일 것이다 (실제로는 이게 아님):
x → h₁(x) → h₂(h₁(x)) → h₃(h₂(h₁(x))) → ŷ
XGBoost, LightGBM, CatBoost 모두 Gradient Boosting 계열이다. 내부적으로 학습 효율을 높이는 방식이 다를 뿐, 예측 구조는 모두 \(\hat{y} = \sum_{t=1}^{T} h_t(x)\) 이다.
4.3.3 GAM (Generalized Additive Model)
\[y = \alpha + f_1(x_1) + f_2(x_2) + \cdots + f_p(x_p)\]
- \(x_1, x_2, \ldots, x_p\): 서로 다른 feature
- 각 \(f_j\): 자신의 feature \(x_j\) 만 입력으로 받는 smooth 함수
- \(f_2\) 는 \(x_1\) 도, \(f_1(x_1)\) 도 모른다
이것이 Gradient Boosting과 다른 점:
| 모델 | 입력 \(x\) | 구조 |
|---|---|---|
| Gradient Boosting | 같은 \(x\) 전체를 각 \(h_t\) 가 받음 | \(\sum_t h_t(x)\) |
| GAM | 각각 다른 \(x_j\) 를 \(f_j\) 가 받음 | \(\sum_j f_j(x_j)\) |
GAM은 “각 feature의 기여도를 따로 추정해 합산” 하는 구조다.
예시: BMI, 나이, 흡연 여부로 질병 위험도를 예측한다면:
\[\text{위험도} = f_1(\text{BMI}) + f_2(\text{나이}) + f_3(\text{흡연})\]
- \(f_1\): BMI 만 보고 위험도 기여분 계산
- \(f_2\): 나이 만 보고 위험도 기여분 계산
- \(f_3\): 흡연 여부 만 보고 위험도 기여분 계산
- 세 함수는 서로를 모른다 — 독립적 병렬 처리
이 구조 덕분에 “BMI가 1 올라가면 위험도가 얼마나 오르나”를 \(f_1\) 만 보고 해석할 수 있다. 높은 해석 가능성이 GAM의 장점이다.
4.3.4 세 예시의 공통점
| 모델 | 함수 형태 | 각 함수의 입력 |
|---|---|---|
| Residual Fitting | \(h_1(x) + h_2(x)\) | 둘 다 원래 \(x\) |
| Gradient Boosting | \(\sum_t h_t(x)\) | 모두 원래 \(x\) |
| GAM | \(\sum_j f_j(x_j)\) | 각자 담당 feature |
세 경우 모두 어떤 함수도 다른 함수의 출력을 입력으로 받지 않는다. 이것이 함수의 합이 되는 기준이다.
5 Sequential vs Joint 추정
같은 합성함수 \(y = g(f(x))\) 구조에서, 파라미터를 어떻게 찾느냐에 따라 결과가 크게 달라진다.
5.1 Sequential 추정 (단계적 추정)
\[\theta_f \rightarrow \theta_g\]
1단계: \(f\) 의 파라미터를 먼저 추정한다
\[\theta_f^* = \arg\min_{\theta_f} L_f(f_{\theta_f}(x))\]
2단계: \(f\) 를 고정한 뒤 \(g\) 를 학습한다
\[\theta_g^* = \arg\min_{\theta_g} L_g(g_{\theta_g}(f_{\theta_f^*}(x)))\]
특징: \(f\) 는 \(g\) 를 고려하지 않는다. 뒤 단계는 앞 단계에 피드백을 주지 않는다.
직관적으로, “좋은 \(f\) 를 먼저 만들고 → 그 위에 \(g\) 를 얹는다”
비유하면: 건축에서 기초 공사를 먼저 완료하고, 그 위에 건물을 올리는 것이다. 기초가 완성된 뒤에는 건물 설계가 기초를 바꿀 수 없다. 기초가 잘못되었으면 건물을 아무리 잘 지어도 한계가 있다.
5.2 Joint 추정 (동시 추정)
\[(\theta_f^*, \theta_g^*) = \arg\min_{\theta_f, \theta_g} L(g_{\theta_g}(f_{\theta_f}(x)))\]
하나의 손실함수로 전체를 같이 학습한다. gradient가 \(g\) 에서 \(f\) 까지 전파된다 (end-to-end).
직관적으로, “최종 예측이 잘 되도록 \(f\), \(g\) 를 같이 맞춘다”
비유하면: 기초와 건물을 동시에 설계하는 것이다. 건물에 수영장이 필요하면 기초부터 내하중을 높이고, 건물이 가벼우면 기초도 가볍게 간다. 최종 목적에 맞게 전체가 조율된다.
5.3 구체적 예시: StandardScaler → Linear Regression
\(x = [1, 2, 3, 100]\) (이상치 포함 데이터)
Sequential: StandardScaler가 먼저 평균/표준편차를 계산하여 정규화한다. 이때 이상치 \(100\) 때문에 표준편차가 커지고, 정상 데이터 \([1,2,3]\) 이 거의 구분 불가능하게 압축된다. Linear Regression은 이 압축된 데이터 위에서 학습하므로 정보가 이미 손실된 상태다.
Joint (만약 가능하다면): “최종 회귀 성능”을 기준으로 정규화 방식 자체를 조정한다. 이상치에 덜 민감한 정규화(예: RobustScaler)로 자동 전환될 수 있다.
이 예시가 보여주는 것: Sequential에서 \(f\) (정규화)는 \(g\) (회귀)를 모른 채 설계된다. 그래서 \(f\) 의 선택이 잘못되면 \(g\) 가 아무리 좋아도 한계가 생긴다.
5.4 비교 정리
| 관점 | Sequential | Joint |
|---|---|---|
| 최적화 | 끊겨 있음 (local optimal 조합) | 연결됨 (global optimal 탐색) |
| 성능 | 정보 손실 가능. \(f\) 가 최종 task에 최적이 아닐 수 있음 | 더 높아질 가능성 큼. task-specific representation 학습 |
| 해석 가능성 | 높음. 각 단계의 의미가 명확 | 낮음. 블랙박스화 |
| 안정성 | 안정적, 재현성 높음 | local minima, overfitting 위험 |
| 데이터 요구량 | 적어도 됨 | 많이 필요 |
5.5 대표 사례
| 방식 | 예시 |
|---|---|
| Sequential | StandardScaler → Linear Regression, PCA → SVM, Feature Engineering → XGBoost |
| Joint | Neural Network (hidden layer = \(f\), output layer = \(g\), 전부 같이 학습) |
6 의사결정 기준
6.1 Sequential이 유리한 경우
- 데이터가 적다
- 해석 가능성이 중요하다
- 전처리가 domain knowledge 기반이다
- 안정성/재현성이 필요하다
6.2 Joint가 유리한 경우
- 데이터가 충분하다
- 표현학습(representation learning)이 중요하다
- 비선형 구조가 필요하다
- 성능이 최우선이다
7 핵심 인사이트
Sequential 추정의 본질적 한계를 한 문장으로 정리하면:
“\(f\) 를 잘못 고르면, 그 위에서 아무리 \(g\) 를 잘 학습해도 한계가 생긴다”
반대로 Joint 추정은:
“\(f\) 자체를 최종 문제에 맞게 변형한다”
이 차이는 순수한 수학적 구분이지만, 실무에서 파이프라인을 설계할 때 가장 먼저 내려야 하는 판단이다. 구체적인 도메인 적용 — 예를 들어 PCR 신호 분석에서 Sequential 추정이 위양성/위음성을 유발하는 메커니즘 — 은 PCR 신호 처리 파이프라인 리팩토링에서 다룬다.
8 관련 주제
선행 지식
- Function — 함수의 기본 정의
- Composite Function — 합성함수의 정의와 정의역
후속 주제
- Taylor Series — 함수 근사와 curvature
다른 카테고리 연결
- PCR 신호 처리 파이프라인 리팩토링 — Sequential 추정의 한계가 PCR 진단에서 실제로 어떻게 문제를 일으키는가
- RT-PCR 진단 알고리즘과 딥러닝 — 의료 규제 관점에서의 모델 설계 원칙