- 科学计算
- 科研
- 数据分析
【免费下载链接】astropy
Astronomy and astrophysics core library
导读
astropy 的建模与拟合模块(astropy.modeling)在拟合前默认会校验"输入坐标数组"与"待拟合数据数组"的形状是否一致,形状不匹配会直接抛出ValueError。自 20369 号变更起,Model类新增了verify_dims_in_fitting类属性(默认True),允许模型显式退出该校验,从而拟合那些合法地返回与输入不同形状输出的模型——例如用仪器响应函数做卷积、把结果重采样到更粗网格的模型。读完本文你将掌握:该属性的默认行为、在普通模型与复合模型上的正确设置方式、底层实现原理(_verify_dims_in_fitting与_convert_input的调用链),以及一个可直接复制的完整拟合示例。
背景:拟合前的形状校验及其局限
在 astropy 中,无论使用线性拟合器还是非线性拟合器,拟合前都会先对输入数据做一次"维度一致性"检查:输入坐标x(二维模型还有y)与数据y/z必须具有相同的形状(shape)。这一约束源于最小二乘等拟合算法对输入输出的结构性假设——坐标与数据理应一一对应。
这一默认校验由 astropy/modeling/fitting.py 中的_convert_input(x, y, z, *, verify_dims=True)实现。当verify_dims=True时,代码会执行如下检查(见 fitting.py):
if z is None: if verify_dims and data_shape != x.shape: raise ValueError("x and y should have the same shape") farg = (x, y) else: if verify_dims and not (x.shape == y.shape == data_shape): raise ValueError("x, y and z should have the same shape") farg = (x, y, z)也就是说,1D 拟合在x与y形状不一致时抛出x and y should have the same shape,2D 拟合在x、y、z三者形状不一致时抛出x, y and z should have the same shape。
但有些模型会合法地改变数据形状:比如一个先与仪器响应函数做卷积、再输出到更粗网格上的模型,其输出长度与输入坐标长度天然不同。这类模型过去无法直接参与拟合,必须绕过形状检查。verify_dims_in_fitting正是为这类场景提供的显式"退出通道"。
新属性:Model.verify_dims_in_fitting
变更记录 docs/changes/modeling/20369.api.rst 指出:
Modelnow has averify_dims_in_fittingattribute, defaulting toTrue. Setting it toFalseon a model, or on any component of a compound model, skips the check that the input coordinates and the data have the same shape when fitting.
该属性在 astropy/modeling/core.py 的Model类中作为类属性定义:
# This class attribute allows users to skip the dimension check which ensures # that input coordinates are the same dimensions as the data. It is set as True # by default ensuring that the default setting is to perform the dimension check. verify_dims_in_fitting = True关键语义:
- 默认值为
True:即默认行为与历史版本完全一致——所有拟合器仍然执行形状校验,存量代码不受影响; - 值取
False时:模型自身的形状校验被跳过,拟合器会带着形状不同的x/y继续运行; - 它是类属性,推荐在自定义模型类体(class body)中声明,例如
verify_dims_in_fitting = False,所有实例自动继承。
配套的功能变更记录 docs/changes/modeling/20369.feature.rst 补充说明了设计意图:该能力允许拟合"返回数组形状与输入不同"的模型,典型如"与仪器响应卷积后在更粗网格上返回结果"的模型;同时特别强调——对复合模型(compound model),该属性必须设置在某个组件模型上,而不是设置在复合模型本身。
底层实现:_verify_dims_in_fitting如何解析退出标志
verify_dims_in_fitting并不会被直接读取,拟合器统一通过辅助函数_verify_dims_in_fitting(model)解析(定义于 astropy/modeling/fitting.py):
def _verify_dims_in_fitting(model): """ Resolve the ``verify_dims_in_fitting`` opt-out flag for ``model``. """ if model is None: return True if hasattr(model, "traverse_postorder"): # i.e. a CompoundModel nodes = model.traverse_postorder() else: nodes = [model] return not any( getattr(node, "verify_dims_in_fitting", True) is False for node in nodes )这段实现包含了三个重要设计决策:
- 普通模型:直接把模型本身放进节点列表,读其
verify_dims_in_fitting; - 复合模型:通过
traverse_postorder()(见 astropy/modeling/core.py)后序遍历整棵复合模型树,检查每一个叶子组件; - "任一叶子退出即整体退出":只要复合模型中任何一个组件设置了
False,整个复合模型的形状校验就被关闭——这正是"属性必须设置在组件上"的底层原因,也对应测试test_verify_dims_in_fitting_leaf_wins("An opt-out on any leaf disables the check for the whole compound model")验证的行为。
拟合器中的调用点
解析结果通过verify_dims=_verify_dims_in_fitting(model_copy)传入_convert_input,覆盖线性拟合与非线性拟合两条路径:
- 线性最小二乘类拟合器(
LinearLSQFitter等)在 fitting.py 调用; - 非线性拟合器(
TRFLSQFitter、LMLSQFitter、LevMarLSQFitter等)在 fitting.py 以及 L1837、L1928 等多处调用。
无论哪种拟合器,只要模型设置了verify_dims_in_fitting = False,_convert_input就会跳过形状断言,直接把坐标与数据送入后续参数求解流程。
实战示例:拟合"重采样到粗网格"的模型
官方用户指南 docs/modeling/fitting.rst 的 "Fitting models that change the shape of the data" 一节给出了完整的可运行示例。核心是自定义一个可拟合的 1D 模型,它在evaluate内部把结果重采样为 7 个点:
import numpy as np from astropy.modeling import Fittable1DModel, Parameter class RebinnedLinear1D(Fittable1DModel): verify_dims_in_fitting = False intercept = Parameter(default=0.) slope = Parameter(default=1.) @staticmethod def evaluate(x, intercept, slope): y = intercept + slope * x return np.interp(np.linspace(x.min(), x.max(), 7), x, y)生成数据:在 200 点网格上求值,模型把结果重采样到 7 个点,坐标与数据形状显式不同:
x = np.linspace(0., 10., 200) y = RebinnedLinear1D(intercept=3., slope=2.)(x) x.shape, y.shape # ((200,), (7,))如果RebinnedLinear1D没有设置verify_dims_in_fitting = False,这组(200,)坐标与(7,)数据会让拟合直接抛出ValueError;设置之后,拟合可以正常完成并恢复出原始参数:
from astropy.modeling.fitting import TRFLSQFitter fit = TRFLSQFitter() m = fit(RebinnedLinear1D(), x, y) m.parameters # array([3., 2.])注:该示例使用
TRFLSQFitter,需要环境已安装 SciPy。测试代码中同类模型还通过参数化覆盖了non_linear_fitters + fitters的全部拟合器(见下文测试章节)。
复合模型:在组件上设置
对复合模型(如|串联、*并联的组合),不要试图在复合模型对象上设置该属性,而应直接设置到其中一个叶子组件上:
from astropy.modeling import models class OptOutGaussian1D(models.Gaussian1D): verify_dims_in_fitting = False # 复合模型中任一组件退出即可关闭整体校验 compound = OptOutGaussian1D(1.0, 5.0, 0.1) * models.Const1D(1.0)在 astropy/modeling/tests/test_fitters.py 的test_verify_dims_in_fitting_leaf_wins中对此有直接验证:models.Linear1D() | models.Shift()(无退出标志)返回校验开启,而RebinnedLinear1D() | models.Shift()(含退出组件)返回校验关闭。
带单位数据的场景
astropy 模型还支持带单位的输入。拟合时CompoundModel.without_units_for_data会重建复合模型节点,退出标志之所以仍然生效,正是因为解析逻辑是从叶子节点上读取的。测试 astropy/modeling/tests/test_quantities_fitting.py(test_verify_dims_in_fitting_survives_unit_stripping)专门验证了这一点:OptOutGaussian1D(1 * u.Jy, 1 * u.um, 0.1 * u.um) * models.Const1D(1.0)在构造复合模型及执行without_units_for_data剥离单位后,_verify_dims_in_fitting均返回False,退出标志不会丢失。
测试验证:默认行为与退出行为的双向保障
围绕该特性,astropy/modeling/tests/test_fitters.py 提供了成体系的测试,可作为理解行为的权威参考:
| 测试用例 | 验证内容 |
|---|---|
test_verify_dims_in_fitting_default(L1608-L1610) | _verify_dims_in_fitting(None)与普通Linear1D默认均返回True,即默认执行校验 |
test_verify_dims_in_fitting_leaf_wins(L1613-L1616) | 复合模型中任意叶子退出,则整体关闭校验 |
test_convert_input_verify_dims_1d(L1619-L1627) | 1D 场景:形状不一致默认抛x and y should have the same shape,verify_dims=False时正常返回 |
test_convert_input_verify_dims_2d(L1630-L1639) | 2D 场景:形状不一致默认抛x, y and z should have the same shape,verify_dims=False时正常返回 |
test_fitting_verifies_dims_by_default(L1642-L1652) | 各拟合器对形状不匹配的数据默认抛ValueError |
test_fitting_with_mismatched_dims(L1655-L1668) | 各拟合器对RebinnedLinear1D(退出校验)可正常拟合,且能恢复intercept=3.0、slope=2.0的真实参数 |
其中测试用的RebinnedLinear1D定义于 test_fitters.py,其evaluate通过np.interp(np.linspace(x.min(), x.max(), 7), x, y)将任意长度的输入重采样为 7 个点,正是"返回不同形状数组"模型的真实写照。
适用场景与注意事项
- 适用场景:仪器响应卷积后降采样、直方图/分箱类模型(输出落在更粗的网格)、任何输入输出形状合法不同的可拟合模型;
- 风险提示:关闭形状校验意味着拟合器不再能保证坐标与数据一一对应,优化器与协方差估计的语义由模型自身负责,务必在
evaluate中正确处理输入输出映射关系; - 设置位置:普通模型直接在类体中写
verify_dims_in_fitting = False;复合模型必须在组件(叶子)上设置,且任一组件退出即整体退出; - 默认安全:属性默认
True,未显式设置时所有现有拟合行为保持不变,存量代码无需任何改动。
参考文件索引
- 变更记录:docs/changes/modeling/20369.api.rst、docs/changes/modeling/20369.feature.rst
- 用户指南:docs/modeling/fitting.rst("Fitting models that change the shape of the data" 章节)
- 属性定义:astropy/modeling/core.py
- 解析与校验实现:astropy/modeling/fitting.py
- 测试用例:astropy/modeling/tests/test_fitters.py、astropy/modeling/tests/test_quantities_fitting.py
- 科学计算
- 科研
- 数据分析
【免费下载链接】astropy
Astronomy and astrophysics core library
相关推荐
Astropy建模与拟合:从简单函数到复杂天体模型的终极指南
Astropy建模与拟合:从简单函数到复杂天体模型的终极指南 Astropy作为天文学和天体物理学领域的核心库,其强大的建模与拟合功能让数据分析变得简单高效。无
科学计算科研数据分析Jesse MCP 蒙特卡洛模拟工具指南:用重采样 K 线验证策略是否过拟合
Jesse MCP 蒙特卡洛模拟工具指南:用重采样 K 线验证策略是否过拟合 导读 Jesse 是一个用 Python 编写的开源加密货币交易机器人,其 MCP
金融科技数据分析后端AI 应用理解模型选择、欠拟合与过拟合:D2L项目中的关键概念解析
理解模型选择、欠拟合与过拟合:D2L项目中的关键概念解析 引言:机器学习中的根本挑战 在机器学习实践中,我们经常面临一个核心困境:如何在训练数据上表现优异的同时
人工智能深度学习机器学习教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考