Минимизация функции в scipy с тремя параметрами возвращает первоначальное предположение - PullRequest
0 голосов
/ 06 августа 2020

Набор точек с координатами x и y выглядит как это . Я хочу построить кривую в области ниже y = 0 формы - a - np.exp(-(x - b)/c), где параметры a, b и c находятся при условии, что 90% точек ниже y = 0 заключены по этой строке и рассматриваемой функции.

Для этого я написал следующий код, но функция minimize дает в результате начальное предположение, и я не знаю, что мне не хватает .

from scipy.optimize import minimize
import numpy as np

def enclosed_points(params):
    a, b, c = params
    den = (y < 0).sum()                   # Calculate the number of points with y coordinate below y0
    func = - a - np.exp(-(x - b)/c)       # Calculate the value of the function for each x
    num = ((y < 0) & (y > func)).sum()    # Calculate the number of points with y coordinate
                                          # below y0 and above the function
    return np.abs(num/den - 0.9)          # Return the absolute value of the difference between
                                          # the ratio of num and den and the target number (0.9)

initial_guess = [0.1, 0.2, 1]             # Dummy initial guess
result = minimize(enclosed_points, initial_guess)

Редактировать. Здесь Я загрузил случайную выборку всех данных в формате npy.

1 Ответ

0 голосов
/ 06 августа 2020

Ну, я попробовал несколько разных методов и изменил некоторые части вашего кода:

def func(x, a, b, c):
    return - a - np.exp(-(x - b)/c)

def enclosed_points(params):
    a, b, c = params
    loss1 = y[np.argwhere( y > 0)]
    loss2 = loss1[np.argwhere( loss1 < func(x[np.argwhere( y > 0)], a, b, c) )]
    loss = ((loss2.sum() / len(y)) - 0.9)**2
    return loss

initial_guess = [-0.1, 0.2, 1]     
result = minimize(enclosed_points, initial_guess, method='SLSQP', options={'eps': 1e-2})

Loss1 и loss2 выполняют ту же работу, что и ваша функция потерь, но я изменяю abs на степень 2 ( потому что, на мой взгляд, это более распространено) (также добавил "method='SLSQP', options={'eps': 1e-2}" в ваш минимайзер на основе другого сообщения на StackOverflow; постарайтесь внимательно прочитать их и также ознакомиться с их проблемами, связанными с этим минимизатором). Однако я думаю, что основная проблема в том, что ваша проблема невыпуклая, и функция minimize пытается найти локальный минимум. Подробное описание см. В этом сообщении. В конце концов, я бы сказал, что с начальной точкой [-0.1, 0.2, 1] я мог бы найти решение (попробуйте другое отрицательное значение для a, и, возможно, вы найдете другие решения :))

Удачи

...