今天,我们来谈一谈曲线拟合,想了很久要不要记录一下数据拟合曲线这个问题,最近又遇到了,还是决定浅浅记录一下,以免遗忘。
主要还是说一下类似双峰的曲线或者形状怪异的曲线怎么进行拟合。
首先说一下,在数据拟合的时候,往往遇到的曲线并非常规曲线,此时会发现,基本函数无法完美拟合,经过多方资料查找,Python有个LMFit可以拟合多个不同的常规函数形成的曲线,比如说一个双峰的曲线拟合为两个正态分布,形状怪异的曲线由两个正态加上幂函数进行拟合,那么这种情况要怎么去一步一步走呢?
注意:①此文章不是常规函数拟合(三次,幂函数,正态,二次),讲述的是混合曲线的拟合。(方法不一定最好,更好的方法还需要再查阅)
②主要是看拟合思想,提供一个思路,因为也是一个类似三方包一样的,我们需要调参,在工作或者学习中,遇到,能解决实际问题就比较好,深究具体的可能需要研究底层逻辑。
当我们拿到一个数据样本,画出了它的分布图,发现偏峰正态还是双峰,但是较低峰的峰值也不是非常明显,我们第一反应可能是拟合一个正态。此时又发现,正态分布呈偏态,可能拟合出来不能贴合图形。
一、LMFit中有个GaussianModel 可以直接帮我拟合两个双峰的曲线,但是需要注意,GaussianModel 很吃初始(initial)参数,需要我们自己先看一下起始的峰值点以及幅度。
二、曲线拟合步骤:
1.拿到数据,画出直方图,观测数据分布情况。
2.确定双峰分布,画出每个柱子的中心点位置,进行中点拟合。
3.LMFit-GaussianModel 拟合,能够看到分布两条曲线就是拟合两个正态分布。
三、代码及注释
""" -*- coding: utf-8 -*- @FileName: Gaussian.py @Software: PyCharm @Time : 2023/7/18 11:20 @Author : Panda """ import numpy as np import seaborn as sns import matplotlib.pyplot as plt from lmfit.models import GaussianModel def get_gaussianmodel(all_data): # 返回柱子数以及柱子所对应的频数(hist, bins) hist, bins = np.histogram(all_data, bins=range(0, 45), density=False) # 取出每个柱子的中点,diff为差分 x = bins[:-1] + np.diff(bins)/2 # 算出每个柱子的概率密度,每个柱子的频数除以总数 y = hist / np.sum(hist) # 画出申明 fig, ax = plt.subplots(1, 2, figsize=(12.8, 8)) # 画出数据分布直方图, 第一个图的直方图 sns.histplot(all_data, bins=range(0, 40), ax=ax[0], stat="probability") # LMFit模型申明,可以两个写在一起,也可以分开写,申明认为是两个高斯曲线拟合成的 model = (GaussianModel(prefix='g1_') + GaussianModel(prefix='g2_')) # 模型拟合参数,先观察一下大致的峰值和幅度,设置初始值 params = model.make_params( g1_amplitude=0.5, g1_center=5, g1_sigma=1, g2_amplitude=0.5, g2_center=10, g2_sigma=0.6) # 拟合高斯模型 result = model.fit(y, params, x=x) # 预测模型的一些报告,可能会告诉你有些参数不可用,和拟合程度,看拟合的结果参数 print(result.fit_report(min_correl=0.5)) # 常见的用于分析模型预测结果的函数或属性 comps = result.eval_components(x=x) # 画出第二个图的直方图 ax[1].hist(bins[:-1], bins, weights=y, color='w', ec='k') # 拟合的第一个高斯曲线 ax[1].plot(x, comps['g1_'], label=r'Gaussian #1, 3-$\sigma$ band') # 拟合的第二个高斯曲线 ax[1].plot(x, comps['g2_'], label=r'Gaussian #2, 3-$\sigma$ band') # 拟合的两个结合的总体曲线 ax[1].plot(x, comps['g1_'] + comps['g2_'], label=r'Gaussian #3, 3-$\sigma$ band') # 画出了拟合的中心散点 ax[1].scatter(x, y, marker="$\circ$",c='k')
四、具体的拟合结果解释
result.fit_report(min_correl=0.5)输出:
标签:LMFit,g2,GaussianModel,曲线,拟合,ax,bins From: https://www.cnblogs.com/future-panda/p/17562368.html