Python在不同条件下最小化

问题描述

我目前正在尝试为大型点数据集寻找替换点数据集。我想以不规则的方式定义替换数据集的点,从而最佳地描述该区域。 我写了一个函数“目标”。这需要一个包含 x 个点的 numpy 数组。这些点我想在最后分发优化。该函数首先计算原始曲线上的交点,然后计算面积。误差被用作参考区域。我如何确保“最佳”分配点数?如何整合条件以便在此处设置数据集的限制?

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,round(first_area_simps,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_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=[])

为了更好地理解,我用一个例子来描述问题:

enter image description here

解决方法

您正在寻找的是分段线性函数逼近。您可以使用 Python pwlf 包轻松构建这些。

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,label="breakpoints")
plt.legend()
plt.tight_layout()
plt.show()

plot

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...