如何通过 Python 在给定的函数形式中获得最适合的多参数

how to get the best-fit multi parameters in a given founction form by Python

我有一个函数有多个未知参数(m, n, u, v, w, a):

z=m * (x + 273.15) -n + u * y - v * (x + 273.15)^2 - w * y^2 + a * y * (x + 273.15)

我知道 (x, y, z) 的一些要点,我的问题是我如何使用它来通过 Python 获得最合适的参数 (m, n, u, v, w, a)?谢谢!

x   y   z

400 5 -356383.4277 405 5.2 -355202.4426 410 5.4 -354021.3507 415 5.6 -352840.1520 420 5.8 -351658.8464 425 6 -350477.4341 430 6.2 -349295.9149 435 6.4 -348114.2890 440 6.6 -346932.5562 445 6.8 -345750.7167 450 7 -344568.7703 455 7.2 -343386.7171 460 7.4 -342204.5571 465 7.6 -341022.2904 470 7.8 -339839.9168 475 8 -338657.4364 480 8.2 -337474.8492 485 8.4 -336292.1552 490 8.6 -335109.3543 495 8.8 -333926.4467 500 9 -332743.4323 505 9.2 -331560.3111 510 9.4 -330377.0830 515 9.6 -329193.7482 520 9.8 -328010.3065 525 10 -326826.7581 530 10.2 -325643.1028 535 10.4 -324459.3407 540 10.6 -323275.4719 545 10.8 -322091.4962 550 11 -320907.4137 555 11.2 -319723.2244 560 11.4 -318538.9283 565 11.6 -317354.5254 570 11.8 -316170.0157 575 12 -314985.3991 580 12.2 -313800.6758 585 12.4 -312615.8457 590 12.6 -311430.9088 595 12.8 -310245.8650 600 13 -309060.7145 605 13.2 -307875.4571 610 13.4 -306690.0930 615 13.6 -305504.6220 620 13.8 -304319.0442 625 14 -303133.3596 630 14.2 -301947.5683 635 14.4 -300761.6701 640 14.6 -299575.6651 645 14.8 -298389.5533 650 15 -297203.3347 655 15.2 -296017.0092 660 15.4 -294830.5770 665 15.6 -293644.0380 670 15.8 -292457.3922 675 16 -291270.6395 680 16.2 -290083.7801 685 16.4 -288896.8138 690 16.6 -287709.7408 695 16.8 -286522.5609 700 17 -285335.2742 705 17.2 -284147.8808 710 17.4 -282960.3805 715 17.6 -281772.7734 720 17.8 -280585.0595 725 18 -279397.2388 730 18.2 -278209.3113 735 18.4 -277021.2770 740 18.6 -275833.1359 745 18.8 -274644.8880 750 19 -273456.5332 755 19.2 -272268.0717 760 19.4 -271079.5034 765 19.6 -269890.8282 770 19.8 -268702.0463 775 20 -267513.1575 780 20.2 -266324.1619 785 20.4 -265135.0596 790 20.6 -263945.8504 795 20.8 -262756.5344 800 21 -261567.1116

这些值看起来合理吗?

[1195.654050550027, 1018.6061701876612, 0.16848387190088943, 3.4621025949581963, 1067.8784835891688, 129.32110722461852]

您可以使用不同的 scipy 优化器,或者提供更好的初始值而不是全零。下面有一个小例子。

#!/usr/bin/env python3
from scipy.optimize import differential_evolution

data = """5   400 -356383.4277
5.2 405 -355202.4426
5.4 410 -354021.3507
5.6 415 -352840.152
5.8 420 -351658.8464
..... paste in the full data ...
20.6    790 -263945.8504
20.8    795 -262756.5344
21  800 -261567.1116"""

# Parse data

data = data.split("\n")
data = list(map(lambda x: filter(None, x.split(" ")), data))
data = map(lambda x: list(map(float, x)), data)
data = list(data)

def fn(x, y, m, n, u, v, w, a):
    return m * (x + 273.15) -n + u * y - v * ((x + 273.15) ** 2) - w * (y ** 2) + a * y * (x + 273.15)

def fitness(parameters):
    error = 0
    for y, x, z in data:
        res = fn(x, y, *parameters)
        error += abs(res - z) ** 2
    return error

from scipy.optimize import differential_evolution

# 6 parameters between 0 and 1200
bounds = [(0, 1200)] * 6

x = differential_evolution(fitness, bounds, disp=True).x

print(list(x))

print(fn(795, 20.8, *x))