# 민감도 분석과 편미분 근사

## 민감도 분석의 기초

민감도 분석은 수치 해석에서 시스템의 출력이 입력 변수의 변화에 얼마나 민감하게 반응하는지를 평가하는 중요한 기법입니다. 이는 수치 미분을 통해 각 입력 변수에 대한 출력의 변화율을 계산함으로써 이루어집니다. 민감도 분석은 특히 최적화 문제나 모델링에서 중요한 역할을 하며, 예측 모델이나 시스템의 안정성 및 신뢰성을 평가할 때 유용합니다.

일반적으로 시스템의 출력 $y$가 입력 변수 $\mathbf{x} = (x\_1, x\_2, \dots, x\_n)$에 의존한다고 가정할 때, 민감도는 각 변수 $x\_i$에 대한 출력 $y$의 변화율로 정의됩니다. 수학적으로는 편미분을 사용하여 표현됩니다.

### 편미분

편미분은 다변수 함수에서 각 변수에 대해 미분을 계산하는 방법입니다. 입력 변수 $\mathbf{x}$가 여러 개일 때, 출력 $y$에 대한 특정 변수 $x\_i$의 편미분은 다른 변수들을 고정시킨 채로 $x\_i$만 변화시킨 경우의 출력 변화율을 나타냅니다. 이를 수학적으로 표현하면 다음과 같습니다:

$$
\frac{\partial y}{\partial x\_i} = \lim\_{\Delta x\_i \to 0} \frac{y(\mathbf{x} + \Delta x\_i \hat{\mathbf{e}}\_i) - y(\mathbf{x})}{\Delta x\_i}
$$

여기서 $\hat{\mathbf{e}}\_i$는 $i$번째 단위 벡터이며, $\Delta x\_i$는 $x\_i$의 작은 변화입니다. 편미분은 특정 변수에 대해 함수의 변화율을 정확히 계산하는 데 유용합니다.

## 수치적 편미분 근사

실제로 편미분을 계산하려면 수치적 근사가 필요합니다. 연속적인 변화에 대한 근사 값은 차분 방식을 통해 구할 수 있으며, 일반적으로 앞차분, 뒤차분, 중앙차분 방법을 사용합니다. 이 방법들은 함수의 값을 이웃한 점에서 차이를 사용하여 미분 값을 추정합니다.

### 중앙차분 근사

중앙차분 방법은 함수의 미분을 양쪽 방향에서의 차이를 이용하여 근사하는 방법입니다. 이 방법은 앞차분이나 뒤차분 방법보다 더 정확한 근사를 제공합니다. $x\_i$에서의 함수 $f(x\_i)$의 미분은 다음과 같이 중앙차분 방법을 통해 근사할 수 있습니다:

$$
\frac{\partial y}{\partial x\_i} \approx \frac{y(\mathbf{x} + h \hat{\mathbf{e}}\_i) - y(\mathbf{x} - h \hat{\mathbf{e}}\_i)}{2h}
$$

여기서 $h$는 매우 작은 값으로, 두 점 사이의 간격을 나타냅니다. 이 방법은 이론적으로 2차 정확도를 가지므로 수치적으로 더 정확한 결과를 얻을 수 있습니다.

### 앞차분 및 뒤차분 근사

앞차분과 뒤차분 방법은 각각 한 방향에서만 차이를 구하는 방법입니다. 이 방법들은 중앙차분에 비해 정확도가 낮지만 계산이 더 간단합니다.

앞차분은 다음과 같이 정의됩니다:

$$
\frac{\partial y}{\partial x\_i} \approx \frac{y(\mathbf{x} + h \hat{\mathbf{e}}\_i) - y(\mathbf{x})}{h}
$$

뒤차분은 반대로 다음과 같습니다:

$$
\frac{\partial y}{\partial x\_i} \approx \frac{y(\mathbf{x}) - y(\mathbf{x} - h \hat{\mathbf{e}}\_i)}{h}
$$

이들은 각각 1차 정확도를 제공하며, 상황에 따라 적합하게 선택할 수 있습니다.

## 민감도 분석을 통한 모델 해석

민감도 분석은 모델의 각 입력 변수에 대해 어떻게 출력이 변화하는지 이해할 수 있는 중요한 도구입니다. 예를 들어, 수치 모델링에서 여러 매개변수가 있을 때, 각 매개변수의 변화가 결과에 미치는 영향을 평가하는 데 유용합니다. 이 분석을 통해 민감도가 큰 변수는 모델링에 더 많은 주의를 기울여야 함을 알 수 있습니다. 반대로 민감도가 작은 변수는 모델링에서 적은 중요성을 가질 수 있습니다.

민감도 분석은 또한 최적화 문제에 필수적입니다. 예를 들어, 비용 함수나 목적 함수의 민감도를 분석하면, 최적화 과정에서 중요한 매개변수를 더 잘 선택할 수 있습니다.

## 수치적 민감도 분석 예시

다음은 수치적 민감도 분석을 위한 간단한 예시로, 2차 함수 $f(x\_1, x\_2) = x\_1^2 + 2x\_2^2$의 민감도를 분석하는 것입니다.

이 함수의 출력은 두 변수 $x\_1$과 $x\_2$에 의존하므로, 이들 각각에 대한 민감도를 계산할 수 있습니다. 먼저 $x\_1$에 대한 편미분을 계산하면:

$$
\frac{\partial f}{\partial x\_1} = 2x\_1
$$

$ x\_1 $의 값이 3일 때, 민감도는 $ 2 \times 3 = 6 $이 됩니다.

$ x\_2 $에 대해서는:

$$
\frac{\partial f}{\partial x\_2} = 4x\_2
$$

$ x\_2 $의 값이 2일 때, 민감도는 $ 4 \times 2 = 8 $이 됩니다.

이 예시에서 알 수 있듯이, 각 입력 변수에 대한 민감도를 계산하면, 어떤 변수가 출력에 더 큰 영향을 미치는지를 알 수 있습니다.

## 편미분 근사의 정확도

수치적 편미분 근사는 정확한 편미분을 계산하는 데 필요한 이론적인 해법이지만, 근사 오차가 존재합니다. 이 오차는 사용되는 차분 방법, 그라디언트 근사의 정확도, 그리고 사용되는 간격의 크기에 따라 달라집니다.

### 오차 계수와 차분 방법

수치적 미분에서 발생하는 오차는 일반적으로 $O(h)$ 또는 $O(h^2)$의 크기를 가지며, 이는 $h$가 간격의 크기일 때의 근사 오차입니다. 여기서 $h$는 매우 작은 값으로 설정됩니다. 각 차분 방법에 따른 정확도는 다음과 같습니다.

1. **앞차분 (Forward Difference)**: 앞차분 방법의 오차 계수는 $O(h)$로, 이는 일차 정확도를 나타냅니다. 즉, $h$가 매우 작아지면 오차가 선형적으로 감소합니다.
2. **뒤차분 (Backward Difference)**: 뒤차분 방법도 앞차분과 동일하게 $O(h)$ 오차를 가지며, 일차 정확도를 가집니다.
3. **중앙차분 (Central Difference)**: 중앙차분 방법은 오차 계수가 $O(h^2)$입니다. 이는 이차 정확도를 의미하며, $h$가 감소할 때 오차가 제곱 비율로 감소합니다. 이 방법은 앞차분이나 뒤차분보다 더 높은 정확도를 제공하므로 선호됩니다.

따라서, 가능한 한 작은 값의 $h$를 선택하되, 너무 작은 값은 부동소수점 오차나 수치적 불안정성을 초래할 수 있음을 유의해야 합니다.

### 오차 분석

편미분 근사에서 발생하는 오차는 두 가지 주요 요소로 나눌 수 있습니다. 첫째는 **절대 오차**로, 이는 계산된 미분 값과 실제 미분 값의 차이를 의미합니다. 둘째는 **상대 오차**로, 이는 계산된 미분 값이 실제 미분 값에 비해 얼마나 부정확한지에 대한 비율입니다.

절대 오차는 일반적으로 $h$의 크기에 비례하며, $h$가 너무 작으면 **소수점 아래의 오차**가 커지게 되어 정확도가 떨어질 수 있습니다. 상대 오차는 문제의 스케일과 조건에 따라 달라지므로 각 경우에 맞는 적절한 차분 방법을 선택하는 것이 중요합니다.

## 수치적 민감도 분석 구현

다음은 Octave를 이용하여 수치적 민감도 분석을 구현하는 예시입니다. 이 예시에서는 2변수 함수 $f(x\_1, x\_2) = x\_1^2 + 2x\_2^2$에 대한 민감도를 계산합니다. 중앙차분 방법을 사용하여 각각의 편미분 값을 근사합니다.

```octave
% 함수 정의
f = @(x1, x2) x1^2 + 2*x2^2;

% 변수 값 설정
x1 = 3;
x2 = 2;

% 차분 간격 h 설정
h = 1e-6;

% 중앙차분 방법을 사용한 편미분 근사
dfdx1 = (f(x1+h, x2) - f(x1-h, x2)) / (2*h);
dfdx2 = (f(x1, x2+h) - f(x1, x2-h)) / (2*h);

% 결과 출력
disp(['df/dx1 = ', num2str(dfdx1)]);
disp(['df/dx2 = ', num2str(dfdx2)]);
```

위 코드에서 `f`는 함수 $f(x\_1, x\_2) = x\_1^2 + 2x\_2^2$이고, `h`는 차분 간격으로, 매우 작은 값인 $1 \times 10^{-6}$으로 설정되었습니다. 중앙차분 방법을 사용하여 두 변수에 대한 편미분 값을 계산하고, 이를 출력합니다.

이 코드는 $x\_1 = 3$과 $x\_2 = 2$에서의 민감도를 계산하며, 결과는 다음과 같습니다:

```
df/dx1 = 6
df/dx2 = 8
```

이는 앞서 수학적으로 계산한 민감도 값과 일치합니다.

## 민감도 분석의 활용

민감도 분석은 시스템이나 모델의 안정성을 평가하고, 매개변수 조정의 우선순위를 결정하는 데 매우 유용합니다. 예를 들어, 시뮬레이션 또는 최적화 문제에서 출력에 큰 영향을 미치는 변수를 찾아내면, 해당 변수를 조정하여 시스템의 성능을 최적화할 수 있습니다. 또한, 민감도 분석은 모델의 불확실성 분석에도 활용되며, 결과적으로 모델링의 신뢰성을 높이는 데 기여합니다.

이와 같은 방법은 다양한 분야에서 활용되며, 특히 공학, 경제학, 생물학적 모델링 등에서 중요하게 다뤄집니다.

## 고차원에서의 민감도 분석

고차원의 문제에서는 민감도 분석이 더욱 복잡해지며, 고차원의 벡터 및 행렬 연산을 포함합니다. 이 경우, 각 변수에 대한 민감도를 동시에 고려해야 하며, 여러 입력 변수의 상호작용에 대한 영향을 분석하는 것이 중요합니다.

### 다변수 함수에서의 민감도 분석

고차원 문제에서는 다변수 함수에 대한 민감도를 분석하는 데 있어 **그라디언트 벡터**를 사용하는 것이 일반적입니다. 함수 $y = f(\mathbf{x})$가 $n$개의 변수 $\mathbf{x} = (x\_1, x\_2, \dots, x\_n)$에 의존한다고 할 때, 출력 $y$에 대한 모든 변수들의 민감도는 **그라디언트**로 나타낼 수 있습니다. 그라디언트는 각 변수에 대한 편미분의 벡터로 정의됩니다.

$$
\nabla f(\mathbf{x}) = \left( \frac{\partial f}{\partial x\_1}, \frac{\partial f}{\partial x\_2}, \dots, \frac{\partial f}{\partial x\_n} \right)
$$

여기서 $\nabla f(\mathbf{x})$는 $f(\mathbf{x})$의 그라디언트 벡터이며, 이 벡터의 각 성분은 $f(\mathbf{x})$에 대한 각 입력 변수 $x\_i$의 편미분 값입니다. 이 벡터를 사용하여 함수의 출력이 입력 변수에 대해 어떻게 변화하는지를 동시에 분석할 수 있습니다.

### 민감도 분석에서의 효율적인 방법

고차원에서 민감도 분석을 수행할 때는 다음과 같은 효율적인 방법들을 사용할 수 있습니다.

#### 1. **선형화 (Linearization)**

고차원 시스템에서는 모델을 **선형화**하여 근사하는 방법이 유용할 수 있습니다. 입력 변수의 작은 변화에 대해 시스템의 출력 변화가 선형적으로 근사될 수 있다면, **선형 근사**를 통해 복잡한 민감도 분석을 간소화할 수 있습니다.

선형화는 Taylor 전개를 통해 이루어집니다. $f(\mathbf{x})$가 주어졌을 때, $\mathbf{x}$에서의 1차 근사는 다음과 같이 표현됩니다:

$$
f(\mathbf{x} + \Delta \mathbf{x}) \approx f(\mathbf{x}) + \nabla f(\mathbf{x})^T \Delta \mathbf{x}
$$

여기서 $\Delta \mathbf{x}$는 입력 변수의 변화이며, $\nabla f(\mathbf{x})$는 함수의 그라디언트입니다.

#### 2. **로우시스키 (Rosenbrock) 방법**

로우시스키 방법은 비선형 최적화 문제에서 자주 사용되는 방법으로, 민감도 분석을 통해 목적 함수의 변화와 매개변수 간의 관계를 해석할 수 있습니다. 이 방법은 최적화 문제에서의 변수 조정을 통해 민감도를 평가하는 데 유용합니다.

## 수치적 민감도 분석: 고차원 예시

고차원 시스템에 대한 수치적 민감도 분석을 C++ 코드로 구현할 수 있습니다. 다음은 3개의 입력 변수 $x\_1, x\_2, x\_3$에 대한 함수 $f(x\_1, x\_2, x\_3) = x\_1^2 + x\_2^2 + x\_3^2$의 민감도를 중앙차분 방법을 사용하여 계산하는 예시입니다.

```cpp
#include <iostream>
#include <cmath>

using namespace std;

// 함수 정의
double f(double x1, double x2, double x3) {
    return pow(x1, 2) + pow(x2, 2) + pow(x3, 2);
}

// 중앙차분을 이용한 수치적 편미분 근사
double centralDifference(double (*func)(double, double, double), double x1, double x2, double x3, int varIndex, double h) {
    double deltaX[3] = {0, 0, 0};
    deltaX[varIndex] = h;

    double fPlus = func(x1 + deltaX[0], x2 + deltaX[1], x3 + deltaX[2]);
    double fMinus = func(x1 - deltaX[0], x2 - deltaX[1], x3 - deltaX[2]);
    return (fPlus - fMinus) / (2 * h);
}

int main() {
    double x1 = 3.0, x2 = 2.0, x3 = 1.0;
    double h = 1e-6;

    // 각 변수에 대한 편미분 근사
    double dfdx1 = centralDifference(f, x1, x2, x3, 0, h);
    double dfdx2 = centralDifference(f, x1, x2, x3, 1, h);
    double dfdx3 = centralDifference(f, x1, x2, x3, 2, h);

    // 결과 출력
    cout << "df/dx1 = " << dfdx1 << endl;
    cout << "df/dx2 = " << dfdx2 << endl;
    cout << "df/dx3 = " << dfdx3 << endl;

    return 0;
}
```

이 C++ 코드는 함수 $f(x\_1, x\_2, x\_3) = x\_1^2 + x\_2^2 + x\_3^2$에 대해 각각의 입력 변수에 대한 민감도를 중앙차분 방법을 사용하여 계산합니다. 변수 $x\_1 = 3$, $x\_2 = 2$, $x\_3 = 1$에서의 민감도를 구한 결과는 다음과 같습니다:

```
df/dx1 = 6
df/dx2 = 4
df/dx3 = 2
```

이 결과는 수학적으로 미리 계산한 값과 일치합니다. 이와 같은 방법을 통해 고차원 함수에 대해서도 효율적으로 민감도 분석을 수행할 수 있습니다.

## 민감도 분석과 최적화

민감도 분석은 최적화 과정에서도 중요한 역할을 합니다. 최적화 문제에서는 민감도가 큰 변수에 대해 더 많은 조정이 필요할 수 있습니다. 민감도가 큰 변수는 최적화 방향에 큰 영향을 미치므로, 이들에 대한 세심한 조정이 필요합니다.

예를 들어, \*\*경사 하강법(Gradient Descent)\*\*을 사용하는 경우, 함수의 그라디언트를 기반으로 각 변수의 값을 조정합니다. 이때 민감도가 큰 변수는 경사 방향으로 더 큰 변화를 겪게 되며, 민감도가 작은 변수는 상대적으로 적은 영향을 받습니다. 따라서 민감도 분석을 통해 변수별로 조정량을 적절히 설정하는 것이 중요합니다.
