分位数回归(Quantile regression)笔记

article/2025/9/21 21:49:15

分位数回归(Quantile regression)是在给定 X \mathbf{X} X的条件下估计 y \mathbf{y} y的中位数或其他分位数, 这是与最小二乘法估计条件均值最大的不同。

分位数回归也是一种线性回归,它为第 q q q个分位数( q ∈ ( 0 , 1 ) q\in (0, 1) q(0,1))训练得到线性预测 y ^ ( w , X ) = X w \hat{y}(w, \mathbf{X})=\mathbf{Xw} y^(w,X)=Xw, 权重 w w w通过最小化下面的公式得到
min ⁡ w 1 n samples ∑ i P B q ( y i − X i w ) + α ∣ ∣ w ∣ ∣ 1 . \min_{w} {\frac{1}{n_{\text{samples}}} \sum_i PB_q(y_i - X_i w) + \alpha ||w||_1}. wminnsamples1iPBq(yiXiw)+α∣∣w1.
其中的 P B PB PB 是pinball loss(也被称为linear loss), 定义如下式, α \alpha α 调整L1损失的大小。
P B q ( t ) = q max ⁡ ( t , 0 ) + ( 1 − q ) max ⁡ ( − t , 0 ) = { q t , t > 0 0 , t = 0 ( q − 1 ) t , t < 0 P B_q(t)=q \max (t, 0)+(1-q) \max (-t, 0)= \begin{cases}q t, & t>0 \\ 0, & t=0 \\ (q-1) t, & t<0\end{cases} PBq(t)=qmax(t,0)+(1q)max(t,0)= qt,0,(q1)t,t>0t=0t<0

分位数回归的特点:

  • 分位数回归对于异常点没有那么敏感
  • 对于数据也不要求完全符合正态分布,不用假设数据的分布服从方差固定的分布。
  • 当我们的预测结果是一个区间而不是一个点的时候更有用
  • 分位数回归相比于线性回归减少的是MAE

当然相比于普通的线性回归,分位数要求更多的训练数据,同时也比线性回归的计算更复杂。

在下面的图片是对加了符合帕累托分布( Pareto Distribution)噪声的数据进行分位数回归学习的结果
在这里插入图片描述

相应的示例代码如下:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.utils.fixes import sp_version, parse_version
from sklearn.linear_model import QuantileRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import cross_validate# 为了避免老版本SciPy的不兼容问题
solver = "highs" if sp_version >= parse_version("1.6.0") else "interior-point"# 生成样本
rng = np.random.RandomState(42)
x = np.linspace(start=0, stop=10, num=100)
X = x[:, np.newaxis]
y_true_mean = 10 + 0.5 * x# 生成满足pareto distribution的数据
y_pareto = y_true_mean + 10 * (rng.pareto(a, size=x.shape[0]) - 1 / (a - 1))# 生成分位数为0.05, 0.5, 0.95的分位数回归
quantiles = [0.05, 0.5, 0.95]
predictions = {}
out_bounds_predictions = np.zeros_like(y_true_mean, dtype=np.bool_)
for quantile in quantiles:qr = QuantileRegressor(quantile=quantile, alpha=0, solver=solver)y_pred = qr.fit(X, y_pareto).predict(X)predictions[quantile] = y_predif quantile == min(quantiles):out_bounds_predictions = np.logical_or(out_bounds_predictions, y_pred >= y_pareto)elif quantile == max(quantiles):out_bounds_predictions = np.logical_or(out_bounds_predictions, y_pred <= y_pareto)plt.plot(X, y_true_mean, color="black", linestyle="dashed", label="True mean")for quantile, y_pred in predictions.items():plt.plot(X, y_pred, label=f"Quantile: {quantile}")plt.scatter(x[out_bounds_predictions],y_pareto[out_bounds_predictions],color="black",marker="+",alpha=0.5,label="Outside interval",
)
plt.scatter(x[~out_bounds_predictions],y_pareto[~out_bounds_predictions],color="black",alpha=0.5,label="Inside interval",
)
plt.legend()
plt.xlabel("x")
plt.ylabel("y")
_ = plt.title("Quantiles of asymmetric Pareto distributed target")# 使用交叉验证比较线性回归与分位数回归
linear_regression = LinearRegression()
quantile_regression = QuantileRegressor(quantile=0.5, alpha=0, solver=solver)cv_results_lr = cross_validate(linear_regression,X,y_pareto,cv=3,scoring=["neg_mean_absolute_error", "neg_mean_squared_error"],
)
cv_results_qr = cross_validate(quantile_regression,X,y_pareto,cv=3,scoring=["neg_mean_absolute_error", "neg_mean_squared_error"],
)
print(f"""Test error (cross-validated performance){linear_regression.__class__.__name__}:MAE = {-cv_results_lr["test_neg_mean_absolute_error"].mean():.3f}MSE = {-cv_results_lr["test_neg_mean_squared_error"].mean():.3f}{quantile_regression.__class__.__name__}:MAE = {-cv_results_qr["test_neg_mean_absolute_error"].mean():.3f}MSE = {-cv_results_qr["test_neg_mean_squared_error"].mean():.3f}"""
)#Test error (cross-validated performance)
#    LinearRegression:
#    MAE = 1.732
#    MSE = 6.690
#    QuantileRegressor:
#    MAE = 1.679
#    MSE = 7.129

keras 定义pinball loss 示例

# multiple quantiles损失定义示例
def quantile_regression_loss0(y_true, y_pred, qs=[0.025, 0.1, 0.5, 0.9, 0.975]):q = tf.constant(np.array([qs]), dtype=tf.float32)e = y_true - y_predv = tf.maximum(q*e, (q-1)*e)return K.mean(v)# 如果是同时预测M个multiple quantiles
def quantile_regression_loss(y_true, y_pred, taus=tf.constant([0.025, 0.1, 0.5, 0.9, 0.975])):"""Function that computes the quantile regression lossArguments:y_pred : Shape (B x M x N) model regression predictionsy_true : Shape (B x M) ground truth targetstaus : Shape (N, ) Vector of used quantilesReturns:loss (float): value of quantile regression loss"""# 这里是因为y_true 定义的是只有一个值,如果与taus的个数一样就不要广播了y_true = tf.expand_dims(y_true, 2)# print(y_pred.shape, y_true.shape)iy = tf.broadcast_to(y_true, tf.shape(y_pred))  # 这里使用y_hat.shape会报错 ValueError: Tried to convert 'shape' to a tensor and failed. Error: Cannot convert a partially known TensorShape (None, 3, 5) to a Tensor.error = (iy - y_pred)loss = tf.maximum(taus * error, (taus - 1.) * error)return K.mean(loss)

参考资料:

  1. scikit-learn 相关的文档: 1, 2.
  2. kaggle 实现分位数回归

http://chatgpt.dhexx.cn/article/JJ8v7X0g.shtml

相关文章

分位数回归(quantile regression)简介和代码实现

普通最小二乘法如何处理异常值&#xff1f; 它对待一切事物都是一样的——它将它们平方&#xff01; 但是对于异常值&#xff0c;平方会显著增加它们对平均值等统计数据的巨大影响。 我们从描述性统计中知道&#xff0c;中位数对异常值的鲁棒性比均值强。 这种理论也可以在预测…

分位数回归(Quantile Regression)

在介绍分位数回归之前&#xff0c;先重新说一下回归分析&#xff0c;我们之前介绍了线性回归、多项式回归等等&#xff0c;基本上&#xff0c;都是假定一个函数&#xff0c;然后让函数尽可能拟合训练数据&#xff0c;确定函数的未知参数。尽可能拟合训练数据&#xff0c;一般是…

C语言最全函数大全

以下图片以字母顺序排列&#xff0c;语法着色版本。 每个函数包含函数名&#xff0c;功能&#xff0c;用法&#xff0c;举例...

C语言函数大全-- s 开头的函数(2)

s 开头的函数&#xff08;2&#xff09; 1. setlinestyle1.1 函数说明1.2 演示示例1.3 运行结果 2. setmem2.1 函数说明2.2 演示示例 3. setmode3.1 函数说明3.2 演示示例3.3 运行结果 4. setpalette4.1 函数说明4.2 演示示例4.3 运行结果 5. setrgbpalette5.1 函数说明5.2 演示…

C语言函数大全-- i 开头的函数

i 开头的函数 1. imagesize1.1 函数说明1.2 演示示例1.3 运行结果 2. initgraph2.1 函数说明2.2 演示示例2.3 运行结果 3. inport3.1 函数说明3.2 演示示例 4. insline4.1 函数说明4.2 演示示例 5. installuserdriver5.1 函数说明5.2 演示示例 6. installuserfont6.1 函数说明6…

函数 C语言】

函数的声明和定义 函数间调用关系是&#xff0c;由于函数调用其他函数&#xff0c;替他函数也可以互相调用&#xff0c;同一个函数可以被一个或多个函数调用任意次。 先声明&#xff0c;后调用。 #include <stdio.h> //去标准库下找文件 #include "stdio.h"…

【C语言】函数详解

&#x1f525;&#x1f525; 欢迎来到小林的博客&#xff01;&#xff01;       &#x1f6f0;️博客主页&#xff1a;✈️小林爱敲代码       &#x1f6f0;️专栏&#xff1a;✈️C语言快速入门       &#x1f6f0;️欢迎关注&#xff1a;&#x1f44d;点…

C语言函数大全-- s 开头的函数(1)

s 开头的函数&#xff08;1&#xff09; 1. sbrk1.1 函数说明1.2 演示示例 2. scalb&#xff0c;scalbf&#xff0c;scalbl2.1 函数说明2.2 演示示例 3. scalbln&#xff0c;scalblnf&#xff0c;scalblnl3.1 函数说明3.2 演示示例3.3 运行结果 4. scalbn&#xff0c;scalbnf&a…

【详解C语言】函数

文章目录 1. 函数是什么&#xff1f;2. C语言中函数的分类&#xff1a;1. 库函数&#xff1a;2. 自定义函数 3. 函数的参数3.1 实际参数&#xff08;实参&#xff09;3.2 形式参数&#xff08;形参&#xff09; 4. 函数的调用&#xff1a;4.1 传值调用4.2 传址调用4.3 练习 5. …

C语言函数介绍

1.字母的大小写转换-->islower() 2.快速排序函数-->qsort() 下面正式给大家介绍这两个函数 &#xff08;1&#xff09;islower() islower() 函数用来检测一个字符是否是小写字母。 在默认情况下&#xff0c;小写字母包括&#xff1a; a,b,c,d,e,f,g,h,i,j,k,l,m,n,o…

C语言标准库函数大全(ctype、time 、stdio、stdlib、math、string)

文章目录 C语言函数库:一. <ctype.h>二. <math.h>三. <stdio.h>四. <stdlib.h>五. <time.h>六. <string.h> 文档资料 C语言函数库: C语言的常用的标准头文件有 &#xff1a; <ctype.h>   <time.h>   <stdio.h> <…

【C语言进阶】最常用的库函数大全——从入门到精通

目录 前言&#xff1a; 一.字符串函数 1.strlen——求字符串长度 strlen 2.长度不受限制的字符串函数 a.strcpy——字符串拷贝 strcpy b.strcat——追加字符串 strcat c.strcmp——字符串比较 strcmp 3.长度受限制的字符串函数——strncpy,strncat,strncmp 为什么会…

C语言一些常用的函数

目录 sizeof()运算符strlen()函数abort()函数exit()函数Sleep()函数atof()将字符串转换成浮点数atoi()将字符串转换成整型数的函数atol()将字符串转换成长整型数的函数strlwr()函数strupr()函数 sizeof()运算符 sizeof()运算符: 编译器自带的,不用到任何包都能用。用法&…

C语言常用函数详解

函数详解&#xff1a; strlen(字符串长度)sizeof(字节大小)strcmp(字符串比较)strcpy(字符串拷贝)strcat(字符串追加)strncpy(字符串按字节拷贝)strncmp(字符串按字节比较)strncat(字符串按字节追加)strstr(查找字符串)strtok(查找符号)memcpy(按字节拷贝数据&#xff08;任意类…

C语言的中常用的函数

一、main函数 一个C程序就是由若干头文件和函数组成&#xff0c;有且只有一个主函数&#xff0c;即main函数。 #include <stdio.h>int main(){printf("c语言主函数");return 0; } C程序就是执行主函数里的代码&#xff0c;C语言中的唯一入口。 main前面的int…

C语言中常用的函数

C语言中常用的函数 1、putchar()函数2、getchar()函数3、pow( a , b )函数4、sqrt( a )函数5、fabs(a)函数6、puts(字符数组)函数——输出字符串的函数7、gets(字符数组)——输入字符串的函数8、strcat(a , b)函数——字符串连接函数9、strcpy函数——字符串复制函数10、strncp…

C语言中的函数(详解)

目录 1.函数是什么 2.c语言中函数的分类&#xff1a; 2.1. 库函数 2. 自定义函数 3. 函数的参数 3.1 实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 4. 函数的调用&#xff1a; 4.1 传值调用 4.2 传址调用 5. 函数的嵌套调用和链…

linux Ubuntu将默认bash修改为csh

Ubuntu将默认bash修改为csh 前言Linux系统中的shell版本问题修改方法bash切换csh方法 前言 为什么要将默认bash修改为csh&#xff0c;有时候安装的软件命令是基于csh写的&#xff0c;如果用bash使用软件就会报错&#xff0c;如&#xff1a;“No command ‘setenv’ found”&…

配置你的 csh/tcsh

配置你的 csh/tcsh 选择 csh/tcsh 和许多刚从 Linux 转到 BSD 的人不同&#xff0c;我并没有装完 BSD 就顺手安装 bash&#xff0c;因为之前除了打命令&#xff0c;我没有用到额外的功能&#xff0c;bash 也好&#xff0c;csh 也罢&#xff0c;在我眼里都是当做 shell 来用。但…

bash 和 tcsh(csh)的不同,带例子

我使用bash和tcsh(csh)过程中总结出的一些异同&#xff0c;附我的彩色的提示行配置 效果&#xff1a; 自做的彩色提示符 bash PS1 命令提示符 ## PS1\[\033[01;33m\][\D{%y-%m-%d} \t]\[\033[00m\]\[\033[01;32m\][\!]\[\033[00m\]${debian_chroot:($debian_chroot)}\[\03…