Скупой вопрос позиционного аргумента наименьших квадратов - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь выполнить надежную нелинейную подгонку следующих данных:

r_fast:

[0.2065 0.2661 0.2026 0.22   0.2065 0.2661 0.264  0.2173 0.2615 0.2682
 0.407  0.4085 0.409  0.4045 0.405  0.3985 0.5235 0.5846 0.5171 0.5385
 0.6415 0.7661 0.699  0.6523 0.7745 0.7332 0.842  0.9085 0.909  0.8445
 0.84   0.8635]

a_fast:

[-43.3  -3.  -86.8 -10.5 -56.2  -2.5  -7.2 -12.2  -4.6  -9.  -21.3  -2.
  -3.2  -2.7  -5.8  -6.8 -15.5  -1.8 -22.1  -0.5  -8.7  -0.8   0.   -3.3
  -0.8  -0.8 -12.5  -0.5  -0.7   0.3  -1.   -1.2]

Я попробовалследующий подход.Тем не менее я получаю сообщение об ошибке:

res_soft_l1 = least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast))

Ошибка:

f() missing 1 required positional argument: 'x2'

Весь код выглядит следующим образом:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import least_squares
def f(r_fast, x0, x1, x2):
    return x[0] + r_fast**x[1] * x[2]
data= pd.read_table('/Users/Hrihaan/Desktop/Data.txt', dtype=float, header=None, sep='\s+').values
r_fast=data[:,1]
a_fast=data[:,2]
r_min=np.min(r_fast)
r_max=np.max(r_fast)
x = np.array([1.0, 1.0, 0.0])
rr= np.linspace(r_min, r_max, len(r_fast))
res_soft_l1 = least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast))
aa= f(rr, *res_soft_l1.x)
plt.xlabel('r_fast', fontsize=30)
plt.ylabel('a_fast', fontsize=30)
plt.scatter(r_fast, a_fast, c='burlywood', s=10**2)
plt.plot(rr, aa, linewidth=3, label='Power law fit')
plt.legend(fontsize=25, loc=8, framealpha=1.0, edgecolor='maroon') 
plt.show()

Я не могучтобы понять, чего мне не хватает.Любая помощь будет принята с благодарностью.Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Есть несколько проблем с кодом.

  1. Функция должна возвращать «остатки», то есть ошибку между прогнозом и фактическими значениями (y), а не прогноз. Я думаю, a_fast являются фактическими значениями в вашем случае.
  2. Параметры для оптимизации всегда должны быть первым аргументом функции. В этом случае [x0, x1 и x2]
  3. Любые другие дополнительные параметры функции должны быть переданы как args в функцию least_squares. Я считаю, что «r_fast» - ваш дополнительный параметр.

Следующий код является минимальным кодом, который работает.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import least_squares

r_fast = np.array([0.2065 ,0.2661,0.2026,0.22,0.2065,0.2661,0.264,0.2173,0.2615,0.2682
,0.407,0.4085,0.409,0.4045,0.405,0.3985,0.5235,0.5846,0.5171,0.5385
,0.6415,0.7661,0.699,0.6523,0.7745,0.7332,0.842,0.9085,0.909,0.8445
,0.84,0.8635])
a_fast = np.array([-43.3 , -3. , -86.8 ,-10.5 ,-56.2,  -2.5 , -7.2 ,-12.2,  -4.6  ,-9., -21.3  ,-2  , -3.2,  -2.7 , -5.8 , -6.8 ,-15.5 , -1.8, -22.1 , -0.5 , -8.7,  -0.8,   0. ,  -3.3 ,  -0.8,  -0.8, -12.5,  -0.5,  -0.7,   0.3 , -1. ,  -1.2])

def f(X ,r_fast):
    x0 ,x1 ,x2 = X
    return x0 + r_fast**x1 * x2 -a_fast



x_init = np.array([1.0, 1.0, 0.0])

res_soft_l1 = least_squares(f, x_init, args= ([r_fast]) ,loss='soft_l1', f_scale=0.1)

выход:

res_soft_l1.x

array([-5.43168803e+03,  1.31665146e-03,  5.43206946e+03])
1 голос
/ 04 апреля 2019

Это потому, что x нужно 4 аргумента, но он получает только 3. В строке least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast)), least_squares вызывает f со следующими аргументами:

f(r_fast=x, x0=r_fast, x1=a_fast, x2=)

Как видитеx2 отсутствует.В любом случае ничего из этого не поможет, потому что ваша функция f не использует x0, x1 или x2.

Вы можете изменить определение своей функции на:

def f(x, r_fast):
    return x[0] + r_fast**x[1] * x[2]

и least_squares вызов

least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast))
...