Использование scipy.optimize.minimize должным образом - PullRequest
0 голосов
/ 18 июня 2019

У меня есть 2 фиксированных параметра (A,B) и 2 нефиксированных параметра (C,T_o), используемых для вычисления вычисленного значения отклика в уравнении R_computed = A + B*tanh((T-T_o)/C).Фактические значения «R», с которыми оно сравнивается, должны иметь минимально возможную ошибку между ними.Я вычислил минимальную ошибку с помощью функции, которая делает квадратный корень из суммы квадратов.

Функция - это то, что я пытаюсь минимизировать в optimize.minimize, когда C,T_o является x0и args= (A,B,R,T).

В данный момент я получаю сообщение об ошибке в строке 52: R_comp = A + B*np.tanh((T-T_o)/C)

TypeError: в Python могут быть преобразованы только массивы длины 1скаляры

Эта ошибка новая, я уже прошел эту проблему раньше, но не могу вернуться туда, где был, так как слишком много перепутал с кодом.Конечная цель - построить графики (T,R) и (T,R_new), где R_new в основном будет кривой, подходящей для R

Все, что я прокомментировал - это то, что я попробовал.

import numpy as np
#import math
import matplotlib.pyplot as plt 
import scipy

import csv
import pandas as pd
#import operator

df =pd.DataFrame.from_csv('test.csv', index_col = None)
counter = 0
upper = 0
Lower_shelf = 2.2;
#import csv

with open('test.csv') as fin:
    csvin = csv.reader(fin, skipinitialspace=True)
    col_header = next(csvin, [])[1:]
    row_header, data = zip(*((row[0], row[1:]) for row in csvin))
    for row in data:
        if int(row[2]) >= 95 :
            upper = upper + float(row[0])
            counter = counter + 1
Upper_shelf = upper/counter
A = 33.18
B = 30.98      
T = array([  67.4,  100.7,  125.1,  150.6,  175.6,  200.3,  224.9,  249.8,
        275. ,  300. ,  350.5,  399.9,  425. ,  450.2,  475. ])
R = array([  6. ,  15.5,  20. ,  22. ,  30.5,  34. ,  45. ,  57. ,  54. ,
        63. ,  59. ,  64. ,  66. ,  64. ,  69. ])
T_o = (Tmax + Tmin)/2
C = (Tmax -T_o)/2


def ssre (A,B,T,R,C):
    R_comp = A + B*np.tanh((T-T_o)/C)

    ret_val = np.sqrt((R-R_comp)**2)
    return ret_val

Result = scipy.optimize.minimize(fun = ssre,x0 =[C,T_o], args= (A, B, R,T))
C_new = Result.x[0]
T_new = Result.x[1]
R_new = A + B*np.tanh((T-T_new)/C_new)
print(Result)
plt.plot(T,R, 'o')
plt.plot(T,R_new)

1 Ответ

0 голосов
/ 19 июня 2019

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

Что касается вашего кода, я исправил следующее:

  • исправьте вызов функции ssre так, как вы передаете ей переменные.
  • исправьте вычисления квадратного корнясуммы квадрата, равного l2-норме.
import numpy as np
import matplotlib.pyplot as plt 
from scipy.optimize import minimize


def ssre (x, A, B, R, T):
    C, T_o  = x[0], x[1]
    R_comp  = A + B*np.tanh((T - T_o) / C)
    ret_val = np.linalg.norm(R - R_comp, 2)
    return ret_val

# initializations 
A   = 33.2
B   = 31
T   = np.array([67.4, 100.7, 125.1, 150.6, 175.6, 200.3, 224.9, 249.8, 275., 300., 350.5, 399.9, 425., 450.2, 475.])
R   = np.array([  6.,  15.5,   20.,   22.,  30.5,   34.,   45.,   57.,  54.,  63.,   59.,   64.,  66.,   64.,  69.])
T_o = (np.max(T) + np.min(T))/2
C   = (np.max(T) - T_o)/2

# minimize
Result = minimize(fun  = ssre,
                  x0   = [C, T_o],
                  args = (A, B, R, T))
# format results
C_new = Result.x[0]
T_new = Result.x[1]
R_new = A + B*np.tanh((T-T_new)/C_new)

# print and plot
print(Result)
plt.plot(T, R, 'o')
plt.plot(T, R_new)
plt.show()

Результат:

      fun: 11.786475736024007
 hess_inv: array([[84.27271526, -4.45138785],
       [-4.45138785, 23.62509084]])
      jac: array([1.78813934e-06, 9.53674316e-07])
  message: 'Optimization terminated successfully.'
     nfev: 76
      nit: 14
     njev: 19
   status: 0
  success: True
        x: array([ 98.74898359, 182.5084917 ])

enter image description here

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