我正在尝试使用 curve_fit 将对数函数拟合到我的数据集,以找到对数函数的 mu、sigma 和 A,并使用它们绘制数据集的最佳曲线。但是剧情真的不是很好。我已经在 StackOverflow 中查看了一些答案并尝试了一些但它也没有用。
这就是我目前所拥有的。
import numpy as pd
from scipy.stats import lognorm
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
#Dataset
x1 = np.asarray([12.5205 12.521 12.5215 12.522 12.5225 12.523 12.5235 12.524 12.5245
12.525 12.5255 12.526 12.5265 12.527 12.5275 12.528 12.5285 12.529
12.5295 12.53 12.5305 12.531 12.5315 12.532 12.5325 12.533 12.5335
12.534 12.5345 12.535 12.5355 12.536 12.5365 12.537 12.5375 12.538
12.5385 12.539 12.5395 12.54 12.5405 12.541 12.5415 12.542 12.5425
12.543 12.5435 12.544 12.5445 12.545 12.5455 12.546 12.5465 12.547
12.5475 12.548 12.5485 12.549 12.5495 12.55 12.5505 12.551 12.5515
12.552 12.5525 12.553 12.5535 12.554 12.5545 12.555 12.5555 12.556
12.5565 12.557 12.5575 12.558 12.5585 12.559 12.5595 12.56 12.5605
12.561 12.5615 12.562 12.5625 12.563 12.5635 12.564 12.5645 12.565
12.5655 12.566 12.5665 12.567 12.5675 12.568 12.5685 12.569 12.5695
12.57 12.5705 12.571 12.5715 12.572 12.5725 12.573 12.5735 12.574
12.5745 12.575 12.5755 12.576 12.5765 12.577 12.5775 12.578 12.5785
12.579 12.5795 12.58 12.5805 12.581 12.5815 12.582 12.5825 12.583
12.5835 12.584 12.5845 12.585 12.5855 12.586 12.5865 12.587 12.5875
12.588 12.5885 12.589 12.5895 12.59 12.5905 12.591 12.5915 12.592
12.5925 12.593 12.5935 12.594 12.5945 12.595 12.5955 12.596 12.5965
12.597 12.5975 12.598 12.5985 12.599 12.5995 12.6 12.6005 12.601
12.6015 12.602 12.6025 12.603 12.6035 12.604 12.6045 12.605 12.6055
12.606 12.6065 12.607 12.6075 12.608 12.6085 12.609 12.6095 12.61
12.6105 12.611 12.6115 12.612 12.6125 12.613 12.6135 12.614 12.6145
12.615 12.6155 12.616 12.6165 12.617 12.6175 12.618 12.6185 12.619
12.6195], dtype=np.float64)
y1 = np.asarray([ 427. 440. 409. 423. 451. 423. 418. 406. 406. 456. 416. 427.
384. 448. 450. 421. 400. 412. 427. 434. 416. 424. 392. 386.
428. 428. 430. 434. 442. 421. 414. 418. 425. 418. 404. 409.
413. 421. 438. 424. 435. 382. 432. 415. 468. 420. 406. 432.
458. 402. 438. 430. 441. 425. 427. 414. 398. 396. 447. 415.
384. 393. 438. 459. 431. 426. 422. 420. 406. 446. 432. 517.
758. 1334. 2068. 3158. 4504. 5638. 6667. 7019. 7331. 7051. 6480. 5879.
5385. 4631. 4135. 3769. 3237. 2983. 2782. 2636. 2474. 2437. 2351. 2277.
2347. 2256. 2252. 2225. 2259. 2242. 2202. 2178. 2192. 2156. 2182. 2129.
2184. 2196. 2111. 2194. 2122. 2121. 2042. 2116. 2128. 2092. 2132. 2041.
2060. 2107. 2086. 2106. 1933. 1971. 1985. 2006. 1965. 2019. 1917. 1926.
1924. 1951. 2018. 2045. 2000. 2040. 1977. 2020. 1996. 1986. 1958. 2048.
1976. 1959. 2038. 1960. 2042. 2053. 1913. 1976. 2074. 2041. 1997. 2016.
1962. 2050. 1922. 2049. 1985. 2015. 2068. 1975. 2020. 2039. 2057. 1976.
2013. 1934. 1951. 2043. 1997. 1995. 2050. 1969. 1990. 2011. 2036. 2042.
2051. 1979. 2011. 1982. 1982. 1994. 2014. 1986. 1990. 2011. 1986. 2027.
2038. 1950. 2034. 1977. 2066. 1949. 2050.]], dtype=np.float64)
#Lognorm function
def lognorm_fit(x, mu, sigma, A):
y_lognorm = (A/(sigma*x*np.sqrt(2*np.pi))) * np.exp(-1* ((np.log(x) - mu)**2/(2*sigma**2)))
return y_lognorm
#Curve_fit
popt, pcov= curve_fit(lognorm_fit, x1, y1)
mu = popt[0]
sigma = popt[1]
A = popt[2]
print(mu)
print(sigma)
print(A)
ajuste = lognorm_fit(x1, mu, sigma, A)
#Plot Results
plt.plot(x1,y1, "ro")
plt.plot(x1, ajuste)
plt.show()
对数正态分布的概率密度函数的曲线形状为:
显然正确拟合数据的曲线形状是不同的:
最重要的是,高 x 的极限值(在“高原”上)不等于低 x 的极限值。
这表明对数正态方程不便于为您的实验建模。图表上表示的蓝色曲线离数据点很远也就不足为奇了。
你应该从实验的物理特性中推导出一个更真实的方程模型,而不是实际实现的对数正态方程,引入到你的软件中。
在一些评论之后:
从纯数学的角度来看,我们当然可以找到许多或多或少正确地拟合数据的函数组合。一个例子如下所示。缺点是方程模型没有物理意义
在此示例中,方程 y(x) 由两个逻辑函数的组合构成。图中给出的参数a、b、c、A、B、C的取值均为粗略值。没有进行精确的非线性回归。请注意,参数 c 和 C 的值很关键,必须更准确地计算。