Решаҳо ва минимумҳо
Чаро реша ва минимумро меҷӯем?
SciPy китобхонаи ҳисобкуниҳои илмӣ бар пояи NumPy аст. Ба ҷойи аз нав навиштани алгоритми ададӣ метавон модели математикиро тавсиф карда, ҳалкунандаи тайёрро интихоб намуд. Модули scipy.optimize барои танзими таҷҳизот, таҳлили ченкуниҳо ва ёфтани реҷаи сарфакоронаи кор лозим мешавад.
Аввал саволҳоро фарқ мекунем. Решаи функсия нуқтаест, ки дар он қимати функсия ба сифр баробар аст: масалан, лаҳзаи баробар шудани даромад ва хароҷот. Минимум нуқтаест, ки дар он қимат хурдтарин аст: масалан, танзиме, ки хатои камтарин медиҳад. Қимати функсия дар нуқтаи минимум ҳатман сифр нест.
1. Функсия ҳамчун аргумент
Ба ҳалкунанда қоидаи ҳисобкуниро медиҳанд, на адади тайёрро. def функсияи номдор ва lambda функсияи кӯтоҳро аз як ифода месозад. Дар f(2) функсия аллакай даъват мешавад; дар brentq(f, ...) худи функсия дода мешавад. Ин мисли супурдани ҳисобкунак бо формула аст: ҳалкунанда худаш ададҳои санҷиширо интихоб мекунад.
def f(x):
return x ** 2 - 7
g = lambda x: x ** 2 - 7
print(f(2), g(3))
Натиҷа:
-3 2
2. Реша дар порча: brentq
brentq(f, a, b) сифри функсияро дар порча меҷӯяд. Функсия бояд бефосила бошад: дар дохили порча график набояд канда шавад ё қутб дошта бошад. Агар қиматҳои канорӣ аломатҳои муқобил дошта бошанд, графики бефосила ҳатман сатҳи сифрро мебурад. Ин мавҷудияти ақаллан як решаро кафолат медиҳад, вале ягонагии онро не. Агар худи канори порча реша бошад, усул метавонад онро фавран баргардонад.
from scipy.optimize import brentq
f = lambda x: x ** 2 - 7
root = brentq(f, 2, 3, xtol=1e-12)
print(f(2), f(3))
print(round(root, 6), round(f(root), 10))
Натиҷа:
-3 2
2.645751 -0.0
Дар дохил чӣ рӯй медиҳад
Усули Брент порчаеро нигоҳ медорад, ки дар он аломат иваз мешавад. Он аз рӯйи шакли тақрибии график қадамҳои тезро месанҷад; агар чунин қадам боэътимод набошад, порчаро ба ду тақсим мекунад. Баъди ҳисоб кардани функсия қисми нолозим партофта мешавад. Ҳамин тавр эътимоднокии тақсимкунӣ ва суръати интерполятсия якҷо мешаванд. xtol таҳаммулпазирии мутлақи ҷойи решаро муайян мекунад; хурд будани f(root)-ро низ санҷидан фоиданок аст.
Параметрҳои формуларо аз муҳити атроф гирифтан мумкин аст. Дар мисоли навбатӣ як қоида барои ду қимати параметр истифода мешавад; ҷустуҷӯ дар ҳар такрори давра фавран иҷро мегардад.
from scipy.optimize import brentq
for k in [2, 5]:
root = brentq(lambda x: x ** 2 - k, 0, k)
print(k, round(root, 6))
Натиҷа:
2 1.414214
5 2.236068
3. Минимуми як тағйирёбанда
minimize_scalar объекти натиҷаро бармегардонад. res.x аргумент, яъне ҷойи минимуми ёфташуда ва res.fun қимати функсия дар он ҷой аст. res.success анҷоми муваффақонаи ҷустуҷӯро нишон медиҳад. Барои ҷустуҷӯ дар ҳудуди муайян ҳам bounds ва ҳам method="bounded"-ро диҳед. Барои функсияи дорои як «чуқурӣ» ин роҳи қулайи ёфтани қаъри он аст; агар чуқуриҳо чандто бошанд, минимуми глобалӣ кафолат дода намешавад.
from scipy.optimize import minimize_scalar
res = minimize_scalar(lambda x: (x - 2.5) ** 2 + 6,
bounds=(0, 8), method="bounded",
options={"xatol": 1e-9})
print(round(res.x, 6), round(res.fun, 6), bool(res.success))
Натиҷа:
2.5 6.0 True
Таҳаммулпазирии xatol ба ҷойи нуқта дахл дорад, на бевосита ба қимати функсия. Дар графики хеле ҳамвор нуқтаҳои гуногун метавонанд қиматҳои қариб яксон диҳанд. Ғайр аз ин, ҷустуҷӯи bounded одатан нуқтаи дохилиро медиҳад. Агар минимум дар канор иҷозат бошад, натиҷаро бо қиматҳои ҳар ду канор муқоиса кунед. Масалан, функсияи афзоянда дар канори чап минимум дорад.
from scipy.optimize import minimize_scalar
f = lambda x: x + 4
l, r = 0, 3
res = minimize_scalar(f, bounds=(l, r), method="bounded")
best = min([l, res.x, r], key=f)
print(best, f(best))
Натиҷа:
0 4
4. Чанд тағйирёбанда: minimize
Вақте ки якчанд танзим ба натиҷа таъсир мерасонад, аргументи функсия вектор аст. Ҷузъҳои он бо p[0], p[1] ва ғайра дастрасанд. x0 наздикшавии ибтидоиро муайян мекунад. Ҳалкунанда самти камшавии функсияро арзёбӣ карда, нуқтаи ҷориро беҳтар мекунад; ҷузъиёти қадамҳо аз алгоритми интихобшуда вобаста аст. Нуқтаи ибтидоӣ ба минимуми маҳаллии ёфташуда таъсир мерасонад. Баъди ҷустуҷӯ success ва дар ҳолати зарурӣ майдони ташхисии message-ро месанҷанд.
from scipy.optimize import minimize
f = lambda p: (p[0] - 3) ** 2 + 2 * (p[1] + 1) ** 2
res = minimize(f, x0=[0, 0])
print(res.x.round(5).tolist())
print(round(res.fun, 8), bool(res.success))
Натиҷа:
[3.0, -1.0]
0.0 True
5. Формула аз рӯйи ченкуниҳо: curve_fit
Усули квадратҳои хурдтарин параметрҳои моделро тавре интихоб мекунад, ки ҷамъи квадратҳои фарқи пешгӯиҳо ва ченкуниҳо камтарин шавад. Квадрат хатоҳои мусбат ва манфиро яксон ҳисоб карда, хатоҳои калонро сахттар ҷарима мекунад. Ин аз гузаронидани каҷхат маҳз аз ҳар як нуқта фарқ дорад.
Аргументи якуми модел координатаҳои ченшуда ва аргументҳои боқимонда параметрҳои номаълуманд. curve_fit якбора массив медиҳад, бинобар ин амалҳои NumPy-ро истифода баред. p0 қиматҳои ибтидоии параметрҳост. Натиҷа массиви параметрҳо ва арзёбии матритсаи ковариатсияи онҳоро дар бар мегирад; матритса номуайянии мувофиқкуниро дар доираи фарзияҳои модел тавсиф мекунад.
import numpy as np
from scipy.optimize import curve_fit
def model(t, k, b):
return k * np.sqrt(t) + b
t = np.array([0., 1., 4., 9., 16.])
y = np.array([1.1, 3.0, 4.9, 7.2, 8.9])
params, cov = curve_fit(model, t, y, p0=(1, 0))
print(params.round(3).tolist())
print(np.round(model(np.array([25.]), *params), 3).tolist())
print(cov.shape)
Натиҷа:
[1.98, 1.06]
[10.96]
(2, 2)
Хатоҳои маъмул ва ислоҳи онҳо
brentq(f(2), 2, 3)ба ҷойи функсия адад дода,TypeErrorмеорад. Ислоҳ:brentq(f, 2, 3).- Ҷустуҷӯи решаи
x ** 2 - 1дар[-2, 2]баValueErrorмеорад: ҳар ду канор мусбатанд, гарчанде дар дохил ду реша ҳаст. Ислоҳ: як решаро, масалан бо порчаи[0, 2], ҷудо кунед. Аломатҳои муқобил талаби бефосилагиро бекор намекунанд:1 / xдар[-1, 1]реша надорад. - Агар ҷойи минимум лозим бошад, танҳо чоп кардани
res.funқимати меҳвари дигарро медиҳад. Ислоҳ: барои аргументres.xва барои қиматres.fun-ро истифода баред; дар мисоли боло онҳо 2.5 ва 6.0 мебошанд. - Дар модел
math.sqrt(t)массиви чандэлементаро қабул намекунад ваTypeErrorмедиҳад. Ислоҳ: мисли намунаи мувофиқкунӣnp.sqrt(t)-ро истифода баред. Меъёри хатои интихобшударо бе асос бо логарифмҳо иваз накунед: вазни хатоҳо тағйир меёбад.
Хатои дуюм ва ислоҳи онро дар иҷрои кӯтоҳи алоҳида месанҷем:
from scipy.optimize import brentq
f = lambda x: x ** 2 - 1
try:
brentq(f, -2, 2)
except ValueError as error:
print(type(error).__name__)
print(round(brentq(f, 0, 2), 6))
Натиҷа:
ValueError
1.0
Ададҳои нуқтаашон шинокунанда тақрибӣ нигоҳ дошта мешаванд. Аз ин рӯ, баъди гирд кардани боқимондаи манфии хеле хурд -0.0 дида мешавад: ин ҷавоби ҷудогонаи ғайрисифрӣ нест. Барои намоиш гирд кунед, вале дар дохили функсияи мақсаднок не — зинаҳои аз гирдкунӣ пайдошуда ба ҷустуҷӯи ададӣ халал мерасонанд.
Ёддошт
| Вазифа | Восита | Чиро санҷидан лозим |
|---|---|---|
| Сифри функсияи бефосила | brentq(f, a, b) |
Аломатҳои канорӣ, xtol |
| Минимуми як тағйирёбанда | minimize_scalar(..., method="bounded") |
bounds, x, fun, success |
| Минимуми чанд тағйирёбанда | minimize(f, x0) |
Нуқтаи ибтидоӣ, маҳаллӣ будани натиҷа |
| Параметрҳои модел аз додаҳо | curve_fit(model, x, y, p0=...) |
Тартиби параметрҳо, амалҳои NumPy |
Пеш аз ҳисоб муайян кунед, ки реша, ҷойи минимум, қимати минимум ё параметрҳои модел лозиманд. Баъди ҳисоб натиҷаро боз ба формула гузошта, маъно ва миқёси ҷавобро санҷед.