PyMC 数据接口完全指南Data、get_data 与 Minibatch 的底层原理与实战用法【免费下载链接】pymcBayesian Modeling and Probabilistic Programming in Python项目地址: https://gitcode.com/GitHub_Trending/py/pymc本文基于 PyMC 仓库的 API 参考文档 展开围绕pymc.Data、pymc.get_data与pymc.Minibatch三个核心数据接口结合 pymc/data.py、pymc/model/core.py 与 tests/test_data.py 中的源码与测试用例深入讲解数据容器的创建、坐标推断、数据热替换set_data、以及面向大规模数据集的小批量采样机制。读完本文你将掌握如何在贝叶斯模型中安全地引入可变数据、如何在不重编译模型的前提下更新观测值与预测点以及如何为随机变分推断SVI等训练过程配置 Minibatch 数据流。一、认识 PyMC 的三个数据 API在 PyMC 中与数据打交道主要涉及三个公开接口它们全部在pymc/data.py中定义并通过pymc/__init__.py暴露给用户见该文件的__all__列表接口作用典型场景pm.Data(name, value, ...)在模型中注册一个可变的 SharedVariable 数据容器声明观测数据、协变量支持后续热更新pm.get_data(filename)从 pymc-examples 示例数据仓库下载数据文件返回BytesIO对象快速加载官方示例数据如radon.csvpm.Minibatch(variable, ...)从张量首维随机抽取固定大小的小批量切片SVI、大规模数据集的随机梯度训练三者的分工十分清晰Data解决「数据如何进入模型并保持可变」的问题get_data解决「示例数据从哪来」的问题Minibatch解决「数据太大时如何按批次喂给模型」的问题。下文逐一深入。二、pm.Data在模型中注册可变数据容器2.1 基本用法Data是数据接口的核心。其完整签名来自 pymc/data.pydef Data( name: str, value, *, dims: Sequence[str] | None None, coords: dict[str, Sequence | np.ndarray] | None None, infer_dims_and_coordsFalse, model: Union[BaseModel, None] None, **kwargs, ) - SharedVariable | TensorConstant:最基础的用法是在with pm.Model()上下文中声明一个观测数据集import pymc as pm import numpy as np with pm.Model() as model: data pm.Data(data, observed_data[0]) # observed_data 为列表/ndarray mu pm.Normal(mu, 0, 10) pm.Normal(y, mumu, sigma1, observeddata)2.2 参数语义与源码约束逐项看各参数在源码中的实际处理逻辑name变量名。源码会经过model.name_for(name)进行模型级重命名pymc/data.py保证命名空间唯一。valuearray_like、pandas.Series、pandas.DataFrame或xarray.DataArray。注意两类限制不支持生成器generator传入生成器会直接抛出NotImplementedError源码注释说明生成器会破坏 InferenceData 且无法作为 SharedVariable 的输入pymc/data.py。不支持 MaskedArray 或含 NaN 的数组传入np.ma.MaskedArray会抛出NotImplementedError提示应将它们直接传给observed以触发自动插补pymc/data.py。测试用例test_masked_array_error专门验证了这一点tests/test_data.py。dims维度名。可以是字符串自动包装为单元素元组或元组且len(dims)必须等于数据的ndim否则抛出ShapeErrorpymc/data.py。coords为新引入的维度提供坐标值字典。infer_dims_and_coords默认False若为True则调用determine_coords从value的 index/columns 中自动推断坐标与维度名pymc/data.py。其前身是已弃用的export_index_as_coords参数。**kwargs透传给pytensor.shared例如可以传dtype、borrow等底层选项测试test_data_kwargs覆盖此路径。2.3 坐标coords与维度的自动推断Data内部通过determine_coordspymc/data.py完成坐标推断规则分数据类型而异Series / DataFrame若value有.index则把 index 解释为该维度的坐标若还有.columns则把列名解释为第二维的坐标。维度名优先取dims其次取index.name/columns.name。xr.DataArray按dims中给出的每个维度名从 DataArray 中提取对应坐标数组。纯 ndarray只注册range(size)形式的隐式坐标若模型coords中没有显式值并要求len(dims) value.ndim。随后Data会把新维度通过model.add_coord(namedname, valuescoords.get(dname, None), lengthxshape[d])注册进模型的dim_lengths中pymc/data.py再调用model.register_data_var(x, dimsnew_dims)完成注册pymc/data.py。测试test_implicit_coords_series、test_implicit_coords_dataframe、test_implicit_coords_xarray、test_explicit_coords、test_set_coords_through_pmdatatests/test_data.py系统验证了这些路径。import pandas as pd with pm.Model() as model: # DataFrame 的 index/columns 会被自动解析为坐标 df pd.DataFrame({obs: [1.0, 2.0, 3.0]}, index[a, b, c]) data pm.Data(data, df, infer_dims_and_coordsTrue)三、热更新数据Model.set_data与pm.set_dataData返回的是一个SharedVariable默认mutableTrue因此可以在不重新编译模型图的前提下修改其取值这正是「热更新」的基石。3.1 两种调用方式模型方法model.set_data(name, values, coordsNone)pymc/model/core.py模块级函数pm.set_data(new_data, modelNone, *, coordsNone)以{变量名: 新值}字典批量更新pymc/model/core.py3.2 维度可变与坐标联动与SharedVariable.set_value不同set_data还能同步更新维度长度与坐标值。核心逻辑pymc/model/core.py若传入列表会自动转为 ndarray并通过convert_observed_data归一化新值的ndim必须与原始数据一致否则抛ValueError当某维度长度改变length_changed时若该维度已有坐标值则必须同时提供新的coords否则抛ValueError若维度长度被TensorConstant固定例如由常量shape派生则无法 resize抛ShapeError若维度长度由另一个SharedVariable决定会发出ShapeWarning提醒同步更新若由不可变变量决定则抛ShapeError。典型的两段式用法官方 docstring 示例见 pymc/model/core.pyimport pymc as pm with pm.Model() as model: x pm.Data(x, [1.0, 2.0, 3.0]) y pm.Data(y, [1.0, 2.0, 3.0]) beta pm.Normal(beta, 0, 1) obs pm.Normal(obs, x * beta, 1, observedy, shapex.shape) idata pm.sample() # 换一组新点做后验预测无需重新编译模型 with model: pm.set_data({x: [5.0, 6.0, 9.0, 12.0, 15.0]}) y_test pm.sample_posterior_predictive(idata)测试test_sample_posterior_predictive_after_set_data、test_sample_posterior_predictive_after_set_data_with_coords、test_sample_after_set_datatests/test_data.py验证了热更新后再采样、再后验预测的完整流程。3.3 常见错误与排查脱离模型上下文调用Data必须在with model:块内创建否则抛TypeError: No model on context stack...pymc/data.py对应测试test_creation_of_data_outside_model_contexttests/test_data.py。对非 Data 变量调用 set_dataset_data要求目标必须是SharedVariable即经由pm.Data创建否则抛TypeErrorpymc/model/core.py对应测试test_set_data_to_non_data_container_variablestests/test_data.py。做后验预测时遇到 PyTensor shape mismatch官方文档提示预测/后验预测阶段数据形状往往需要改变若报形状错误应回到set_data的文档确认维度更新规则pymc/data.py。四、pm.get_data一键加载官方示例数据get_data是数据获取的便捷工具pymc/data.pydef get_data(filename): Return a BytesIO object for a package data file.其实现非常简洁从 pymc-examples 仓库的示例数据目录BASE_URL见 pymc/data.py用urllib.request.urlopen拉取文件内容返回io.BytesIO对象。这意味着它需要联网且返回的是原始字节流一般配合pandas.read_csv等解析器使用import pandas as pd import pymc as pm radon pd.read_csv(pm.get_data(radon.csv))对应测试test_get_data验证了返回类型确为io.BytesIOtests/test_data.py。该接口适合在示例与教学场景中快速复现官方示例无需手工下载数据集。五、pm.Minibatch面向大数据的小批量采样Minibatch用于从变量的**首维leading dimension**随机抽取固定数量切片是大规模数据下 SVI / 随机梯度训练的核心工具。5.1 用法与签名def Minibatch(variable: TensorVariable, *variables: TensorVariable, batch_size: int):示例源码 docstringpymc/data.pydata1 np.random.randn(100, 10) data2 np.random.randn(100, 20) mdata1, mdata2 Minibatch(data1, data2, batch_size10)返回张量与输入一一对应切片索引在两批之间不重复、随机变化天然适配随机梯度训练。5.2 源码实现与约束Minibatch的实现pymc/data.py值得逐层拆解batch_size必须是整数否则抛TypeErrorpymc/data.py所有输入先经pt.as_tensor转为符号张量并对每个输入执行is_valid_observed校验不允许包含随机变量random variable的图只接受非随机数据常量、共享变量或其可推导表达式否则抛ValueErrorpymc/data.py。测试test_not_allowed验证了传入pt.random.normal(...)会被拒绝tests/test_data.py多变量时通过Assert强制所有输入的首维长度相等否则求值时抛AssertionError错误信息提示All variables shape[0] in Minibatch should be equalpymc/data.py。测试test_assert精确匹配了该信息tests/test_data.py使用pt.random.shared_rng与MinibatchIndexRV继承自 PyTensor 的IntegersRV见 pymc/data.py在[0, upper)区间内生成batch_size个随机索引随后用tensor[mb_indices]完成切片整个切片图被包装进MinibatchOp基于OpFromGraph的可识别算子pymc/data.py以避免被其他重写规则意外改写输出张量命名为minibatch.0、minibatch.1等若只传入一个变量返回单个张量传入多个则返回张量列表。5.3 典型使用场景Minibatch最常用的场景是配合 Variational APISVI做小批量随机梯度训练以及在仿真/采样流程中按批次抽取数据。测试test_1d、test_multiple_vars展示了基本行为连续两次pm.draw得到的切片形状恒为(batch_size, ...)且内容不同多变量情况下两个切片保持元素级对应关系如mA -mB见 tests/test_data.py。with pm.Model() as model: X_mb, y_mb pm.Minibatch(X, y, batch_size128) # ... 定义模型observed 使用小批量张量 ... approx pm.fit(n10000) # SVI 训练六、数据流在模型生命周期中的完整闭环把三个接口串起来可以看到一条完整的数据生命周期链路获取数据pm.get_data(radon.csv)或本地加载得到原始数据注册数据在with pm.Model()中通过pm.Data(x, data, dims..., coords...)把数据变为可变的SharedVariable并注册维度/坐标建模与采样随机变量引用数据容器pm.sample()完成后验推断热更新pm.set_data({x: new_values})替换数据含维度变化与坐标联动复用同一模型做交叉验证或对新数据做后验预测大数据训练数据量过大时改用pm.Minibatch(...)按批抽取支撑 SVI 等随机梯度类方法。这一闭环在 tests/test_data.py 中被系统覆盖从确定性数据回归test_deterministic、热更新后重采样test_sample_after_set_data、后验预测test_sample_posterior_predictive_after_set_data到数据作为索引test_shared_data_as_index、作为随机变量输入test_shared_data_as_rv_input以及数据参与似然计算test_scaling_data_works_in_likelihoodtests/test_data.py构成了数据接口的完整回归保障。七、小结与最佳实践可变数据一律走pm.Dataobserved直接传字面量数组会绑定为常量无法热更新需要set_data时必须在pm.Data中注册坐标与维度一次声明创建Data时优先用dimscoords或infer_dims_and_coordsTrue声明维度避免后续维度变化带来的ShapeError更新维度同步更新坐标set_data改变维度长度时若原维度已有坐标务必传入新的coords否则报错大数据用Minibatch只接受非随机数据多变量首维必须等长batch_size必须是整数示例数据用get_data需要联网返回BytesIO配合 pandas 解析即可。若需进一步深入可继续阅读 数据容器示例 Notebook坐标与维度专题、模型核心实现set_data/register_data_var/add_coord的完整逻辑以及 数据接口测试覆盖上述全部行为边界的回归用例。【免费下载链接】pymcBayesian Modeling and Probabilistic Programming in Python项目地址: https://gitcode.com/GitHub_Trending/py/pymc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
