Ошибка TypeErction при подгонке поверхности к данным трехмерного рассеяния с использованием scipy.optimize.curve_fit () - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть Pandas DataFrame со столбцами, содержащими значения x, y и z.

import pandas as pd
df = pd.DataFrame({'Age': x,
                   'Mileage': y,
                   'Price': z})

Использование scipy.optimize.curvefit() Я могу приспособить одномерную экспоненциальную функцию y = exp(-bx):

import numpy as np
from scipy.optimize import curve_fit

# fit y to x
def exp_function(x, a, b):
    return a * np.exp(-b * x)

popt, pcov = curve_fit(exp_function, df['Age'],    # x-values
                        df['Price'],               # y-values
                        absolute_sigma=False, maxfev=1000)

# popt
# array([2.81641498e+04, 1.29183078e-01])                      # a, b-values

Но когда я пытаюсь распространить тот же анализ на 3D, я сталкиваюсь a TypeError:

# fit z to (x, y)
def exp_function_2(x, y, a, b, c):
    return (a/2) * (np.exp(-b * x) + np.exp(-c * y))

popt, pcov = curve_fit(exp_function_2, 
                       df['Age'],           # x-values
                       df['Mileage'],       # y-values
                       df['Price'],         # z-values
                       absolute_sigma=False, maxfev=1000)


# TypeError: exp_function_2() takes 5 positional arguments but 1518 were given

Похоже, мне кажется, что я передаю 1518 аргументов (длина моего Pandas кадра данных) в exp_function_2().

Почему мой код работает для подгонки 2D (x, y), но зацикливается на подгонке 3D (x, y, z)?

1 Ответ

1 голос
/ 05 февраля 2020

Вы вызываете метод с неверными аргументами.

Документы указывают , что прототип - curve_fit(f, xdata, ydata, p0=None, ...), где p0 - начальное предположение для параметров вашей функции , Так что в случае, когда у вас есть TypeError, вы передаете все 1518 элементов вашего фрейма в качестве параметров по умолчанию вашей функции, которая, конечно, принимает только 5 аргументов. Тот факт, что ваш код работает в 2D-случае, является счастливым совпадением того, что ключевой аргумент p0 вообще не используется.

Вам нужно передать оба предиктора как один аргумент в xdata, и затем распакуйте их внутри экспоненциальной функции. Примерно так (хотя я не уверен, что у меня правильная индексация данных, я редко использую pandas):

def exp_function_2(x, a, b, c):
    return (a/2) * (np.exp(-b * x['Age']) + np.exp(-c * x['Mileage']))
...