오늘은 최근에 여러 공부를 하면서 굉장히 유용하다고 느낀 함수인 Scipy 패키지의 optimizie 함수에 대해 정리해보도록 하겠다. 내용의 출처는 ChatGPT와 https://scipy.org/ (패키지의 소개 홈페이지) 이다.
Scipy 패키지
scipy 패키지는 여러 계산 과정에서 굉장히 유용하게 사용되는 패키지이다. 최적화, 보간법, 선형대수 등 여러 수학적인 계산을 넘어서 통계와 이미지 처리 까지 지원해주는 함수들이 내장되어 있다. 오늘 정리할 함수는 이 중 최적화를 도와주는 optimize function이다.
Optimize 함수
https://docs.scipy.org/doc/scipy/tutorial/optimize.html#
위의 사이트로 들어가보면 Optimize 함수의 여러 기능들이 소개되어 있다. 굉장히 많은 이론들이 집약되어 있는데 이 내용들을 모두 공부하고 있기엔 머리가 그만큼 좋지도 않을 뿐더러 의욕도 생기지 않는다. 그래서 핵심적인 부분만 ChatGPT를 통해 살펴보았는데,
1. Minimize - 최소화
2. Root Finding - 해 구하기
3. Curve Fit - Least Square를 이용한 곡선 적합
4. Linear Programming - 선형계획법
이 핵심적인 함수들이라고 한다. Scipy 패키지가 굉장히 강력해 보이는 것이 홈페이지의 문서를 얼핏 살펴만 봐도 웬만한 방정식의 해는 다 구할 수 있고, LP 문제 뿐만 아니라 MIP, Assignment Problem 등 복잡한 문제들도 풀 수 있는 것으로 느껴진다. 기회가 되면 이런 부분들을 해보기로 하고, 내가 공부하면서 사용했던 Minimize 함수와 그 코드를 공유해보고자 한다.
Minimize 함수 사용해보기
min_alpha = 1
min_value = 10000
def bias(lst, result):
bias = 0
for i in range(len(result)):
bias+=(lst[i]-result[i])
bias = bias/len(result)
return bias
for i in range(1, 101):
alpha = i / 100
if bias(lst[1:],ES(alpha, lst))< min_value:
min_value = bias(lst[1:], ES(alpha, lst))
min_alpha = alpha
print(min_alpha, min_value)
Bias를 최소화 시켜주는 alpha 값을 찾는 문제를 풀고 있는 상황이다. 내가 프로그래밍을 자바로 시작해서 그런지, 처음엔 패키지를 사용할 생각을 못 하고 이런 식으로 문제를 풀었다. 이 때는 i를 100번만 실행하면 되기 때문에 1초 정도밖에 걸리지 않았는데, 문제는 다음 상황에서 발생했다.
min_alpha = 1
min_beta = 1
min_gamma = 1
min_value = 10000
for i in range(0, 1001):
for j in range(0, 1001):
for k in range(0, 1001):
alpha = i / 1000
beta = j / 1000
gamma = k / 1000
forecast = Winters(lst2, sf_lst2, alpha, beta, gamma)
if msd(lst2[4:],forecast)< min_value:
min_value = msd(lst2[4:],forecast)
min_alpha = alpha
min_beta = beta
min_gamma = gamma
print(min_alpha,min_beta,min_gamma, min_value)
for 문을 3중으로 구성하고 범위를 1000까지 늘렸더니 시간복잡도가 말도 안 되게 증가해버린 것이다. 이런 식으로 코드가 짜여지면 내 노트북처럼 평범한 CPU로는 몇 시간이 걸릴지 모를 노릇이다. 따라서 다른 방법을 찾아야 했고, 이걸 해결해준 것이 바로 Minimize Function이다.
minimize function을 사용하려면 우선 최소한 2가지 Parameter가 필요하다.
1. 최소화하고자 하는 함수
2. 해를 찾아나가기 시작할 시작점
그리고 필요하다면 Method, Bounds, Constraint 등을 추가할 수 있다. 문제상황에 맞게 설정하면 될 것이다.
from scipy.optimize import minimize
def objective(x):
alpha, beta, gamma = x
sesonal, forecast = Winters(lst2, sf_lst2, alpha, beta, gamma)
return msd(lst2[4:], forecast)
initial_guess = [0.5, 0.5, 0.5]
bounds = [(0, 1), (0, 1), (0, 1)]
result = minimize(objective, initial_guess, bounds=bounds)
print(result.x)
print(result.fun)
For문을 사용해서 해를 찾았던 것을 Minimize 함수를 통해 최적해를 찾은 모습이다.
나는 원하는 해의 범위가 0부터 1 사이여야했으므로 Bound를 설정해주었고, 최소화하고자 하는 함수는 따로 정의, 시작점은 임의로 모두 0.5 로 고정시켜주었다. 그랬더니 거의 1초만에 최적해를 찾아주었다. BFGS 라는 method가 default로 지정되어 있어 이 방법을 사용했을 터인데, 얼핏 찾아보니 머신러닝에서 해를 찾는 방법으로 널리 사용되고 있는 알고리즘이라고 한다. 속도가 이렇게나 빠르니 괜히 널리 사용되는 것이 아니구나 싶었다.
참고로 Maximization 문제를 풀고 싶다면, Max를 찾아주는 maximize 함수는 따로 존재하지 않으므로 목적함수의 부호를 바꾸어준 뒤 minimize 함수를 적용해야 할 것이다.
'파이썬' 카테고리의 다른 글
파이썬 - 텍스트 데이터 전처리 파이프라인 (1) : 한국어 텍스트 전처리 (0) | 2023.08.19 |
---|---|
파이썬 오류 기록 - LGBM, Python, Dask 관련 AttributeError (0) | 2023.06.04 |
파이썬 - 단순 계산하는 과제 함수 선언해서 쉽게 해결하기 (0) | 2023.04.12 |
파이썬 - KBO 선수 기록 크롤링해서 엑셀로 저장하기 (0) | 2023.02.20 |
파이썬 - ARIMA predict 함수 오류 기록 (0) | 2023.02.08 |