基于样条的多元分位数回归实现及predict方法报错问题咨询
带样条的多元分位数回归实现疑问
我想用带样条的多元分位数回归分析数据,数据包含3个自变量和1个因变量。我将数据划分为训练集与验证集,计划在训练集拟合模型后用验证集验证。采用statsmodels.formula.api的quantreg()及patsy的bs()实现,但调用predict()时出现报错。现存在两个疑问:
- 当前实现思路是否正确?
- 该场景下如何正确使用
predict()?
原代码
import pandas as pd import statsmodels.formula.api as smf import patsy from sklearn.model_selection import train_test_split train_x, valid_x, train_y, valid_y = train_test_split(data.iloc[:,:3], data.total, test_size=0.1, random_state = 1) train=train_x.join(train_y) vel = train['vel'] salmean = train['salmean'] em = train['em'] total = train['total'] model = smf.quantreg('total ~ bs(vel, df=3, degree=3) + bs(salmean, df=3, degree=3) + bs(em, df=3, degree=3) ', train).fit(0.9) y_pre =model.predict(valid_x)
报错信息
PatsyError: predict requires that you use a DataFrame when predicting from a model that was created using the formula api. The original error message returned by patsy is: Error evaluating factor: NotImplementedError: some data points fall outside the outermost knots, and I'm not sure how to handle them. (Patches accepted!) total ~ bs(vel, df=3, degree=3) + bs(salmean, df=3, degree=3) + bs(em, df=3, degree=3)
问题分析与解答
1. 实现思路的正确性
整体思路没问题:拆分训练/验证集、用样条拓展自变量维度、拟合分位数回归,这个流程是分位数回归建模的标准做法。但报错暴露了两个细节疏漏:
- 验证集中部分自变量值超出了训练集生成样条时的边界节点范围,而patsy的
bs()默认不支持外推计算 - 外层提示的"需要DataFrame"是patsy内部报错后的附加提示,核心问题是样条外推的限制
2. 正确使用predict()的方法
需要从固定样条节点和允许外推两个核心点调整,同时保证预测数据的变量名一致性:
修正后的代码
import pandas as pd import statsmodels.formula.api as smf from patsy import bs from sklearn.model_selection import train_test_split # 拆分数据集 train_x, valid_x, train_y, valid_y = train_test_split(data.iloc[:,:3], data.total, test_size=0.1, random_state=1) train = train_x.join(train_y) # 基于训练集提前计算每个自变量的样条节点 knots_vel = bs(train['vel'], df=3, degree=3).knots knots_salmean = bs(train['salmean'], df=3, degree=3).knots knots_em = bs(train['em'], df=3, degree=3).knots # 用固定节点拟合模型,开启extrapolate允许外推 model = smf.quantreg( 'total ~ bs(vel, knots=knots_vel, degree=3, extrapolate=True) + ' 'bs(salmean, knots=knots_salmean, degree=3, extrapolate=True) + ' 'bs(em, knots=knots_em, degree=3, extrapolate=True)', data=train ).fit(0.9) # 直接传入验证集DataFrame进行预测 y_pre = model.predict(valid_x)
关键调整说明
- 固定样条节点:基于训练集生成节点,确保训练和预测阶段使用完全一致的样条分段规则,避免因数据分布差异导致的节点偏移
- 开启外推:
extrapolate=True参数让patsy允许对超出节点范围的验证集数据进行外推计算,解决核心报错 - 变量名一致性:确保
valid_x包含vel、salmean、em三个变量名,与公式中的变量名严格对应
内容的提问来源于stack exchange,提问作者Sharon
相关产品推荐
相关产品推荐

