如何通过 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))
我有一个函数有多个未知参数(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))