scipy
Scipy 是基于 Numpy 的科学计算库,用于数学、科学、工程学等领域
包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算
优化算法
常见的优化函数有:
minimize
: 适用于无约束或带约束的函数优化
least_squares
: 最小二乘问题
curve_fit
: 用于拟合数据
fmin
、fminbound
、basinhopping
等全局优化方法
无约束优化
无约束优化问题就是只需要最小化一个函数,无需考虑变量的取值范围
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np from scipy.optimize import minimize
def objective(x): return (x - 3)**2 + 4
x0 = [0]
result = minimize(objective, x0, method = "Nelder-Mead") print(f"最小值点: {result.x}, 最小值: {result.fun}")
|
约束优化
边界约束:
通过bounds指定参数的取值范围
1 2 3 4 5 6 7 8 9 10
| def objective(x): return (x - 3)**2 + 4
bounds = [(0, 5)]
x0 = [0]
result = minimize(objective, x0, bounds=bounds, method='L-BFGS-B') print(f"最小值点: {result.x}, 最小值: {result.fun}")
|
线性约束/非线性约束:
通过 constraints
参数可以添加线性或非线性约束
type
:指定约束的类型,可以是 'eq'
(等式约束)或者 'ineq'
(不等式约束)
fun
:该函数接受优化变量,对于不等式约束,最好采用lambda表达式容易表示范围,true返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def objective(x): return x[0]**2+x[1]**2
constraints = [{'type': 'ineq', 'fun': lambda x: x[0] + x[1] - 1}]
x0 = [1, 1]
result = minimize(objective, x0, constraints=constraints, method='SLSQP') print(f"最小值点: {result.x}, 最小值: {result.fun}")
|
最小二乘法优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| from scipy.optimize import least_squares import numpy as np
rng = np.random.default_rng(42) x_data = np.linspace(0, 10, 100) y_data = 2 * x_data + 1 + 0.5*rng.normal(0, 1, x_data.size)
def model(params, x): return params[0] * x + params[1]
def residuals(params, x, y): return model(params, x) - y
initial_guess = [1, 1]
result = least_squares(residuals, initial_guess, args=(x_data, y_data))
print(f"拟合参数: {result.x}")
|
曲线拟合
curve_fit
不仅可以拟合线性函数,还可以用于拟合各种类型的函数模型,例如:
- 二次函数:
y = ax^2 + bx + c
- 指数函数:
y = a * exp(bx)
- 高斯分布:
y = a * exp(-(x-b)^2 / (2 * c^2))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import numpy as np from scipy.optimize import curve_fit
def quadratic_func(x, a, b, c): return a * x**2 + b * x + c
rng = np.random.default_rng(42) xdata = np.linspace(0, 10, 100) ydata = 1.5 * xdata**2 - 2.5 * xdata + 4.0 + 0.5*rng.normal(0, 1, size=xdata.size)
popt, pcov = curve_fit(quadratic_func, xdata, ydata)
a_fit, b_fit, c_fit = popt
print(f"拟合的参数:a = {a_fit:.2f}, b = {b_fit:.2f}, c = {c_fit:.2f}")
|