模型与数据拟合

这个模块为一些Numpy和Scipy fitting函数提供了包装器,称为Fitters。所有装配工都可以称为函数。他们举了一个例子 FittableModel 作为输入并修改其 parameters 属性。这样做的目的是使其具有可扩展性,并允许用户方便地添加其他装配工。

线性拟合是用纽比的 numpy.linalg.lstsq 功能。目前有两个非线性装配工使用 scipy.optimize.leastsqscipy.optimize.fmin_slsqp .

将输入传递给装配工的规则如下:

  • 非线性装配工当前仅处理单个模型(而不是模型集)。

  • 线性装配工可以将单个输入拟合到多个模型集,从而创建多个拟合模型。这可能需要指定 model_set_axis 参数,就像评估模型时使用的一样;这可能是装配工知道如何广播输入数据所必需的。

  • 这个 LinearLSQFitter 目前只适用于简单(不是复合)模型。

  • 当前的拟合器只处理具有单一输出的模型(包括双变量函数,如 Chebyshev2D 但不是映射的复合模型 x, y -> x', y'

简单的一维模型拟合

在本节中,我们看一个将高斯拟合到模拟数据集的简单示例。我们使用 Gaussian1DTrapezoid1D 模型和 LevMarLSQFitter 适合数据拟合:

import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models, fitting

# Generate fake data
np.random.seed(0)
x = np.linspace(-5., 5., 200)
y = 3 * np.exp(-0.5 * (x - 1.3)**2 / 0.8**2)
y += np.random.normal(0., 0.2, x.shape)

# Fit the data using a box model.
# Bounds are not really needed but included here to demonstrate usage.
t_init = models.Trapezoid1D(amplitude=1., x_0=0., width=1., slope=0.5,
                            bounds={"x_0": (-5., 5.)})
fit_t = fitting.LevMarLSQFitter()
t = fit_t(t_init, x, y)

# Fit the data using a Gaussian
g_init = models.Gaussian1D(amplitude=1., mean=0, stddev=1.)
fit_g = fitting.LevMarLSQFitter()
g = fit_g(g_init, x, y)

# Plot the data with the best-fit model
plt.figure(figsize=(8,5))
plt.plot(x, y, 'ko')
plt.plot(x, t(x), label='Trapezoid')
plt.plot(x, g(x), label='Gaussian')
plt.xlabel('Position')
plt.ylabel('Flux')
plt.legend(loc=2)

(png _, svgpdf

../_images/fitting-1.png

如上所示,一旦实例化,fitter类就可以作为接受初始模型的函数使用 (t_initg_init )以及数据值 (xy ),并返回已安装的模型 (tg

简单的二维模型拟合

类似于一维的例子,我们可以创建一个模拟的二维数据集,并拟合一个多项式模型。例如,这可以用来调整图像的背景。

import warnings
import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models, fitting

# Generate fake data
np.random.seed(0)
y, x = np.mgrid[:128, :128]
z = 2. * x ** 2 - 0.5 * x ** 2 + 1.5 * x * y - 1.
z += np.random.normal(0., 0.1, z.shape) * 50000.

# Fit the data using astropy.modeling
p_init = models.Polynomial2D(degree=2)
fit_p = fitting.LevMarLSQFitter()

with warnings.catch_warnings():
    # Ignore model linearity warning from the fitter
    warnings.simplefilter('ignore')
    p = fit_p(p_init, x, y, z)

# Plot the data with the best-fit model
plt.figure(figsize=(8, 2.5))
plt.subplot(1, 3, 1)
plt.imshow(z, origin='lower', interpolation='nearest', vmin=-1e4, vmax=5e4)
plt.title("Data")
plt.subplot(1, 3, 2)
plt.imshow(p(x, y), origin='lower', interpolation='nearest', vmin=-1e4,
           vmax=5e4)
plt.title("Model")
plt.subplot(1, 3, 3)
plt.imshow(z - p(x, y), origin='lower', interpolation='nearest', vmin=-1e4,
           vmax=5e4)
plt.title("Residual")

(png _, svgpdf

../_images/fitting-2.png