Scipy ValueError: объект слишком глубокий для нужного массива с optimize.leastsq - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь согласовать свои трехмерные данные с линейной трехмерной функцией Z = a x + b y + c.Я импортирую данные с помощью панд:

dataframe = pd.read_csv('3d_data.csv',names=['x','y','z'],header=0)

print(dataframe)

            x          y          z
0   52.830740   7.812507   0.000000
1   44.647931  61.031381   8.827942
2   38.725318   0.707952  52.857968
3    0.000000  31.026271  17.743218
4   57.137854  51.291656  61.546131
5   46.341341   3.394429  26.462564
6    3.440893  46.333864  70.440650

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

def model_calc(parameter, x, y):
    a, b, c = parameter
    return a*x + b*y + c

def residual(parameter, data, x, y):
    res = []
    for _x in x:
        for _y in y:
            res.append(data-model_calc(parameter,x,y))
    return res

Я подгоняю данные к:

params0 = [0.1, -0.2,1.]
result = scipy.optimize.leastsq(residual,params0,(dataframe['z'],dataframe['x'],dataframe['y']))
fittedParams = result[0]

Но в результате получается ValueError:

ValueError: object too deep for desired array [...]
minpack.error: Result from function call is not a proper array of floats.

Я пытался минимизировать остаточную функцию, чтобы дать только одно значение илиодин np.array, но это не помогло.Я не знаю, где проблема, и, возможно, пространство для поиска параметров это не слишком сложно.Буду очень признателен за некоторые подсказки!

1 Ответ

0 голосов
/ 12 ноября 2018

Если вы подгоняете параметры к функции, вы можете использовать curve_fit . Вот реализация:

from scipy.optimize import curve_fit

def model_calc(X, a, b, c):
    x, y = X
    return a*x + b*y + c

p0 = [0.1, -0.2, 1.]
popt, pcov = curve_fit(model_calc, (dataframe.x, dataframe.y), dataframe.z, p0)  #popt is the fit, pcov is the covariance matrix (see the docs)

Обратите внимание, что ваш синтаксис должен быть, если форма f (X, a, b, c), где X может быть двухмерным вектором (см. этот пост ).

(Другой подход)

Если вы знаете, что ваша посадка будет линейной, вы можете использовать numpy.linalg.lstsq. Смотрите здесь . Пример решения:

import numpy as np
from numpy.linalg import lstsq
A = np.vstack((dataframe.x, dataframe.y, np.ones_like(dataframe.y))).T
B = dataframe.z
a, b, c = lstsq(A, B)[0]
...