<jupyter_start><jupyter_text>변분법 - 입력인 함수가 변할 떼 범함수의 출력이 어떻게 달라지는가를 계산하는 학문 - 범함수     * function y(x) $\rightarrow$ functional F $\rightarrow$ real number      - 입력이 함수처럼 생겼는데 대괄호로 되어 있으면 범함수 : $F[y(x)]$       - $E[p(x)] = \int^\infty_{-\infty} xp(x)dx$            - $H[p(x)] = -\int^\infty_{-\infty} p(x) log p(x)dx$ --- 최적화 기초 - 함수가 주어졌을 때 그 값이 가장 작아지거나 가장 커지는 위치를 찾는 것       - $x* = argmax_xf(x)$      - $x* = argmin_xf(x)$        최소화 하려는 함수 $f(x)$       - 목적함수 (objective function)       - 비용함수 (cost function)      - 손실함수 (loss function)       - 오차함수 (error function) --- rosenbrock$\rightarrow f(x,y) = (1-x)^2 + 100(y-x^2)^2$ grid search - x값을 넣어보고 그 중 가장 작은 값을 선택하는 방식 - 높은 차원(4차 이상)에서는 사용하기 힘들다는 단점.  수치적 최적화(numerical optimization) - 적은 횟수의 시도로 x의 위치를 찾는 방법   1) 현재 위치 $x_k$가 최적점인지 판단하는 알고리즘           - 필요조건             1) $\nabla f = 0$ / $f' = 0$              2) $g = 0$             - 충분조건             1) 2차 도함수의 부호까지 필요          - $f'' > 0 $         - Hessian array PD $\rightarrow$ 최적점         2) 어떤 위치 $x_k$를 시도한 뒤, 다음 번 시도할 위치 $x_{k+1}$을 찾는 알고리즘        - 최대경사법(Steeppest Gradient Descent / SGD)      - $x_{k+1} = x_k - \mu\nabla f(x_k) = x_k - \mu g(x_k)$       ----  - 목적함수를 수식으로 알 수 있는 경우 : 2차 도함수 : Hessian array - 딥러닝처럼 목적함수가 수식으로 쓰여지지 않는 경우 : momentum  ----   2차 도함수를 사용한 뉴턴 방법   $x_{n+1} = x_n - [H f(x_n)]^{-1}\nabla f(x_n)$     $\rightarrow$ 사람이 미분을 직접해야하는 경우가 생김      Auasi-Newton (준 뉴턴) 방법   - BFGS (Broyden - Fletcher - Goldfarb - Shanno)  - CG (Conjugated Gradient)  ---  Scipy 최적화   - func: 목적함수   - x0: 초깃값 벡터   - jac: (옵션) 그레디언트 벡터를 출력하는 함수---  minimize() 명령의 결과는 OptimizeResult 클래스 객체로 다음 속성을 가진다.   - x: 최적화 해   - success: 최적화에 성공하면 True 반환   - status: 종료 상태. 최적화에 성공하면 0 반환   - message: 메시지 문자열   - fun: x 위치에서의 함수의 값   - jac: x 위치에서의 자코비안(그레디언트) 벡터의 값   - hess_inv: x 위치에서의 헤시안 행렬의 역행렬의 값 (준 뉴턴방법)   - nfev: 목적함수 호출 횟수   - njev: 자코비안 계산 횟수   - nhev: 헤시안 계산 횟수   - nit: x 이동 횟수<jupyter_code>from scipy import optimize
# success 값이 True == 최적화에 성공했다는 뜻
# nfev의 값을 줄이기 위해서는 def로 도함수 값을 미리 지정해서 넣어줘야 함.


def f1(x):
    return (x-2) ** 2 + 2


x0 = 0
result = sp.optimize.minimize(f1, x0)
print(result)
def f1p(x):
    return 2*(x-2)


result = sp.optimize.minimize(f1, x0, jac=f1p)
print(result)<jupyter_output>fun: 2.0
 hess_inv: array([[0.5]])
      jac: array([0.])
  message: 'Optimization terminated successfully.'
     nfev: 3
      nit: 2
     njev: 3
   status: 0
  success: True
        x: array([2.])<jupyter_text>--- 2차원 목적함수 재정의 (벡터 입력)<jupyter_code>def f2(x):
    return (1-x[0]**2 + 100.0 * (x[1] - x[0]**2)**2)


x0 = (-2, -2)
result = sp.optimize.minimize(f2, x0)
print(result)<jupyter_output>fun: -20246.68622892564
 hess_inv: array([[ 5.62789387e-03, -1.59855363e+00],
       [-1.59855363e+00,  4.54061320e+02]])
      jac: array([-22798.86914062,    -81.07983398])
  message: 'Maximum number of iterations has been exceeded.'
     nfev: 2064
      nit: 400
     njev: 516
   status: 1
  success: False
        x: array([ -142.35210213, 20263.71558382])<jupyter_text>연습문제 5.1.1 - 초기점 변경 - $\nabla f(x)$를 구현하여 $jac$ 인수로 주는 방법으로 계산속도 향상<jupyter_code>def f2(x):
    return (1-x[0]**2 + 100.0 * (x[1] - x[0]**2)**2)


x0 = (0, 0)
result = sp.optimize.minimize(f2, x0, jac=None)
print(result)
def f2g(x):
    return np.array((2.0*(x[0]-1)-400.0 * x[0] * (x[1] - x[0]**2),
                     200.0*(x[1] - x[0]**2)))


result = sp.optimize.minimize(f2, x0, jac=f2g)
print(result)
import sympy
sympy.init_printing(use_latex='mathjax')
x, y = sympy.symbols('x y')
f = (1 - x)**2 + 100*(y - x ** 2)**2
sympy.diff(f, x)
sympy.diff(f, y)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16458852867830423, 'fraction_numerical': 0.06539207536713772, 'mean_word_length': 2.3864915572232643, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '524862', 'license': 'MIT', 'n_tokens_mistral': 2204, 'n_tokens_neox': 2469, 'n_words': 445, 'path': 'MATH/12_Optimization_01.ipynb', 'repo_name': 'CATERINA-SEUL/Data-Science-School', 'size': '3609'}