python - Python 在不同条件下最小化
问题描述
我目前正在尝试为大型点数据集找到替换的点数据集。我想以不规则的方式定义替换数据集的点,从而最佳地描述该区域。我写了一个函数“目标”。这需要一个 numpy 数组,其中包含 x 个点。这些点我想在最后分发优化。该函数首先计算原始曲线上的交点,然后计算面积。误差用作参考区域。如何确保“最佳”分配积分?如何整合条件以便在此处设置数据集的限制?
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from scipy.integrate import simps
from scipy.optimize import minimize
from numpy import trapz
# testpoints given by user
base_points_x = np.array([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1])
base_points_y = np.array([1,5,5.5,6,6.5,6.7,6.9,7,7.1,7.15])
# calculate the base area
base_area_trapz = trapz(base_points_y, x=base_points_x)
base_area_simps = simps(base_points_y, x=base_points_x)
print("base area =", round(base_area_trapz,4))
print("base area =", round(base_area_simps,4))
# 1. method, use a discrete small equal discretised number of points
dis_points = 5
first_points_x = np.linspace(base_points_x[0], base_points_x[-1], dis_points)
first_points_y = np.zeros(dis_points)
for n in range(0, dis_points):
xa = np.argmin(base_points_x <= first_points_x[n])
xb = np.argmax(base_points_x >= first_points_x[n])
first_points_y[n] = np.interp(first_points_x[n], base_points_x, base_points_y)
#calculate the first area and difference
first_area_trapz = trapz(first_points_y, x=first_points_x)
first_area_simps = simps(first_points_y, x=first_points_x)
print("base area =", round(first_area_trapz, 4), round(base_area_trapz-first_area_trapz, 4))
print("base area =", round(first_area_simps, 4), round(base_area_simps-first_area_simps, 4))
# 2. method optimize the area
def objective(x):
y = np.zeros(len(x))
for n in range(0, len(x)):
xa = np.argmin(base_points_x <= x[n])
xb = np.argmax(base_points_x >= x[n])
y[n] = np.interp(x[n], base_points_x, base_points_y)
return base_area_trapz - trapz(y, x=x)
#guess values (taken from previous function)
x0 = first_points_x
res = minimize(objective, x0, method='nelder-mead', bounds=[])
为了更好地理解,我举了一个例子:
解决方案
您正在寻找的东西被称为分段线性函数近似。您可以使用 Pythonpwlf
包轻松构建它们。
python3 -m pip install pwlf
然后,作为使用示例(警告,可能有点慢):
import numpy as np
import pwlf
import matplotlib.pyplot as plt
# Generate some dummy data.
X = np.linspace(0, 2*np.pi, 100)
y = np.sin(X) * X * X
pwlffit = pwlf.PiecewiseLinFit(X, y)
# Atol sets absolute tolerance, see scipy.optimize.differential_evolution.
lfx = pwlffit.fit(5, atol=1e-10)
lfy = pwlffit.predict(lfx)
plt.plot(X, y, label="data")
plt.plot(lfx, lfy, label="approximation")
plt.scatter(lfx, lfy, label="breakpoints")
plt.legend()
plt.tight_layout()
plt.show()
推荐阅读
- batch-file - 为什么 /i 选项不能与 xcopy 命令一起使用?
- python - PRAW/Tweepy 过滤关键字
- laravel - 在 laravel 中更改所有图像的 url 和链接 href
- oracle11g - 如何通过顶点中的动态操作在区域中没有日期时隐藏区域
- css - NativeScript Playground - 未应用内置类
- c# - 打开 id 未重定向到正确的登录页面
- amazon-web-services - 无服务器框架 lambda 执行角色不匹配?
- android - 动态添加视图后,按钮 onClick 不会触发
- c++ - 在类中声明指针的静态双端队列
- dataweave - 转换数据库结果以匹配 accounts-api.raml 文件中指定的 Account 架构