mapie是独立于scikit-learn的模型无关预测区间估计库,不能直接用sklearn原生模型生成预测区间,因其仅输出点估计;mapie通过包装兼容sklearn接口的模型(如randomforestregressor),结合jackknife+、cv+、分位数回归等保形预测策略,为其补全不确定性量化能力,需单独安装pip install mapie。

MAPIE是什么,为什么不能直接用sklearn自带的模型
MAPIE(Model Agnostic Prediction Intervals with Ensembles)不是scikit-learn原生模块,而是独立包,从scikit-learn 1.0起才被广泛适配——但它本身不随sklearn安装。直接调用sklearn里的LinearRegression或RandomForestRegressor得不到预测区间,因为这些模型只输出点估计。
MAPIE的作用是“套在已有模型外面”,通过分位数回归、分位数残差重采样或jackknife+等策略,为任意兼容sklearn接口的回归器补上不确定性量化能力。
常见错误现象:ModuleNotFoundError: No module named 'mapie';或者误以为sklearn.model_selection.cross_val_predict能返回区间——它不能。
- 必须显式安装:
pip install mapie(注意不是scikit-learn子模块) - MAPIE 0.7+ 才完全支持
sklearn1.0+ 的set_params和get_params规范,旧版可能报AttributeError: 'XXX' object has no attribute 'n_features_in_' - 它不修改底层模型,只是包装器,所以训练耗时≈原模型×2~3倍(取决于
method和n_bootstraps)
用MapieRegressor套住一个RandomForestRegressor并计算95%区间
这是最常用场景:已有成熟回归模型,想快速加上预测区间。关键在于选对method参数,不同方法对数据分布假设不同,直接影响区间宽度和覆盖率。
示例中用method="quantile"(分位数回归森林),它对异方差数据更鲁棒,比"base"(普通残差重采样)更推荐:
from mapie.regression import MapieRegressor from sklearn.ensemble import RandomForestRegressor from sklearn.datasets import make_regression <p>X, y = make_regression(n_samples=1000, n_features=10, noise=10, random_state=42) model = RandomForestRegressor(random_state=42) mapie = MapieRegressor( estimator=model, method="quantile", alpha=0.05, # 对应95%置信水平 cv=5, # 使用5折交叉验证生成校准集 random_state=42 ) mapie.fit(X, y) y_pred, y_pis = mapie.predict(X, return_intervals=True)</p><h1>y_pis.shape == (n_samples, 2),分别是下界和上界</h1><p></p>
-
alpha=0.05表示单侧误差率,对应整体覆盖概率≈95%,不是“每个点都95%落在区间内”的强保证,而是渐近频率意义下的平均覆盖率 -
cv="split"可换成LeaveOneOut(),但小样本下慢且不稳定;默认cv=5已足够 - 如果
y_pis出现nan或上下界倒置,大概率是method="base"遇到训练集残差为0的极端情况,换"quantile"或"enbpi"即可
如何验证预测区间的实际覆盖率是否达标
MAPIE不保证理论覆盖率严格等于1-alpha,尤其在小样本或分布偏斜时。必须做后验校验,否则区间只是“看起来像95%”,实际可能是80%或110%。
核心是用未参与拟合的测试集(不是fit时的交叉验证折),计算真实标签落在预测区间内的比例:
from sklearn.model_selection import train_test_split <p>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) mapie.fit(X_train, y_train) y_pred_test, y_pis_test = mapie.predict(X_test, return_intervals=True)</p><p>covered = ((y_test >= y_pis_test[:, 0]) & (y_test </p>
- 若
coverage ,说明区间太窄,可尝试增大<code>alpha(如0.1)、换method="enbpi"(更保守)、或增加n_bootstrap(默认100) - 若
coverage > 0.98,区间过宽,浪费信息,可减小alpha或改用method="plus"(更紧凑) - 不要在训练集上算覆盖率——那会严重高估,因模型已见过这些点
多输出回归(y是二维数组)时怎么处理
MAPIE默认只支持单输出(y.shape = (n_samples,))。若目标变量是多个(比如同时预测温度和湿度),不能直接传入y形状为(n_samples, 2)的数组,否则报错ValueError: y must be 1-dimensional。
正确做法是:对每个输出维度单独建模,用MultiOutputRegressor包装MapieRegressor——但注意,MapieRegressor本身不支持MultiOutputRegressor作为estimator,得反着来:
- 先用
MultiOutputRegressor套住基础模型(如RandomForestRegressor) - 再把整个
MultiOutputRegressor作为estimator传给MapieRegressor - 此时
method只能选"base"或"plus","quantile"不支持多输出
代码片段:
from sklearn.multioutput import MultiOutputRegressor <p>multi_model = MultiOutputRegressor(RandomForestRegressor(random_state=42)) mapie_multi = MapieRegressor( estimator=multi_model, method="plus", # 注意这里不能用"quantile" alpha=0.05, cv=3 ) mapie_multi.fit(X, y_2d) # y_2d.shape == (n_samples, 2) y_pred_multi, y_pis_multi = mapie_multi.predict(X, return_intervals=True)</p><h1>y_pis_multi.shape == (n_samples, 2, 2) → [样本, 输出维, 区间端点]</h1><p></p>
多输出场景下,每个维度的覆盖率需分别验证,且区间宽度往往差异很大——湿度预测区间可能比温度宽3倍,这是正常现象,别强行统一缩放。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











