Передача списка списков в качестве входных данных для scipy.optimize.curve_fit

1

Я пытаюсь решить пример проблемы модели смешанного маркетинга, используя python и функцию curve_fit.

Мне нужно подогнать два набора параметров, которые я добавляю к своей функции в виде списка аргументов * arg. Я могу заставить кривую соответствовать работе для одного набора параметров (один список), но не двух.

Код

#import packages
from scipy.optimize import curve_fit
import pandas as pd
import numpy as np
from statsmodels.tsa.filters.filtertools import recursive_filter as rec

Dataset

a = np.array(0).repeat(150)
b = np.array(0).repeat(150)
c = np.array(0).repeat(150)
a[0:90] = np.random.uniform(5,10,(90,))
b[50:150] = np.random.uniform(20,40,(100,))
c[30:100] = np.random.uniform(5,25,(70,))
df = pd.DataFrame({'a':a,'b':b,'c':c})

Установка одного набора параметров

def mmm(data,*param):
    dic = {}
    j = 0
    for i in data:
        dic[i] = rec(data[i],param[j])
        j += 1
    return(np.sum(pd.DataFrame(dic),1))

Функция применяет рекурсивный фильтр к каждому полю в аргументе данных с другим лямбда-параметром и возвращает сумму строки данных.

kpi = mmm(df,*(0.5,0.5,0.1)) + np.random.uniform(-5,5)

При передаче аргумента * функции scipy curve fit вам нужно определить функцию, которая выводит функцию. Как описано здесь: передайте кортеж в качестве входного аргумента для scipy.optimize.curve_fit

Установите кривую

a = np.zeros(3)
def make_func():
    def mmm(data,*param):
        dic = {}
        j = 0
        for i in data:
            dic[i] = rec(data[i],param[j])
            j += 1
        return(np.sum(pd.DataFrame(dic),1))
    return(mmm) 
leastsq, covar = curve_fit(make_func(),df,kpi,a)

print(leastsq)
array([0.87560795, 0.87192766, 0.84864161])

Установка двух наборов параметров

def mmm(x,*arg):
    c = args[0]
    a = args[1]
    dic = {}
    j = 0
    for i in x:
        dic[i] = c[j] * rec(x[i], a[j])
        j += 1
    return(np.sum(pd.DataFrame(dic),1))   

Функция, применяет рекурсивный фильтр к каждому полю в аргументе данных с другой лямбдой (a), умножает его на скаляр (c) и берет сумму строки для данных.

args = [[4,5,3],[0.2,0.4,0.5]]
kpi = mmm(df,*args) + np.random.uniform(-5,5)

Установите кривую

args = np.zeros(6)
def make_func():
    def mmm(x,*args):
        c = args[0]
        a = args[1]
        dic = {}
        j = 0
        for i in x:
            dic[i] = c[j] * rec( x[i], a[j])
            j += 1
        return(np.sum(pd.DataFrame(dic),1))
    return(make_func)
leastsq, covar = curve_fit(make_func,df, kpi, p0=args)

Используя тот же метод, что и для одного списка параметров, выплевывает ошибку для двоих. Ошибка заключается в следующем:

TypeError: make_func() takes 0 positional arguments but 7 were given

Есть ли что-то еще, я должен сделать, чтобы заставить этот код работать?

Ура,

  • 0
    Попробуйте поставить скобку () после make_func в последней строке. Ваша ошибка не воспроизводится, потому что мы не знаем, что такое df
  • 0
    Я обновил выше, чтобы включить df dataframe.
Показать ещё 1 комментарий
Теги:
python-3.x
scipy
mathematical-optimization
curve-fitting

1 ответ

1

Есть две вещи, которые кажутся мне источником ошибки.

1) В последней части, где вы вписываете кривую в функцию make_func(), вы возвращаете сама функция. Если я сравню его с предыдущим определением функции, я думаю, что он должен быть return(mmm).

2) args = np.zeros(6) приводит к массиву нулей, который вы передаете как аргумент make_func(). Затем вы присваиваете c = args[0] и a = args[1] так что в основном c=0 и a=0 которые являются скалярными переменными. Теперь в функции mmm(x,*args): вы используете dic[i] = c[j] * rec( x[i], a[j]). Здесь всплывает IndexError: invalid index to scalar variable. потому что a и c являются скалярами, но вы используете для них индексные операции.

  • 0
    Спасибо, я сгладил все эти ошибки, но код все еще не работает. Вам удалось настроить кривую на работу?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню