-
scipy.optimize.minimize 를 이용한 최적화 예시(BFGS, SLSQP)Archive/프로젝트 인사이트 2023. 1. 25. 14:14
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
위의 패키지를 사용하여 코드를 완성하였습니다.
해당 패키지에서는 다음과 같은 method를 사용할 수 있다.
이 중에서 최적값을 찾기 위해 다음의 두 알고리즘을 사용하였다.
- BFGS
최적화를 위해서는 방향, 간격을 정하는 것이 중요하고 그라이언트와 헤시안이 필요함!
하지만 2차 미분인 헤시안을 계산하는 데는 엄청난 컴퓨팅 파워가 소모된다. 따라서 헤시안과 유사한 값을 사용하는 것이 바로 BFGS 임.
제약 조건이 없을 때 사용 가능. - SLSQP
2차방정식으로 근사하여 문제를 풀고, 다음번 지점을 예측하여 다시 동일한 방법을 수행하는 방식으로 최적점을 찾는 방법. 제약조건과 상하한선을 지정 가능
사실 최적화의 이론적 방법론에 대해 짧은 시간 내에 이해하는 것은 너무 어려워서, 패키지의 기능과 최적화가 미분을 이용하여 최적점에 도달한다는 식의 기본적인 이해만 하고 넘어갔다.
추후 시간을 두고 기초적인 이해부터 하고 싶다...
최적화 scipy.optimize.minimize를 실행하기 전에, 목표함수와 bound를 지정하여야 한다.
def f1(pp,*args): p=args[0] q=args[1] epdrandom=args[2] gundang=args[3] price=args[4] p=np.array(p) q=np.array(q) epdrandom=np.array(epdrandom) gundang=np.array(gundang) price=np.array(price) return - ((q + epdrandom * (price *(1-pp) - price *(1-p)) * q /(price * (1-p))) \ * (price * (1-pp)) + gundang).sum() bnds=tuple([[0.3,0.60]])*len(p)
여기서는 앞선 게시물의 논문에서 내가 구현한 매출식을 그대로 갖다 썼다.
수요탄력성에 따라 움직이는 호텔의 매출을 식으로 나타내었다.
여기서 유의할 점은, 최적화할 변수인 pp 말고도 다른 변수들이 식에 포함되어 있는데
이들을 전부 scipy.optimize.minimize 식에서 arg로 지정해 줘야 한다. 그래야 목표 함수 내에서 인식을 하게 된다.
또한 최적화할 변수를 0.3~0.6으로 상한과 하한을 설정하였다.
ppd1 = sp.optimize.minimize(f1, #목표함수 np.array([0.32]*len(p)), #초기값 설정 args=tuple([p,q,epdrandom,gundang,price]), #기타 arg 설정 method='L-BFGS-B',#method 설정 bounds=bnds, #bound 설정 options={'disp':1,'maxiter':1000}) #기타 옵션(과정 print 여부 등)
그리고 그 다음은 매우 쉽다!
옵션 값을 채우기만 하면 된다.
(사실 목표함수를 구현하는게 어려움 ㅠ )
최적화는 매우 예민해서, 초기값과 경계, 제한 조건에 따라 값이 천차만별이 되기 때문에 매우 어렵다.
seed를 설정하거나, 여러번 실행한 뒤 분포를 보고 확률적으로 접근하였다.
'Archive > 프로젝트 인사이트' 카테고리의 다른 글
[최적화] Numerical optimization based on the L-BFGS method (0) 2022.12.30 [논문 리뷰/최적화] Model of Price Optimization as a Part of Hotel Revenue Management- Stochastic Approach (0) 2022.12.20 최적화 linear programming (0) 2022.12.13 Response Surface Methods (0) 2022.12.05 Gradient tape 공부 (0) 2022.12.05 - BFGS