scipy

Scipy 是基于 Numpy 的科学计算库,用于数学、科学、工程学等领域

包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算

优化算法

常见的优化函数有:

  • minimize: 适用于无约束或带约束的函数优化
  • least_squares: 最小二乘问题
  • curve_fit: 用于拟合数据
  • fminfminboundbasinhopping 等全局优化方法

无约束优化

无约束优化问题就是只需要最小化一个函数,无需考虑变量的取值范围

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]
# 使用默认的 Nelder-Mead 算法进行优化
# 可以通过参数 method 来选择不同的算法
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
# 边界约束:x 在 0 和 5 之间
bounds = [(0, 5)]
# 初始猜测
x0 = [0]
# 使用 L-BFGS-B 算法进行优化
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

# 约束条件: x[0] + x[1] >= 1 (线性)
constraints = [{'type': 'ineq', 'fun': lambda x: x[0] + x[1] - 1}]
# 约束条件: x[0]^2 + x[1]^2 >= 1 (非线性)
# constraints = [{'type': 'ineq', 'fun': lambda x: x[0]**2 + x[1]**2 -1}]
# 初始猜测
x0 = [1, 1]

# 使用 SLSQP (Sequential Least Squares Quadratic Programming) 方法
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) # y = 2x + 1 + noise

# 定义拟合函数
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)

# 使用 curve_fit 进行拟合
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}")