Минимизация Python с разными условиями

#python #numpy #optimization #minimize

#python #numpy #оптимизация #минимизировать

Вопрос:

В настоящее время я пытаюсь найти замену набора данных точек для большого набора данных точек. Я хочу определить точки набора данных замены таким образом, чтобы они были нерегулярными и, таким образом, оптимально описывали область. Я написал функцию «objective». Для этого требуется массив 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=[])

 

Для лучшего понимания я рисую проблему на примере:

введите описание изображения здесь

Комментарии:

1. Не могли бы вы, возможно, нарисовать визуализацию именно того, что вы хотите? Мне это немного непонятно.

2. Спасибо за подсказку, я сделал это, пожалуйста, посмотрите на вопрос в конце.

Ответ №1:

То, что вы ищете, известно как аппроксимация кусочно-линейной функции. Вы можете легко создать их, используя pwlf пакет Python.

 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()
 

график

Комментарии:

1. Ну, прежде всего, спасибо за код и пример. Но (здесь возникает но) это только то, что я ищу. Видите ли, проблема в том, что линейная аппроксимация в случае ur отлично справляется, но конечные точки не относятся к исходным данным, а это сущностный результат. Пожалуйста, можете ли вы проверить рисунок, который я сделал?

2. @elPenguin Если конечные точки должны быть частью исходных данных, вы в конечном итоге сталкиваетесь с комбинаторной проблемой, которую обычно трудно решить оптимально. Что вы могли бы сделать в качестве приближения, так это выполнить алгоритм, который я описал здесь, а затем выбрать ближайшую точку в исходном наборе данных к предложенным точкам останова.