Python for AI, Embedded/Data Science: NumPy, Pandas, SciPy

SciPy 스플라인 보간 (UnivariateSpline)

임베디드 친구 2025. 12. 5. 20:46
반응형

SciPy 스플라인 보간 (UnivariateSpline)

1. 스플라인 보간이란?

스플라인 보간(Spline Interpolation)은 데이터를 부드러운 곡선으로 연결하는 기법으로, 주어진 데이터 포인트 사이를 다항식으로 보간하는 방법입니다. 특히, UnivariateSpline은 하나의 독립 변수에 대한 스플라인 보간을 수행하는 SciPy의 유용한 도구입니다.

일반적인 보간법(선형, 다항식 등)은 단순하지만 데이터가 복잡하거나 불규칙한 경우에는 정확성이 떨어질 수 있습니다. 반면, 스플라인 보간은 자연스럽고 부드러운 곡선을 생성하면서도 과적합(overfitting)을 피할 수 있습니다.

SciPy의 scipy.interpolate.UnivariateSpline 클래스는 B-스플라인(basis spline)을 이용하여 데이터를 보간하고, 사용자가 곡선의 부드러움을 조절할 수 있도록 설계되었습니다.


2. 스플라인 보간의 원리

스플라인 보간은 데이터를 구간별로 다항식을 이용해 보간하는 방식입니다. 각 구간에서 저차원의 다항식을 사용하면서, 구간 경계에서는 연속성과 매끄러움을 유지하도록 설계됩니다.

UnivariateSpline은 다음과 같은 기본 원리로 작동합니다:

  1. 노드(node) 설정: 데이터 포인트를 기준으로 스플라인의 결절점(knots)을 설정합니다.
  2. 다항식 구성: 각 구간에서 3차 다항식(큐빅 스플라인)을 사용하여 데이터를 보간합니다.
  3. 연속성 보장: 구간 경계에서 함수 값과 도함수가 연속되도록 제약을 부과합니다.
  4. 부드러움 조정: 스무딩 파라미터(s)를 통해 곡선의 부드러움을 조정합니다.

3. UnivariateSpline의 주요 매개변수

scipy.interpolate.UnivariateSpline 클래스는 다음과 같은 주요 매개변수를 지원합니다.

  • x: 보간할 데이터의 x 좌표 (1차원 배열)
  • y: 보간할 데이터의 y 좌표 (1차원 배열)
  • s: 스무딩 파라미터 (기본값: 0)
    • s=0: 모든 데이터 포인트를 정확히 통과하는 곡선 (과적합 가능)
    • s>0: 일정 수준의 오차를 허용하고 부드러운 곡선 생성
  • k: 스플라인의 차수 (기본값: 3)
  • ext: 외삽 방법 (0: 오류, 1: 가장자리 값 사용 등)

4. UnivariateSpline 사용 예제

아래는 UnivariateSpline을 사용하여 스플라인 보간을 수행하는 간단한 예제입니다.

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline

# 예제 데이터 생성
x = np.linspace(0, 10, 10)
y = np.sin(x)

# 노이즈 추가
y_noisy = y + 0.1 * np.random.normal(size=len(x))

# 스플라인 보간 수행
spline = UnivariateSpline(x, y_noisy, s=0.5)
x_fine = np.linspace(0, 10, 1000)
y_spline = spline(x_fine)

# 그래프 시각화
plt.figure(figsize=(10, 6))
plt.plot(x, y_noisy, 'o', label='노이즈가 추가된 데이터')
plt.plot(x_fine, y_spline, label='스플라인 보간 (s=0.5)', color='orange')
plt.plot(x_fine, np.sin(x_fine), '--', label='원본 함수', color='green')
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('UnivariateSpline을 이용한 스플라인 보간')
plt.grid(True)
plt.show()

결과 해석

  1. 노이즈가 추가된 데이터: 원본 sin(x) 함수에 약간의 잡음을 추가한 데이터입니다.
  2. 스플라인 보간: s=0.5로 설정하여 부드러운 곡선을 생성했습니다.
  3. 원본 함수: 보간된 곡선이 실제 sin(x) 함수와 유사하게 나타나는 것을 확인할 수 있습니다.

5. 스무딩 파라미터(s)의 역할

스무딩 파라미터 s는 보간 곡선의 부드러움을 조절하는 중요한 역할을 합니다.

  • s=0: 데이터 포인트를 모두 정확히 통과하지만, 노이즈의 영향을 크게 받아 과적합될 수 있습니다.
  • 적절한 s: 약간의 오차를 허용하면서, 노이즈의 영향을 줄이고 부드러운 곡선을 생성합니다.
  • s가 클 때: 과도하게 부드러운 곡선이 생성되며, 데이터의 주요 특징이 무시될 수 있습니다.

예제: s 값에 따른 보간 결과

plt.figure(figsize=(12, 8))

for i, s in enumerate([0, 0.5, 5], 1):
    plt.subplot(3, 1, i)
    spline = UnivariateSpline(x, y_noisy, s=s)
    y_spline = spline(x_fine)
    plt.plot(x, y_noisy, 'o', label='노이즈가 추가된 데이터')
    plt.plot(x_fine, y_spline, label=f'스플라인 보간 (s={s})', color='orange')
    plt.legend()
    plt.xlabel('x')
    plt.ylabel('y')
    plt.grid(True)

plt.suptitle('스무딩 파라미터 s 값에 따른 보간 결과')
plt.tight_layout()
plt.show()

6. 스플라인 도함수와 적분

UnivariateSpline을 이용하면 보간된 곡선의 미분적분도 쉽게 수행할 수 있습니다.

(1) 도함수 계산

# 1차 도함수 계산
spline_derivative = spline.derivative(n=1)

# 도함수 값
y_derivative = spline_derivative(x_fine)

plt.figure(figsize=(10, 6))
plt.plot(x_fine, y_spline, label='스플라인 보간 곡선')
plt.plot(x_fine, y_derivative, label='1차 도함수', color='red')
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('스플라인 보간 곡선과 1차 도함수')
plt.grid(True)
plt.show()

(2) 적분 계산

# 0~10 구간의 적분 값
integral_value = spline.integral(0, 10)
print(f"0에서 10까지의 스플라인 보간 곡선의 적분 값: {integral_value:.4f}")

7. UnivariateSpline의 장점과 한계

장점:

  1. 부드러운 보간: 데이터를 자연스럽게 연결하는 부드러운 곡선을 생성합니다.
  2. 스무딩 조절: s 매개변수를 통해 노이즈를 무시하면서 최적의 곡선을 찾을 수 있습니다.
  3. 미분과 적분: 보간된 곡선의 도함수와 적분을 간단하게 구할 수 있습니다.

한계:

  1. 고차원 데이터 제한: UnivariateSpline은 1차원 데이터에만 사용 가능합니다. 다차원 데이터는 interp2dgriddata를 사용해야 합니다.
  2. 과적합 가능성: s=0으로 설정하면 모든 데이터를 정확히 통과하는 과적합이 발생할 수 있습니다.

8. 결론

스플라인 보간, 특히 UnivariateSpline은 데이터의 부드러운 보간과 분석에 강력한 도구입니다. 적절한 스무딩 파라미터를 선택하면 노이즈의 영향을 줄이면서 신뢰성 높은 보간 곡선을 얻을 수 있습니다.

실제 데이터 분석이나 시뮬레이션에서 스플라인 보간을 활용하면, 불완전한 데이터에서도 정확한 추정과 예측이 가능합니다. 특히 과학, 공학, 금융 등 다양한 분야에서 데이터 분석과 시각화에 널리 사용되고 있습니다.

반응형