SciPy (izrunÄ sai pie) ir matemÄtiskas lietojumprogrammas pakotne, kuras pamatÄ ir Numpy Python paplaÅ”inÄjums. Izmantojot SciPy, jÅ«su interaktÄ«vÄ Python sesija kļūst par tÄdu paÅ”u pilnÄ«gu datu zinÄtni un sarežģītu sistÄmu prototipÄÅ”anas vidi kÄ MATLAB, IDL, Octave, R-Lab un SciLab. Å odien es vÄlos Ä«si runÄt par to, kÄ izmantot dažus labi zinÄmus optimizÄcijas algoritmus scipy.optimize pakotnÄ. DetalizÄtÄku un jaunÄko palÄ«dzÄ«bu par funkciju lietoÅ”anu vienmÄr var iegÅ«t, izmantojot komandu help() vai izmantojot taustiÅu kombinÄciju Shift+Tab.
Ievads
Lai pasargÄtu sevi un lasÄ«tÄjus no primÄro avotu meklÄÅ”anas un lasÄ«Å”anas, saites uz metožu aprakstiem galvenokÄrt bÅ«s VikipÄdijÄ. Parasti Ŕī informÄcija ir pietiekama, lai vispÄrÄ«gi izprastu metodes un to piemÄroÅ”anas nosacÄ«jumus. Lai saprastu matemÄtisko metožu bÅ«tÄ«bu, sekojiet saitÄm uz autoritatÄ«vÄkÄm publikÄcijÄm, kuras var atrast katra raksta beigÄs vai savÄ iecienÄ«tÄkajÄ meklÄtÄjÄ.
TÄtad modulis scipy.optimize ietver Å”Ädu procedÅ«ru ievieÅ”anu:
VairÄku mainÄ«go skalÄro funkciju nosacÄ«ta un beznosacÄ«juma minimizÄÅ”ana (minimums), izmantojot dažÄdus algoritmus (Nelder-Mead simplex, BFGS, Newton konjugÄta gradienti, KOBILA Šø SLSQP)
Atlikumu samazinÄÅ”ana MNC (least_squares) un lÄ«kÅu pielÄgoÅ”anas algoritmi, izmantojot nelineÄros mazÄkos kvadrÄtus (curve_fit)
Viena mainÄ«gÄ skalÄro funkciju samazinÄÅ”ana (minim_scalar) un sakÅu meklÄÅ”ana (root_scalar)
DaudzdimensionÄli vienÄdojumu sistÄmas (saknes) risinÄtÄji, izmantojot dažÄdus algoritmus (hibrÄ«ds Pauels, Levenbergs-Marquardt vai liela mÄroga metodes, piemÄram, Å Å«tons-Krilovs).
Å ajÄ rakstÄ mÄs apskatÄ«sim tikai pirmo vienumu no visa Ŕī saraksta.
VairÄku mainÄ«go skalÄrÄs funkcijas beznosacÄ«jumu samazinÄÅ”ana
MinimÄlÄ funkcija no pakotnes scipy.optimize nodroÅ”ina vispÄrÄ«gu saskarni vairÄku mainÄ«go skalÄro funkciju nosacÄ«tÄs un beznosacÄ«juma minimizÄÅ”anas problÄmu risinÄÅ”anai. Lai parÄdÄ«tu, kÄ tas darbojas, mums bÅ«s nepiecieÅ”ama piemÄrota funkcija no vairÄkiem mainÄ«gajiem, kurus mÄs dažÄdos veidos samazinÄsim.
Å iem nolÅ«kiem ir ideÄla N mainÄ«go Rozenbroka funkcija, kurai ir Å”Äda forma:
Neskatoties uz to, ka Rozenbroka funkcija un tÄs Jacobi un Hessian matricas (attiecÄ«gi pirmais un otrais atvasinÄjums) jau ir definÄtas scipy.optimize pakotnÄ, mÄs to definÄsim paÅ”i.
SkaidrÄ«bas labad uzzÄ«mÄsim 3D divu mainÄ«go Rozenbroka funkcijas vÄrtÄ«bas.
ZÄ«mÄÅ”anas kods
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
# ŠŠ°ŃŃŃŠ°ŠøŠ²Š°ŠµŠ¼ 3D Š³ŃŠ°ŃŠøŠŗ
fig = plt.figure(figsize=[15, 10])
ax = fig.gca(projection='3d')
# ŠŠ°Š“Š°ŠµŠ¼ ŃŠ³Š¾Š» Š¾Š±Š·Š¾ŃŠ°
ax.view_init(45, 30)
# Š”Š¾Š·Š“Š°ŠµŠ¼ Š“Š°Š½Š½ŃŠµ Š“Š»Ń Š³ŃŠ°ŃŠøŠŗŠ°
X = np.arange(-2, 2, 0.1)
Y = np.arange(-1, 3, 0.1)
X, Y = np.meshgrid(X, Y)
Z = rosen(np.array([X,Y]))
# Š ŠøŃŃŠµŠ¼ ŠæŠ¾Š²ŠµŃŃ Š½Š¾ŃŃŃ
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
plt.show()
Jau iepriekÅ” zinot, ka minimums ir 0 plkst , apskatÄ«sim piemÄrus, kÄ noteikt Rozenbroka funkcijas minimÄlo vÄrtÄ«bu, izmantojot dažÄdas scipy.optimize procedÅ«ras.
Neldera-MÄ«da vienkÄrÅ”Ä metode
Lai 0-dimensiju telpÄ ir sÄkuma punkts x5. Izmantojot algoritmu, atradÄ«sim tai tuvÄko Rozenbroka funkcijas minimÄlo punktu Nelder-Mead simplex (algoritms ir norÄdÄ«ts kÄ metodes parametra vÄrtÄ«ba):
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 339
Function evaluations: 571
[1. 1. 1. 1. 1.]
SimpleksÄ metode ir vienkÄrÅ”Äkais veids, kÄ samazinÄt skaidri definÄtu un diezgan vienmÄrÄ«gu funkciju. Tam nav jÄaprÄÄ·ina funkcijas atvasinÄjumi, pietiek norÄdÄ«t tikai tÄs vÄrtÄ«bas. Nelder-Mead metode ir laba izvÄle vienkÄrÅ”Äm minimizÄÅ”anas problÄmÄm. TomÄr, tÄ kÄ tajÄ netiek izmantoti gradienta aprÄÄ·ini, minimuma atraÅ”ana var aizÅemt ilgÄku laiku.
Pauela metode
VÄl viens optimizÄcijas algoritms, kurÄ tiek aprÄÄ·inÄtas tikai funkciju vÄrtÄ«bas, ir Pauela metode. Lai to izmantotu, minimÄlajÄ funkcijÄ jÄiestata metode = 'powell'.
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 19
Function evaluations: 1622
[1. 1. 1. 1. 1.]
Broyden-Fletcher-Goldfarb-Shanno (BFGS) algoritms
Lai panÄktu ÄtrÄku konverÄ£enci ar risinÄjumu, procedÅ«ra BFGS izmanto mÄrÄ·a funkcijas gradientu. Gradientu var norÄdÄ«t kÄ funkciju vai aprÄÄ·inÄt, izmantojot pirmÄs kÄrtas atŔķirÄ«bas. JebkurÄ gadÄ«jumÄ BFGS metode parasti prasa mazÄk funkciju izsaukumu nekÄ simpleksa metode.
Ä»aujiet mums atrast Rozenbroka funkcijas atvasinÄjumu analÄ«tiskÄ formÄ:
Å Ä« izteiksme ir derÄ«ga visu mainÄ«go atvasinÄjumiem, izÅemot pirmo un pÄdÄjo, kas definÄti kÄ:
ApskatÄ«sim Python funkciju, kas aprÄÄ·ina Å”o gradientu:
def rosen_der (x):
xm = x [1: -1]
xm_m1 = x [: - 2]
xm_p1 = x [2:]
der = np.zeros_like (x)
der [1: -1] = 200 * (xm-xm_m1 ** 2) - 400 * (xm_p1 - xm ** 2) * xm - 2 * (1-xm)
der [0] = -400 * x [0] * (x [1] -x [0] ** 2) - 2 * (1-x [0])
der [-1] = 200 * (x [-1] -x [-2] ** 2)
return der
Gradienta aprÄÄ·ina funkcija ir norÄdÄ«ta kÄ minimuma funkcijas jac parametra vÄrtÄ«ba, kÄ parÄdÄ«ts tÄlÄk.
res = minimize(rosen, x0, method='BFGS', jac=rosen_der, options={'disp': True})
print(res.x)
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 25
Function evaluations: 30
Gradient evaluations: 30
[1.00000004 1.0000001 1.00000021 1.00000044 1.00000092]
KonjugÄtÄ gradienta algoritms (Å Å«tons)
Algoritms Å Å«tona konjugÄcijas gradienti ir modificÄta Å Å«tona metode.
Å Å«tona metode balstÄs uz funkcijas tuvinÄÅ”anu lokÄlÄ apgabalÄ ar otrÄs pakÄpes polinomu:
kur ir otro atvasinÄjumu matrica (Hesijas matrica, Hesijas matrica).
Ja Hess ir pozitÄ«vs noteikts, tad Ŕīs funkcijas lokÄlo minimumu var atrast, pielÄ«dzinot kvadrÄtiskÄs formas nulles gradientu nullei. RezultÄts bÅ«s izteiksme:
Apgriezto Hesenes vÄrtÄ«bu aprÄÄ·ina, izmantojot konjugÄta gradienta metodi. PiemÄrs Ŕīs metodes izmantoÅ”anai Rosenbrock funkcijas samazinÄÅ”anai ir sniegts zemÄk. Lai izmantotu Å Å«tona-CG metodi, ir jÄnorÄda funkcija, kas aprÄÄ·ina Hesenes.
Rozenbroka funkcijas Hesene analÄ«tiskÄ formÄ ir vienÄda ar:
kur Šø , definÄjiet matricu .
AtlikuÅ”ie matricas elementi, kas nav nulle, ir vienÄdi ar:
PiemÄram, piecdimensiju telpÄ N = 5 Rozenbroka funkcijas Hesenes matricai ir joslas forma:
Kods, kas aprÄÄ·ina Å”o Hesenes vÄrtÄ«bu kopÄ ar kodu Rozenbroka funkcijas minimizÄÅ”anai, izmantojot konjugÄtÄ gradienta (Å Å«tona) metodi:
def rosen_hess(x):
x = np.asarray(x)
H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1)
diagonal = np.zeros_like(x)
diagonal[0] = 1200*x[0]**2-400*x[1]+2
diagonal[-1] = 200
diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:]
H = H + np.diag(diagonal)
return H
res = minimize(rosen, x0, method='Newton-CG',
jac=rosen_der, hess=rosen_hess,
options={'xtol': 1e-8, 'disp': True})
print(res.x)
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 24
Function evaluations: 33
Gradient evaluations: 56
Hessian evaluations: 24
[1. 1. 1. 0.99999999 0.99999999]
PiemÄrs ar Hesenes un patvaļīga vektora reizinÄjuma funkcijas definÄ«ciju
ReÄlÄs pasaules problÄmÄs visas Hesenes matricas aprÄÄ·inÄÅ”ana un glabÄÅ”ana var prasÄ«t ievÄrojamus laika un atmiÅas resursus. Å ajÄ gadÄ«jumÄ faktiski nav nepiecieÅ”ams norÄdÄ«t paÅ”u Hesenes matricu, jo minimizÄÅ”anas procedÅ«rai nepiecieÅ”ams tikai vektors, kas vienÄds ar Hesenes reizinÄjumu ar citu patvaļīgu vektoru. TÄdÄjÄdi no skaitļoÅ”anas viedokļa ir daudz labÄk nekavÄjoties definÄt funkciju, kas atgriež Hesenes reizinÄjuma rezultÄtu ar patvaļīgu vektoru.
Apsveriet Hesa āāfunkciju, kas izmanto minimizÄÅ”anas vektoru kÄ pirmo argumentu un patvaļīgu vektoru kÄ otro argumentu (kopÄ ar citiem minimizÄjamÄs funkcijas argumentiem). MÅ«su gadÄ«jumÄ Rozenbroka funkcijas Hesenes reizinÄjuma aprÄÄ·inÄÅ”ana ar patvaļīgu vektoru nav Ä«paÅ”i sarežģīta. Ja p ir patvaļīgs vektors, tad reizinÄjums izskatÄs kÄ:
Funkcija, kas aprÄÄ·ina Hesenes un patvaļīga vektora reizinÄjumu, tiek nodota kÄ hessp argumenta vÄrtÄ«ba minimizÄÅ”anas funkcijai:
def rosen_hess_p(x, p):
x = np.asarray(x)
Hp = np.zeros_like(x)
Hp[0] = (1200*x[0]**2 - 400*x[1] + 2)*p[0] - 400*x[0]*p[1]
Hp[1:-1] = -400*x[:-2]*p[:-2]+(202+1200*x[1:-1]**2-400*x[2:])*p[1:-1]
-400*x[1:-1]*p[2:]
Hp[-1] = -400*x[-2]*p[-2] + 200*p[-1]
return Hp
res = minimize(rosen, x0, method='Newton-CG',
jac=rosen_der, hessp=rosen_hess_p,
options={'xtol': 1e-8, 'disp': True})
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 24
Function evaluations: 33
Gradient evaluations: 56
Hessian evaluations: 66
Slikta Hesenes matricas kondicionÄÅ”ana un nepareizi meklÄÅ”anas virzieni var izraisÄ«t Å Å«tona konjugÄtÄ gradienta algoritma neefektivitÄti. Å Ädos gadÄ«jumos priekÅ”roka tiek dota uzticÄ«bas reÄ£iona metode (uzticÄ«bas reÄ£ions) konjugÄts Å Å«tona gradienti.
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 20
Function evaluations: 21
Gradient evaluations: 20
Hessian evaluations: 0
[1. 1. 1. 1. 1.]
Krilova tipa metodes
TÄpat kÄ uzticÄ«bas-ncg metode, arÄ« Krilova tipa metodes ir labi piemÄrotas liela mÄroga problÄmu risinÄÅ”anai, jo tajÄs tiek izmantoti tikai matricas vektoru produkti. To bÅ«tÄ«ba ir atrisinÄt problÄmu uzticÄ«bas reÄ£ionÄ, kuru ierobežo saÄ«sinÄta Krilova apakÅ”telpa. NeskaidrÄm problÄmÄm labÄk izmantot Å”o metodi, jo tÄ izmanto mazÄku nelineÄro iterÄciju skaitu, jo vienÄ apakÅ”problÄmÄ ir mazÄks matricas vektoru produktu skaits, salÄ«dzinot ar uzticÄ«bas-ncg metodi. TurklÄt kvadrÄtiskÄs apakÅ”problÄmas risinÄjums tiek atrasts precÄ«zÄk, nekÄ izmantojot uzticÄ«bas-ncg metodi.
PiemÄrs ar Hesenes matricas definÄ«ciju:
res = minimize(rosen, x0, method='trust-krylov',
jac=rosen_der, hess=rosen_hess,
options={'gtol': 1e-8, 'disp': True})
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 19
Function evaluations: 20
Gradient evaluations: 20
Hessian evaluations: 18
print(res.x)
[1. 1. 1. 1. 1.]
PiemÄrs ar Hesenes reizinÄjuma funkciju un patvaļīgu vektoru:
res = minimize(rosen, x0, method='trust-krylov',
jac=rosen_der, hessp=rosen_hess_p,
options={'gtol': 1e-8, 'disp': True})
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 19
Function evaluations: 20
Gradient evaluations: 20
Hessian evaluations: 0
print(res.x)
[1. 1. 1. 1. 1.]
Visas metodes (Newton-CG, trust-ncg un trust-krylov) ir labi piemÄrotas liela mÄroga problÄmu risinÄÅ”anai (ar tÅ«kstoÅ”iem mainÄ«go). Tas ir saistÄ«ts ar faktu, ka pamatÄ esoÅ”ais konjugÄta gradienta algoritms paredz aptuvenu apgrieztÄs Heses matricas noteikÅ”anu. RisinÄjums tiek atrasts iteratÄ«vi, bez tieÅ”as Hesenes valodas paplaÅ”inÄÅ”anas. TÄ kÄ funkcija ir jÄdefinÄ tikai Hesenes un patvaļīga vektora reizinÄjumam, Å”is algoritms ir Ä«paÅ”i piemÄrots darbam ar retÄm (joslas diagonÄles) matricÄm. Tas nodroÅ”ina zemas atmiÅas izmaksas un ievÄrojamu laika ietaupÄ«jumu.
VidÄja izmÄra problÄmÄm Hessian uzglabÄÅ”anas un faktoringa izmaksas nav kritiskas. Tas nozÄ«mÄ, ka risinÄjumu ir iespÄjams iegÅ«t mazÄkÄs iterÄcijÄs, gandrÄ«z precÄ«zi atrisinot uzticÄ«bas reÄ£iona apakÅ”problÄmas. Lai to izdarÄ«tu, katrai kvadrÄtiskajai apakÅ”problÄmai iteratÄ«vi tiek atrisinÄti daži nelineÄri vienÄdojumi. Å Ädam risinÄjumam parasti ir nepiecieÅ”ami 3 vai 4 Hesenes matricas Cholesky dekompozÄ«cijas. RezultÄtÄ metode konverÄ£Ä mazÄkÄs iterÄcijÄs un prasa mazÄk mÄrÄ·a funkciju aprÄÄ·inu nekÄ citas ieviestÄs ticamÄ«bas apgabala metodes. Å is algoritms ietver tikai pilnÄ«gas Hesenes matricas noteikÅ”anu un neatbalsta iespÄju izmantot Hesenes un patvaļīga vektora reizinÄjuma funkciju.
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 13
Function evaluations: 14
Gradient evaluations: 13
Hessian evaluations: 14
array([1., 1., 1., 1., 1.])
DroÅ”i vien pie tÄ arÄ« apstÄsimies. NÄkamajÄ rakstÄ mÄÄ£inÄÅ”u pastÄstÄ«t interesantÄko par nosacÄ«to minimizÄÅ”anu, minimizÄÅ”anas pielietojumu aproksimÄcijas uzdevumu risinÄÅ”anÄ, viena mainÄ«gÄ funkcijas minimizÄÅ”anu, patvaļīgiem minimizatoriem un vienÄdojumu sistÄmas sakÅu atraÅ”anu, izmantojot scipy.optimize. iepakojums.