
简介本资源是一套基于Python与PyQt5实现的分位数回归分析完整项目面向统计建模初学者、计量经济学课程设计者及毕业设计学生解决传统均值回归无法刻画变量关系在不同分位点异质性的问题。项目涵盖分位数Granger因果检验含Sup-Wald统计量计算、分位数向量自回归QVAR建模及多分位点脉冲响应函数绘制兼具理论严谨性与工程可执行性。压缩包共64个文件以10个核心Python脚本含main.py、func.py、GUI逻辑模块、7个.ui界面文件、3个.xlsx结果模板及配套文档README.md、运行细节.txt、LICENSE为主辅以图标资源与构建脚本整体仅1.8MB轻量易部署。已有61人学习下载提供开箱即用的GUI交互界面、statsmodels底层调用封装、pandas结果导出功能以及测试数据、输出样例和附赠内容便于快速理解算法流程、调试参数并拓展至实证研究场景。1. 分位数回归不是“换个损失函数就行”PyQt封装的QVAR分析工具专治经济金融数据里的非对称响应与尾部依赖你手头有一组GDP、通胀、利率时间序列OLS回归告诉你“利率每升1%GDP平均降0.3%”——但现实里加息2%时经济可能断崖式下滑而降息2%却只温和回暖。这种“涨得慢、跌得狠”的非对称性普通线性模型根本抓不住。分位数回归Quantile Regression正是为此而生它不拟合均值而是建模整个条件分布——比如第10分位下行风险、第50分位中位数、第90分位上行潜力。更进一步当你要问“通胀波动是否在极端下行期才真正驱动利率调整”就得用分位数Granger因果检验若变量间存在多期动态反馈QVARQuantile Vector Autoregression脉冲响应曲线才是答案。本项目用Python实现全套算法内核再用PyQt搭出免代码交互界面输入CSV、点选分位点、拖动滞后阶数、一键生成三类结果图表——不是Jupyter Notebook里调参跑通就完事而是能直接交作业、做汇报、给导师现场演示的完整工程。适合统计/计量/金融方向本科生做毕业设计也适合作为高年级课程设计载体——所有源码可读、可调试、可扩展文档覆盖数学推导、代码结构、界面逻辑三层。2. 从理论到代码分位数回归与QVAR的底层实现逻辑与PyQt封装策略2.1 为什么必须重写分位数回归求解器sklearn不香吗sklearn.linear_model.QuantileRegressor确实能跑通基础分位数回归但它有三个硬伤不支持自定义权重真实金融数据常含异方差如高频交易数据波动随时间放大需加权估计无标准误解析解学术写作要求报告t值、p值而sklearn默认只返回系数协方差矩阵需手动Bootstrap耗时且不稳定无法嵌入QVAR框架QVAR本质是多个分位数回归的联合估计需共享滞后项结构并施加约束如系数路径平滑性sklearn单模型无法协同优化。因此本项目采用内点法Interior Point Method实现分位数回归核心求解器。其目标函数为$$\min_{\beta} \sum_{i1}^n \rho_\tau(y_i - x_i^\top \beta),\quad \rho_\tau(u) u(\tau - I(u0))$$我们将其转化为线性规划问题$$\min \tau \mathbf{1}^\top \mathbf{u}^ (1-\tau)\mathbf{1}^\top \mathbf{u}^- \quad \text{s.t. } \mathbf{y} \mathbf{X}\beta \mathbf{u}^ - \mathbf{u}^-, ; \mathbf{u}^, \mathbf{u}^- \geq 0$$用scipy.optimize.linprog求解比statsmodels的迭代法更稳定且天然支持稀疏设计矩阵应对高维控制变量场景。# quantile_regression.py 核心求解函数 def solve_quantile_regression(X, y, tau0.5, weightsNone): X: (n_samples, n_features) 设计矩阵含截距项 y: (n_samples,) 因变量向量 tau: 目标分位点0.05~0.95 weights: (n_samples,) 可选权重向量用于处理异方差 返回: beta (n_features,), se_beta (n_features,) 标准误 n, p X.shape # 构造LP问题min c^T [u, u-] c np.hstack([tau * np.ones(n), (1-tau) * np.ones(n)]) # 约束Xbeta u - u- y # 拆分为[X, I, -I] [beta, u, u-]^T y A_eq np.hstack([X, np.eye(n), -np.eye(n)]) b_eq y # 非负约束u 0, u- 0 bounds [(None, None)] * p [(0, None)] * n [(0, None)] * n # 加权若提供weights则缩放等式约束等价于加权最小化 if weights is not None: A_eq np.diag(weights) A_eq b_eq weights * b_eq res linprog(c, A_eqA_eq, b_eqb_eq, boundsbounds, methodhighs) if not res.success: raise RuntimeError(fLP solver failed at tau{tau}: {res.message}) # 提取beta前p个变量 beta res.x[:p] # Bootstrap计算标准误200次重采样平衡精度与速度 n_boot 200 boot_betas np.zeros((n_boot, p)) indices np.random.choice(n, size(n_boot, n), replaceTrue) for i in range(n_boot): X_boot X[indices[i]] y_boot y[indices[i]] if weights is not None: w_boot weights[indices[i]] boot_betas[i] solve_quantile_regression(X_boot, y_boot, tau, w_boot)[0] else: boot_betas[i] solve_quantile_regression(X_boot, y_boot, tau)[0] se_beta np.std(boot_betas, axis0) return beta, se_beta提示此函数返回标准误而非p值因分位数回归的渐近分布依赖密度函数估计Bootstrap更鲁棒。若需p值可在后续模块中调用statsmodels的QuantReg作对比验证但生产环境推荐Bootstrap。2.2 QVAR建模如何把多个分位数回归拧成一个动态系统QVARQuantile Vector Autoregression不是简单地对每个变量单独做分位数回归而是构建向量自回归结构并在每个分位点τ上联合估计所有方程。设k维变量向量$Y_t [y_{1t}, ..., y_{kt}]^\top$p阶QVAR模型为$$Q_\tau(Y_t | Y_{t-1}, ..., Y_{t-p}) A_0(\tau) \sum_{j1}^p A_j(\tau) Y_{t-j}$$其中$A_j(\tau)$为$k \times k$系数矩阵。关键挑战在于不同τ下的系数应呈现平滑变化否则τ0.1和τ0.9的脉冲响应完全割裂失去经济学解释力。本项目采用分位数网格惩罚样条平滑Penalized Spline Smoothing在τ∈[0.05,0.95]上取19个等距分位点步长0.05对每个系数$a_{ij}^{(l)}(\tau)$第l阶滞后中第i行第j列元素拟合三次样条$$a_{ij}^{(l)}(\tau) \sum_{m0}^3 \gamma_{ijm}^{(l)} \tau^m \sum_{s1}^{S} \delta_{ijs}^{(l)} (\tau - \kappa_s)_^3$$加入二阶导数惩罚项$\lambda \int [a(\tau)]^2 d\tau$控制过拟合。# qvar_model.py 中的平滑拟合函数 def smooth_coefficient_path(taus, coeffs, smooth_lambda1e-3, spline_degree3): taus: (n_tau,) 分位点数组如 np.linspace(0.05, 0.95, 19) coeffs: (n_tau, n_params) 每个tau下原始估计的系数矩阵展平 smooth_lambda: 平滑惩罚强度太小则震荡太大则丢失尾部特征 返回: smooth_coeffs (n_tau, n_params) 平滑后系数 from scipy.interpolate import splrep, splev n_tau, n_params coeffs.shape smooth_coeffs np.zeros_like(coeffs) for j in range(n_params): # 对第j个参数在taus上拟合带惩罚的样条 # 使用scipy的splrep内部已集成平滑参数s tck splrep(taus, coeffs[:, j], ssmooth_lambda * np.var(coeffs[:, j])) smooth_coeffs[:, j] splev(taus, tck) return smooth_coeffs # 示例对QVAR中利率→GDP的滞后1阶系数做平滑 taus np.linspace(0.05, 0.95, 19) raw_coefs np.array([qr_result[beta][1] for qr_result in qr_results]) # 假设索引1是利率系数 smoothed_coefs smooth_coefficient_path(taus, raw_coefs.reshape(-1, 1))注意splrep的s参数需与系数方差成比例否则在低波动分位点如τ0.5过度平滑。经验法则是s smooth_lambda * var(coeff)smooth_lambda初始设为1e-3根据残差图调整。2.3 PyQt界面设计如何让统计模型“看得见、摸得着”PyQt5不是为了炫技而是解决真实痛点导师要看你是否真懂模型逻辑而不是只会复制粘贴model.fit()。因此界面设计遵循“操作即理解”原则数据导入区支持CSV/Excel自动检测时间列、数值列拒绝非数值列如字符串ID进入模型模型配置卡分位点输入框支持逗号分隔如0.05,0.25,0.5,0.75,0.95滞后阶数滑块1~12变量选择树多选因变量、自变量结果可视化区左侧Tab页切换“分位数回归表”、“Granger因果热力图”、“QVAR脉冲响应动画”右侧实时渲染Matplotlib图表导出按钮一键生成PDF报告含公式、参数、图表避免截图拼接。核心技巧在于信号-槽解耦所有计算逻辑封装在独立模块quantile_engine.py,qvar_engine.pyPyQt只负责触发、传参、接收结果、更新UI。这样既保证算法可单元测试又避免GUI线程阻塞长计算用QThread隔离。# main_window.py 关键槽函数 def on_run_qvar_clicked(self): 点击‘运行QVAR’按钮触发 try: # 1. 获取UI参数 taus [float(x.strip()) for x in self.tau_input.text().split(,)] lags self.lag_slider.value() y_vars [item.text() for item in self.y_list.selectedItems()] x_vars [item.text() for item in self.x_list.selectedItems()] # 2. 构建数据已预处理为numpy array data_matrix self.data_processor.get_design_matrix(y_vars x_vars, lags) # 3. 启动后台线程执行QVAR self.qvar_thread QVARWorker(data_matrix, taus, lags, y_vars, x_vars) self.qvar_thread.finished.connect(self.on_qvar_finished) self.qvar_thread.start() self.status_label.setText(QVAR计算中...请勿关闭窗口) except ValueError as e: QMessageBox.critical(self, 参数错误, f分位点格式错误{str(e)}) except Exception as e: QMessageBox.critical(self, 计算错误, fQVAR运行失败{str(e)}) # QVARWorker 继承QThreadrun()中调用核心算法 class QVARWorker(QThread): def __init__(self, data, taus, lags, y_vars, x_vars): super().__init__() self.data data self.taus taus self.lags lags self.y_vars y_vars self.x_vars x_vars def run(self): # 调用qvar_engine.py中的主函数 self.results qvar_engine.run_qvar( self.data, self.taus, self.lags, y_namesself.y_vars, x_namesself.x_vars )玄学经验PyQt中QThread不能直接传递大型numpy数组易内存泄漏务必在run()中重新加载或使用multiprocessing.Manager共享内存。本项目采用前者——线程内self.data仅存引用实际计算前np.copy()确保安全。3. 分位数Granger因果检验拒绝“相关即因果”在分布尾部寻找驱动证据3.1 Granger因果的分位数改造为什么传统F检验在极端情形下失效经典Granger因果检验基于OLS残差的F统计量隐含假设是误差项同方差且正态分布。但金融冲击如股灾、汇率闪崩往往导致误差分布厚尾、偏斜——此时F检验第一类错误率飙升假阳性即把噪声误判为因果。分位数Granger因果Quantile Granger Causality绕过分布假设直接检验“在条件分布的τ分位点上加入滞后X是否显著改进Y的预测”检验统计量构造如下无因果原假设 $H_0$: $Q_\tau(Y_t|Y_{t-1},...,Y_{t-p}) Q_\tau(Y_t|Y_{t-1},...,Y_{t-p},X_{t-1},...,X_{t-p})$估计两个模型限制模型Restricted仅用Y自身滞后非限制模型Unrestricted加入X滞后计算两模型在τ分位点的检查函数损失差$$\Delta L_\tau \sum_{tp1}^T \rho_\tau(y_t - \hat{q}t^{(R)}) - \sum{tp1}^T \rho_\tau(y_t - \hat{q}_t^{(U)})$$其中$\hat{q}_t^{(R)}$, $\hat{q}t^{(U)}$为对应分位数预测。若$\Delta L\tau$显著大于0则拒绝$H_0$。本项目采用Wild Bootstrap生成零分布因分位数损失非光滑传统Bootstrap不适用。Wild Bootstrap通过随机符号扰动残差$e_t^* e_t \cdot v_t$$v_t$取±1概率各0.5保持误差结构更准确。3.2 实现细节如何避免Granger检验沦为“调参游戏”分位数Granger检验有两大陷阱分位点选择偏差若只检验τ0.05和τ0.95可能遗漏中间敏感点如τ0.15。本项目强制用户指定分位点网格如0.05,0.1,0.15,...,0.95并返回全网格p值矩阵多重检验膨胀检验19个分位点若按α0.05阈值假阳性率高达$1-(0.95)^{19}≈63%$。采用Benjamini-Hochberg FDR校正控制错误发现率≤10%。# granger_test.py 核心函数 def quantile_granger_causality(y, x, taus, max_lag4, n_boot300, fdr_alpha0.1): y, x: (n_samples,) 时间序列已对齐 taus: list of float, 分位点列表 max_lag: 最大滞后阶数自动选择BIC最优阶 n_boot: Wild Bootstrap重复次数 fdr_alpha: FDR控制水平 返回: pvals (len(taus),) 校正后p值significant (bool array) 是否显著 # 步骤1用BIC选择最优滞后阶数对中位数回归 best_lag select_optimal_lag(y, x, taus[0.5], max_lagmax_lag) # 步骤2对每个tau计算ΔL_τ及Bootstrap分布 delta_L_obs np.zeros(len(taus)) delta_L_boot np.zeros((n_boot, len(taus))) for i, tau in enumerate(taus): # 估计限制模型和非限制模型 q_r quantile_regression(y[best_lag:], y[best_lag-1:-1], tau, lagsbest_lag) q_u quantile_regression(y[best_lag:], np.column_stack([y[best_lag-1:-1], x[best_lag-1:-1]]), tau, lagsbest_lag) # 计算观测损失差 pred_r q_r.predict(y[best_lag-1:-1]) pred_u q_u.predict(np.column_stack([y[best_lag-1:-1], x[best_lag-1:-1]])) delta_L_obs[i] np.mean([rho_tau(y[t] - pred_r[t-best_lag], tau) for t in range(best_lag, len(y))]) \ - np.mean([rho_tau(y[t] - pred_u[t-best_lag], tau) for t in range(best_lag, len(y))]) # Wild Bootstrap residuals y[best_lag:] - pred_r for b in range(n_boot): v np.random.choice([-1, 1], sizelen(residuals)) y_star pred_r residuals * v # 重估计两模型 q_r_star quantile_regression(y_star, y[best_lag-1:-1], tau, lagsbest_lag) q_u_star quantile_regression(y_star, np.column_stack([y[best_lag-1:-1], x[best_lag-1:-1]]), tau, lagsbest_lag) pred_r_star q_r_star.predict(y[best_lag-1:-1]) pred_u_star q_u_star.predict(np.column_stack([y[best_lag-1:-1], x[best_lag-1:-1]])) delta_L_boot[b, i] np.mean([rho_tau(y_star[t-best_lag] - pred_r_star[t-best_lag], tau) for t in range(best_lag, len(y_star))]) \ - np.mean([rho_tau(y_star[t-best_lag] - pred_u_star[t-best_lag], tau) for t in range(best_lag, len(y_star))]) # 步骤3计算p值Bootstrap pvals np.zeros(len(taus)) for i in range(len(taus)): pvals[i] np.mean(delta_L_boot[:, i] delta_L_obs[i]) # 步骤4FDR校正 significant fdrcorrection(pvals, alphafdr_alpha)[0] return pvals, significant # rho_tau辅助函数 def rho_tau(u, tau): return u * (tau - (u 0))血泪经验Wild Bootstrap中v必须严格取±1不能用标准正态否则破坏分位数损失的凸性导致Bootstrap分布失真。曾因用np.random.normal()翻车调试3小时才发现。4. QVAR脉冲响应分析如何从静态系数走向动态故事4.1 脉冲响应的分位数困境传统IRF为何在危机中“失语”标准VAR的脉冲响应函数IRF描述“对y₁施加一个单位冲击未来各期y₂的均值变化”。但2008年金融危机中美联储降息50bp美股当日涨2%τ0.9但中小企业贷款违约率跳升15%τ0.1——均值IRF只显示“微幅改善”完全掩盖了尾部风险。QVAR IRF必须回答“在分布的第τ分位点上冲击如何改变未来h期的条件分位数”数学上QVAR IRF定义为$$\psi_h^{(i,j)}(\tau) \frac{\partial Q_\tau(y_{j,th} | \mathcal{F}t)}{\partial \varepsilon{i,t}}$$其中$\varepsilon_{i,t}$为第i个变量的结构冲击。本项目采用Cholesky分解分位数模拟法先用样本协方差矩阵做Cholesky分解得到结构冲击$\varepsilon_t L^{-1} u_t$$u_t$为残差对每个τ生成N1000条路径从$t0$开始设$\varepsilon_{i,0}1$其余为0按QVAR方程递推$y_{t1} A_0(\tau) \sum A_j(\tau) y_{t1-j} \varepsilon_{t1}$在每期$h$计算N条路径的τ分位数即为$\psi_h^{(i,j)}(\tau)$。4.2 PyQt中实现动态脉冲响应可视化让“尾部风险”自己说话界面中“脉冲响应”Tab页包含左上面板变量选择下拉框冲击变量、响应变量、分位点右上面板h-step滑块1~24期实时更新图表横轴主图表区双Y轴——左轴为IRF值右轴为置信带Bootstrap标准误底部控件导出PNG、叠加多条IRF如同时看τ0.05和τ0.95、切换置信带类型标准误/分位数区间。关键实现是响应路径缓存每次参数变更如换分位点都触发全路径重算耗时约3秒N1000, h24。为避免用户等待采用懒加载进度条首次点击“绘制”时启动线程计算后续切换分位点直接从内存读取对应路径。# irf_visualizer.py 中的绘图函数 def plot_irf(ax, irf_paths, tau, h_max24, ci_level0.9): ax: matplotlib axes对象 irf_paths: dict, key为tauvalue为 (h_max, n_sim) 数组 tau: 当前显示分位点 ci_level: 置信水平默认90% paths irf_paths[tau] # (h_max, n_sim) irf_mean np.mean(paths, axis1) ci_lower np.quantile(paths, (1-ci_level)/2, axis1) ci_upper np.quantile(paths, 1-(1-ci_level)/2, axis1) # 绘制主IRF线 h_range np.arange(1, h_max1) ax.plot(h_range, irf_mean, b-, linewidth2, labelfQIRF (τ{tau})) # 填充置信带 ax.fill_between(h_range, ci_lower, ci_upper, alpha0.2, colorblue) # 添加网格和标签 ax.grid(True, alpha0.3) ax.set_xlabel(Horizon (months)) ax.set_ylabel(Response) ax.legend() ax.set_title(fQuantile Impulse Response: τ{tau}) # 在PyQt槽函数中调用 def on_irf_plot_clicked(self): tau float(self.tau_combo.currentText()) h_max self.h_slider.value() # 检查缓存 if tau not in self.irf_cache: # 启动后台计算 self.irf_worker IRFWorker(self.qvar_results, tau, h_max) self.irf_worker.finished.connect(lambda paths: self.update_irf_plot(paths, tau)) self.irf_worker.start() self.progress_bar.setVisible(True) else: self.update_irf_plot(self.irf_cache[tau], tau) def update_irf_plot(self, paths, tau): self.irf_cache[tau] paths self.irf_ax.clear() plot_irf(self.irf_ax, self.irf_cache, tau) self.irf_canvas.draw() self.progress_bar.setVisible(False)后悔药IRF计算耗时但用户常想对比不同τ。因此self.irf_cache用dict存储所有已算τ的结果内存换时间。经实测19个τ×1000路径×24期仅占约12MB RAM远低于PyQt内存阈值。5. 避坑指南分位数建模中90%新手踩过的5个致命错误5.1 现象分位数回归系数符号在τ0.1和τ0.9完全相反且p值全0.01但导师说“这不可能”原因未检验分位数交叉Quantile Crossing。当不同τ的回归线在某些X值处相交意味着模型违反单调性假设条件分位数应随τ单调增导致解释崩溃。例如τ0.1的系数为正τ0.9为负说明低分位时X促进Y高分位时X抑制Y——这在经济学中需极强机制支撑否则大概率是过拟合或数据噪声。解决在拟合后强制施加单调性约束。本项目采用重参数化法令$\beta(\tau) \int_0^\tau \gamma(s) ds$其中$\gamma(s) \geq 0$将问题转为非负约束优化。代码中启用monotonicTrue参数即可激活该模式牺牲少量拟合优度换取理论一致性。5.2 现象QVAR脉冲响应在h1期剧烈震荡之后迅速衰减为0像“脉冲后立即死亡”原因滞后阶数p过小。QVAR要求p足够大以捕捉动态但p过大又导致过拟合。新手常按AIC/BIC选p但AIC基于均值模型对分位数不适用。解决改用分位数BICQ-BIC$$\text{Q-BIC} 2 \sum_{t} \rho_\tau(y_t - \hat{q}_t) \log(T) \cdot \text{df}$$其中df为自由度。本项目在select_optimal_lag()中默认启用Q-BIC比标准BIC更稳健。实测在GDP-利率数据上Q-BIC选p3标准BIC选p1后者IRF失真。5.3 现象PyQt界面点击“运行”后无响应任务管理器显示Python进程CPU 100%但内存不涨原因QThread中直接调用matplotlib.pyplot.show()。PyQt的事件循环与matplotlib的GUI后端冲突导致死锁。解决禁用所有plt.show()改用FigureCanvasQTAgg嵌入PyQt。所有图表必须通过self.canvas FigureCanvas(fig)创建并调用self.canvas.draw()刷新。本项目plot_utils.py中所有绘图函数均返回fig, ax对象由UI层统一渲染。5.4 现象Granger因果检验p值在τ0.05处为0.001但在τ0.1处跃升至0.4中间无过渡原因分位点网格太稀疏如只设0.05,0.5,0.95无法捕捉因果效应的连续变化。统计功效在边缘分位点本就较低单点检验易受抽样变异影响。解决强制使用细密网格至少11点0.05,0.1,...,0.95并绘制p(τ)曲线。若曲线呈U型两端显著、中间不显著说明因果仅存在于极端状态若单调下降说明因果强度随τ增强。本项目granger_result_widget.py中自动绘制该曲线并标出FDR校正后的显著τ区间。5.5 现象导出PDF报告时公式乱码中文标题显示为方框原因Matplotlib默认字体不支持中文且LaTeX渲染未配置。解决在main.py入口处全局设置import matplotlib matplotlib.rcParams[font.sans-serif] [SimHei, Arial Unicode MS, DejaVu Sans] matplotlib.rcParams[axes.unicode_minus] False # 正常显示负号 # 若需LaTeX公式启用matplotlib.rcParams[text.usetex] True需系统安装TeXPDF导出使用matplotlib.backends.backend_pdf.PdfPages而非plt.savefig(xxx.pdf)确保多页报告格式统一。6. 进阶技巧用QVAR脉冲响应诊断政策时滞并反向优化分位点选择6.1 政策时滞诊断从IRF峰值位置读取“真实传导周期”央行降息后企业融资成本何时下降居民消费何时回暖传统VAR用IRF峰值位置如h3估计时滞但这是均值时滞。现实中政策对弱势群体τ0.1传导慢需6个月对金融部门τ0.9传导快1个月。QVAR IRF给出分位数时滞谱对每个τ找IRF绝对值最大值对应的h。本项目在irf_analyzer.py中内置时滞分析函数def analyze_policy_lag(irf_paths, taus, threshold0.1): irf_paths: {tau: (h_max, n_sim)} 字典 taus: 分位点列表 threshold: IRF值超过稳态标准差的比例用于定义“有效响应” 返回: lags (len(taus),) 各τ下峰值滞后delay_profile dict 描述时滞分布 lags np.zeros(len(taus)) for i, tau in enumerate(taus): path irf_paths[tau] # (h_max, n_sim) irf_mean np.mean(path, axis1) # 找第一个|irf| threshold * std(irf) 的h std_irf np.std(irf_mean) for h in range(len(irf_mean)): if abs(irf_mean[h]) threshold * std_irf: lags[i] h 1 # h从0开始返回第几期 break else: lags[i] np.nan # 未达阈值 # 生成时滞分布摘要 delay_profile { mean_lag: np.nanmean(lags), tau_10_delay: lags[np.argmin(np.abs(np.array(taus)-0.1))], tau_90_delay: lags[np.argmin(np.abs(np.array(taus)-0.9))], asymmetry: lags[np.argmin(np.abs(np.array(taus)-0.9))] - lags[np.argmin(np.abs(np.array(taus)-0.1))] } return lags, delay_profile # 示例输出 lags, profile analyze_policy_lag(irf_cache, taus[0.05,0.1,0.25,0.5,0.75,0.9,0.95]) print(f政策传导不对称性高分位τ0.9比低分位τ0.1快{profile[asymmetry]}期) # 输出政策传导不对称性高分位τ0.9比低分位τ0.1快4期6.2 反向优化分位点用IRF稳定性筛选最具信息量的τ并非所有分位点都同等重要。τ0.5中位数常被默认使用但若IRF在此处平坦无变化说明中位数对冲击不敏感而τ0.15的IRF振幅最大才是关键分位。本项目提供tau_sensitivity_score()函数量化每个τ的信息价值计算IRF路径的变异系数CVstd(IRF)/mean(|IRF|)CV越大响应越显著计算IRF的持续期从首期到IRF衰减至峰值10%的期数加权综合得分score 0.6 * CV 0.4 * duration。# tau_selector.py def select_informative_taus(irf_paths, taus, top_k3): irf_paths: {tau: (h_max, n_sim)} taus: 分位点列表 top_k: 返回top-k个最有信息量的τ 返回: selected_taus list, scores dict scores {} for tau in taus: path irf_paths[tau] irf_mean np.mean(path, axis1) cv np.std(irf_mean) / (np.mean p a hrefhttps://download.csdn.net/download/zru_9602/91459728 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p