Получить неправильный результат с помощью scipy.optimize.fmin_cobyla - PullRequest
0 голосов
/ 16 мая 2018

Я очень новичок в scipy, и теперь я пытаюсь использовать функции in scipy.optimize, проводя небольшой эксперимент.

Я попытался подобрать sin-функцию, найдя параметр, который имеет наименьшее значение ошибки.

Используемая функция: fmin_cobyla

Код ниже:

import matplotlib.pyplot as plt
from scipy.optimize import fmin_cobyla
from scipy.optimize import fmin_slsqp
from scipy.optimize import leastsq
import numpy as np
from sympy import *

noise = np.random.randn(100)

def func_model(x, para):
    ''' Model: y = a*sin(2*k*pi*x+theta)'''
    a, k, theta = para
    return a*np.sin(2*k*np.pi*x+theta)

def func_noise(x, para):
    a, k, theta = para
    return a*np.sin(2*k*np.pi*x+theta) + noise

def func_error(para_guess):
    '''error_func'''
    x_seq = np.linspace(-2*np.pi, 0, 100)
    para_fact = [10, 0.34, np.pi/6]
    data = func_noise(x_seq, para_fact)
    error_value  = data - func_model(x_seq, para_guess)
    return error_value

# 1<a<15  0<k<1  0<theta<pi/2
constraints = [lambda x: 15 - x[0], lambda x: x[0]- 1, \
               lambda x: 1 - x[1],  lambda x: x[1], \
               lambda x: np.pi/2 - x[2], lambda x: x[2]]

para_guess_init = np.array([7, 0.2, 0])

solution = fmin_cobyla(func_error, para_guess_init, constraints)
print(solution)   # supposed to be like [10, 0.34, np.pi/6]

xx = np.linspace(-2*np.pi, 0, 100)
plt.plot(xx, func_model(xx, [10, 0.34, np.pi/6]), label="raw")
plt.plot(xx, func_noise(xx, [10, 0.34, np.pi/6]), label="with noise")
plt.plot(xx, func_model(xx, solution), label="fitted")
plt.legend()
plt.show()

после запуска я получил результат

решение = [1.6655938 0.598686670.0731335]

enter image description here

Это, конечно, неправильный ответ

Может ли кто-нибудь мне помочь.Заранее спасибо ..

1 Ответ

0 голосов
/ 16 мая 2018

Здесь есть две вещи, которые кажутся явно неправильными: во-первых, вы меняете шум каждый раз, когда вызывается ваша целевая функция, поэтому ваша оптимизация пытается поразить движущуюся цель.Установите смоделированные данные перед вызовом fmin_cobyla:

the_noise = np.random.randn(100)
data = func_noise(x_seq, para_fact)

Кроме того, ваш func_error должен возвращать разницу между моделью и данными для каждой точки, а не разницу суммы квадратов:

def func_error(para_guess):
    error_value = data - func_model(x_seq, para_guess)
    return error_value

Вы все еще можете обнаружить, что fmin_cobyla пытается найти ограниченный минимум ... некоторая предварительная обработка, чтобы лучше оценить первоначальное предположение для фазы или частоты, может помочь вам в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...