SciPy를 활용한 곡선 맞추기 (curve_fit)
1. 개요
데이터 분석과 과학적 연구에서는 관측된 데이터를 설명하는 수학적 모델을 찾는 과정이 중요합니다. 이러한 모델을 통해 데이터를 분석하고, 예측을 수행하며, 현상을 보다 잘 이해할 수 있습니다. SciPy의 curve_fit
함수는 주어진 데이터를 기반으로 특정 함수 형태에 가장 잘 맞는 최적의 매개변수를 찾는 데 사용됩니다.
이 포스팅에서는 scipy.optimize.curve_fit
을 이용하여 데이터를 곡선에 맞추는 방법을 자세히 설명하고, 다양한 예제를 통해 실습해보겠습니다.
2. curve_fit
함수 개요
scipy.optimize.curve_fit
함수는 비선형 최소제곱법을 이용하여 관측 데이터에 주어진 함수 형태를 적합(fitting)하는 역할을 수행합니다. 이 함수는 다음과 같이 정의됩니다.
scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, bounds=(-inf, inf), method=None, jac=None, **kwargs)
주요 매개변수
- f: 적합할 함수. 첫 번째 인수로 독립 변수, 그 뒤에 매개변수를 받는 형태여야 합니다.
- xdata: 독립 변수 데이터 (예: 관측된 x값).
- ydata: 종속 변수 데이터 (예: 관측된 y값).
- p0: 매개변수의 초기 추정값 (기본값은 None).
- sigma: ydata의 표준 편차 (가중치 부여 시 사용).
- bounds: 매개변수의 상한과 하한 범위 (기본값은 무한대).
반환값
curve_fit
함수는 다음 두 가지를 반환합니다.
- popt: 최적화된 매개변수의 배열.
- pcov: 매개변수 추정값의 공분산 행렬.
3. 간단한 예제: 선형 함수에 맞추기
가장 기본적인 예제로, 선형 함수 y = a*x + b
형태로 데이터를 생성하고 이를 curve_fit
을 이용해 적합해보겠습니다.
예제 코드
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# 선형 함수 정의
def linear_func(x, a, b):
return a * x + b
# 샘플 데이터 생성
x_data = np.linspace(0, 10, 50)
y_data = 2.5 * x_data + 1.3 + np.random.normal(0, 1, size=len(x_data))
# curve_fit 적용
popt, pcov = curve_fit(linear_func, x_data, y_data)
# 결과 출력
print("최적의 매개변수 a와 b:", popt)
# 시각화
plt.scatter(x_data, y_data, label='관측된 데이터')
plt.plot(x_data, linear_func(x_data, *popt), color='red', label='적합된 선형 함수')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
실행 결과
최적의 매개변수는 약 a ≈ 2.5
와 b ≈ 1.3
으로 추정됩니다. 이는 우리가 데이터를 생성할 때 사용한 값과 유사합니다.
4. 비선형 함수에 맞추기
이번에는 비선형 함수인 2차 다항식 형태의 함수 y = ax^2 + bx + c
에 데이터를 적합해보겠습니다.
예제 코드
# 2차 다항식 함수 정의
def quadratic_func(x, a, b, c):
return a * x**2 + b * x + c
# 샘플 데이터 생성
a_true, b_true, c_true = 1.5, -2.3, 0.8
x_data = np.linspace(0, 10, 100)
y_data = quadratic_func(x_data, a_true, b_true, c_true) + np.random.normal(0, 2, size=len(x_data))
# curve_fit 적용
popt, pcov = curve_fit(quadratic_func, x_data, y_data)
# 결과 출력
print("최적의 매개변수 a, b, c:", popt)
# 시각화
plt.scatter(x_data, y_data, label='관측된 데이터', s=10)
plt.plot(x_data, quadratic_func(x_data, *popt), color='green', label='적합된 곡선')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
실행 결과
최적화된 매개변수는 실제 값과 매우 유사하게 추정됩니다.
5. 상한과 하한 범위 설정하기
경우에 따라 특정 매개변수의 범위를 제한해야 할 수도 있습니다. 예를 들어, 물리적 의미에서 음수가 되어서는 안 되는 매개변수 등을 제한할 수 있습니다.
예제 코드
# 지수 함수 정의
def exp_func(x, a, b):
return a * np.exp(b * x)
# 데이터 생성
x_data = np.linspace(0, 5, 50)
y_data = exp_func(x_data, 2.0, 0.5) + np.random.normal(0, 0.2, size=len(x_data))
# 범위 설정 (a는 양수, b는 -1 ~ 1)
popt, pcov = curve_fit(exp_func, x_data, y_data, bounds=([0, -1], [10, 1]))
print("최적의 매개변수 a와 b:", popt)
이와 같이 bounds
매개변수를 사용하면 매개변수의 상한과 하한을 설정할 수 있습니다.
6. 가중치 적용
모든 데이터가 동일한 신뢰도를 갖는 것은 아닐 수 있습니다. 예를 들어, 관측 오차가 큰 데이터는 신뢰도가 낮으므로 적합 과정에서 덜 반영되도록 가중치를 설정할 수 있습니다.
예제 코드
# 가중치 적용 예제
sigma = np.ones_like(y_data)
sigma[20:30] = 5.0 # 특정 구간에 큰 오차 부여
# curve_fit 적용
popt, pcov = curve_fit(quadratic_func, x_data, y_data, sigma=sigma)
sigma
값을 설정하면 오차가 큰 데이터는 적합 과정에서 영향을 덜 미치게 됩니다.
7. 결론
scipy.optimize.curve_fit
은 비선형 최소제곱법을 이용해 데이터에 적합한 곡선을 찾는 강력한 도구입니다. 선형, 비선형 함수에 모두 사용할 수 있으며, 범위 제한, 가중치 부여 등 다양한 상황에 맞춰 유연하게 활용 가능합니다.
실제 분석이나 연구 과정에서 적합한 모델을 찾는 과정은 데이터를 이해하고 예측력을 높이는 데 중요한 역할을 하므로, curve_fit
을 잘 활용하면 유용한 인사이트를 얻을 수 있을 것입니다.
'Python SciPy' 카테고리의 다른 글
SciPy를 활용한 필터 설계 및 적용 (butter, filtfilt) (0) | 2025.03.11 |
---|---|
SciPy.optimize - 제약 조건과 경계 설정 방법 (0) | 2025.03.10 |
비선형 방정식 찾기 (SciPy.optimize.root) (0) | 2025.03.08 |
SciPy.optimize를 활용한 최소화 문제 해결 (minimize) (0) | 2025.03.07 |
SciPy를 활용한 행렬식과 역행렬 계산 (0) | 2025.03.06 |