Сравнивая модель с данными, чтобы найти наиболее подходящую переменную с помощью scipy.optimize.minimize () [python] - PullRequest
1 голос
/ 12 марта 2020

Мне нужно сравнить модель с данными, чтобы найти наилучший подходящий ввод. Мои данные - это поверхностная отражательная способность тела (= рассеянный свет + тепловое излучение) на разных длинах волн, и я моделирую отражательную способность, моделируя часть теплового излучения по закону Планка. Мне нужно найти температуру, при которой моделируемое излучение (и, следовательно, коэффициент отражения) соответствует наблюдениям.

Для этого я определяю закон Планка как:

h = 6.626070e-34 # the Planck constant
c = 2.997924e+8  # the speed of light in vacuum
k = 1.380649e-23 # the Boltzmann constant

def planck(T):  # Planck's law for black body radiation
    intensity = (2*h*c**2) / ( ((wvleng*1e-9)**5) * (np.exp(h*c/((wvleng*1e-9)*k*T)) - 1.0) )
    thermal = 0.95 * (intensity*np.pi*D**2)/(SSI*1e9)
    return thermal

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

def residuals(T): # 
  S = scat_light + 0.95*planck(T) # simulated reflectance
  return np.sum((reflectance - S)**2)

, где T - температура черного тела. Наконец, я использую optimize.minimize, чтобы найти, какое Т приводит к наилучшему соответствию между S (имитируемой отражательной способностью) и отражательной способностью данных:

x0 = 345.0  # initial guess, temperature is the only variable
res = scipy.optimize.minimize(residuals, x0, method='SLSQP') # optimization
fitted_temperature = res.x

Вот проблема: она дает мне температуру намного ниже (~ 220K) чем это должно быть (около 340K), не вписываясь в данные вообще. У кого-нибудь есть идеи о том, почему он не сходится должным образом? Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Хорошо, у меня было несколько проблем в моем коде:

1) В моей функции planck мое тепловое излучение относительно солнечного спектрального излучения составляет thermal = 0.95*(intensity*4*np.pi)/(SSI*1e9) вместо thermal = 0.95 * (intensity*np.pi*D**2)/(SSI*1e9).

2) Самая большая ошибка, которая дала мне ~ 200K вместо ~ 300, заключалась в моей функции residuals. Идея состоит в том, чтобы минимизировать разницу между наблюдаемыми «общими» спектрами отражения (= обратно рассеянный свет + тепловое излучение) и смоделированными «общими» спектрами (правильно рассчитанными как S = scat_light + 0.95*planck(T) в residuals. Ошибка связана с тем, что что эта функция возвращает сумму квадратов разностей между BACK-SCATTERED светом и имитированным ОБЫЧНЫМ спектром отражения (= baskscaterred + термический): поскольку «количество» обратного рассеянного света намного «меньше», чем тепловое излучение в исследуемом для длин волн он пытался уместить «меньшие» данные (и, таким образом, объяснить подгонку при низких температурах).

Я изменил это, и теперь я получаю температуру ~ 313 К, которая очень хорошо соответствует моей наблюдаемой общей кривой отражательной способности.

Спасибо всем за ваши ответы!

0 голосов
/ 12 марта 2020

Согласно документации scipy.optimize.minimize x0 должно быть следующим: «Начальное предположение. Массив вещественных элементов размера (n,), где« n »- количество независимых переменных». Итак, вы предполагаете, что температура T = 345 минимизирует сумму квадратов разностей. Затем возвращается один лучший T для всех T в ваших данных (при условии, что у вас более одного образца), чтобы минимизировать эту функцию. Поскольку, очевидно, вы знаете, что ответ должен быть около 340 КБ, я мог бы представить, что в ваших формулах есть ошибка, ведущая в или из функции planck() где-то.

Также не мешало бы посмотреть на другие атрибуты вывода res, чтобы увидеть, могут ли там быть дополнительные подсказки.

...