【问题标题】:Fail to fit a normal distribution with Python. scipy package defects?无法使用 Python 拟合正态分布。 scipy包缺陷?
【发布时间】:2020-04-30 03:12:44
【问题描述】:
import numpy as np
from astropy import modeling
import matplotlib.pyplot as plt
from scipy import optimize

def gaussian(x, amplitude, mean, stddev):
    return amplitude * np.exp(-((x - mean)/4/stddev)**2)

# the data
m = modeling.models.Gaussian1D(amplitude=10, mean=100, stddev=10)
x = np.linspace(0, 400, 400)
data = m(x)

# fitting
popt, _ = optimize.curve_fit(gaussian, x, data)

plt.figure(0)
plt.plot(x, data)

plt.plot(x, gaussian(x, *popt))

plt.show()

我运行它来进行正态分布拟合。但它给了我一条线。想不通为什么。

但是,如果我将平均值降低到 45 以下,它将给出一个很好的拟合。这是 scipy 包的设计缺陷吗?

【问题讨论】:

    标签: python-3.x scipy normal-distribution scipy-optimize


    【解决方案1】:

    当您使用 scipy.optimize.curve_fit 时,模型参数的初始估计值(在本例中为幅度、平均值和标准差)会产生很大的不同。 您没有提供任何初步猜测。提供猜测(带有实际值),那么拟合是完美的(因为高斯是完美的高斯,没有添加噪声):

    import numpy as np
    from astropy import modeling
    import matplotlib.pyplot as plt
    from scipy import optimize
    
    def gaussian(x, amplitude, mean, stddev):
        return amplitude * np.exp(-((x - mean)/4/stddev)**2)
    
    # the data
    m = modeling.models.Gaussian1D(amplitude=10, mean=100, stddev=10)
    x = np.linspace(0, 400, 400)
    data = m(x)
    
    # fitting
    popt, _ = optimize.curve_fit(gaussian, x, data, p0 = [10, 100, 10])
    
    plt.figure(0)
    plt.plot(x, data)
    
    plt.plot(x, gaussian(x, *popt))
    
    plt.show()
    

    你会得到:gaussian fit

    您可以通过在数据中添加一些噪音来确保拟合有效,例如:

    from astropy import modeling
    import matplotlib.pyplot as plt
    from scipy import optimize
    import numpy as np
    
    def gaussian(x, amplitude, mean, stddev):
        return amplitude * np.exp(-((x - mean)/4/stddev)**2)
    
    # the data
    m = modeling.models.Gaussian1D(amplitude=10, mean=100, stddev=10)
    x = np.linspace(0, 400, 400)
    data = m(x)
    noise = np.random.normal(len(m))
    data = data + noise
    
    # fitting
    popt, _ = optimize.curve_fit(gaussian, x, data, p0 = [10, 100, 10])
    
    plt.figure(0)
    plt.plot(x, data, 'o', label = 'data')
    
    plt.plot(x, gaussian(x, *popt), label = 'fit')
    
    plt.legend()
    
    plt.show()
    

    你会得到:fit to noisy gaussian

    【讨论】:

      猜你喜欢
      • 2018-08-21
      • 2013-03-15
      • 1970-01-01
      • 2011-02-23
      • 2011-03-15
      • 2013-07-03
      • 2020-12-22
      • 1970-01-01
      • 2016-12-25
      相关资源
      最近更新 更多