-
2020-12-06 14:51:01
分位数回归森林(Quantile Regression Forests),一般回归模型预测均值,但该算法预测数据的分布。它可以用来预测给定输入的价格分布,例如,给定一些属性,汽车价格分布的第25和75百分位是多少。
大多数预测器在预测期间返回E(Y|X),这可以解释为这个问题的答案,给定输入,输出的期望值是多少?
分位数方法,在q处返回y,其中F(Y =y|X)=q,其中q是百分位数,y是分位数。一个有用的快速用例是当有许多异常值影响条件平均值时。有时重要的是获得不同百分比的估计值(例如,在对曲线进行评分时)。
注意:一些机器学习模型还返回P(Y|X)的整个分布。比如高斯过程和蒙德里安森林。一个有用的应用是超参数优化,其中条件分布P(Y|X)是平衡开发和探索的必要条件。
分位数决策树
扩展标准决策树以提供百分位数的预测是相当简单的。当一个决策树是合适的,诀窍是不仅要在叶节点上存储目标的充分统计量,如均值和方差,而且要在叶节点上存储所有的目标值。在预测中,这些被用来计算经验分位数估计。
假设参数min_samples_leaf被设置为5,那么对于一个新的样本X,当确定Y|X在不同量子位上时,叶中的5个样本被赋予相同的权重。如果min_samples_leaf被设置为1,那么期望就等于每百分位上的分位数。
注:分位数的经验估计有很多方法。scikit-garden,依赖于这个加权百分位数方法
分位数回归森林
同样的方法可以扩展到随机森林。为了估计F(Y= y |x)=q, y_train中的每个目标值都有一个权值。形式上,在估计分位数时,y_train[j]的权重为\frac{1}{T} \sum_{t=1}^{T} \frac{\mathbb{1}(y_j \in L(x))}{\sum_{i=1}^N \mathbb{1}(y_i \in L(x))},其中L(x)表示x落在叶子上。
非正式地说,这意味着对于一个新的未知样本,我们首先找到它落在每棵树上的叶子。然后,对于训练数据中的每一个(X, y),在每棵树上按如下方式赋予y一个权重。
如果它和新样本在同一片叶子上,那么重量就是样本在同一片叶子上的比例。
如果没有,则权重为零。
每个y的权值在所有树中求和并取平均值。既然我们有一个目标值数组和一个与这些目标值对应的权重数组,我们可以用它来测量经验分位数估计值。
例:
现在,我们将使用scikit-garden中的ExtraTreesQuantileRegressor来绘制波士顿数据集上的预测区间。
先引入必要的库:
加载数据和必要的估计。注意,min_samples_split被设置为10,交叉验证为5-split。
将分位数存储在98.5%和2.5个百分位。
绘制预测间隔,即原始目标值。我们看到大多数样本位于 95 p.c 预测间隔内。
更多相关内容 -
分位数回归(quantile regression)简介和代码实现
2021-11-01 09:04:07这种理论也可以在预测统计中为我们服务,这正是分位数回归的意义所在——估计中位数(或其他分位数)而不是平均值。 通过选择任何特定的分位数阈值,我们既可以缓和异常值,也可以调整错误的正/负权衡。我们还可以...普通最小二乘法如何处理异常值? 它对待一切事物都是一样的——它将它们平方! 但是对于异常值,平方会显著增加它们对平均值等统计数据的巨大影响。
我们从描述性统计中知道,中位数对异常值的鲁棒性比均值强。 这种理论也可以在预测统计中为我们服务,这正是分位数回归的意义所在——估计中位数(或其他分位数)而不是平均值。 通过选择任何特定的分位数阈值,我们既可以缓和异常值,也可以调整错误的正/负权衡。我们还可以处理需要分位数界限的情况,例如:婴儿的安全出生体重,顶级竞技电子竞技玩家的技能水平,等等。
什么是分位数?
分位数(Quantile),亦称分位点,是指将一个随机变量的概率分布范围分为几个等份的数值点,常用的有中位数(即二分位数)、四分位由3个部分组成(第25、50和75个百分位,常用于箱形图)和百分位数等。
什么是分位数回归?
分位数回归是简单的回归,就像普通的最小二乘法一样,但不是最小化平方误差的总和,而是最小化从所选分位数切点产生的绝对误差之和。 如果 q=0.50(中位数),那么分位数回归会出现一个特殊情况 - 最小绝对误差(因为中位数是中心分位数)。我们可以通过调整超参数 q,选择一个适合平衡特定于需要解决问题的误报和漏报的阈值。
statsmodels中的分位数回归
分位数回归是一种不太常见的模型,但 Python中的StatsModel库提供了他的实现。这个库显然受到了R的启发,并从它借鉴了各种语法和API。
StatsModel使用的范例与scikit-learn稍有不同。但是与scikit-learn一样,对于模型对象来说,需要公开一个.fit()方法来实际训练和预测。但是不同的是scikit-learn模型通常将数据(作为X矩阵和y数组)作为.fit()的参数,而StatsModel是在初始化对象时传入数据,而fit方法只传递一些可以调试的超参数。
下面是来自statsmodel的例子(Engel数据集包含在与statmodels中)
%matplotlib inline import numpy as np import pandas as pd import statsmodels.api as sm import statsmodels.formula.api as smf import matplotlib.pyplot as plt data = sm.datasets.engel.load_pandas().data mod = smf.quantreg("foodexp ~ income", data) res = mod.fit(q=0.5) print(res.summary())
我们可以看看quantile regression model fit的帮助文档:
help(quant_mod.fit)
分位数回归与线性回归
标准最小二乘回归模型仅对响应的条件均值进行建模,并且计算成本较低。 相比之下,分位数回归最常用于对响应的特定条件分位数进行建模。 与最小二乘回归不同,分位数回归不假设响应具有特定的参数分布,也不假设响应具有恒定方差。
下表总结了线性回归和分位数回归之间的一些重要区别:
xgboost的分位数回归
最后如果想使用xgboost,又想试试分位数回归,那么可以参考以下代码
class XGBQuantile(XGBRegressor): def __init__(self,quant_alpha=0.95,quant_delta = 1.0,quant_thres=1.0,quant_var =1.0,base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bytree=1, gamma=0, learning_rate=0.1, max_delta_step=0,max_depth=3, min_child_weight=1, missing=None, n_estimators=100, n_jobs=1, nthread=None, objective='reg:linear', random_state=0,reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,silent=True, subsample=1): self.quant_alpha = quant_alpha self.quant_delta = quant_delta self.quant_thres = quant_thres self.quant_var = quant_var super().__init__(base_score=base_score, booster=booster, colsample_bylevel=colsample_bylevel, colsample_bytree=colsample_bytree, gamma=gamma, learning_rate=learning_rate, max_delta_step=max_delta_step, max_depth=max_depth, min_child_weight=min_child_weight, missing=missing, n_estimators=n_estimators, n_jobs= n_jobs, nthread=nthread, objective=objective, random_state=random_state, reg_alpha=reg_alpha, reg_lambda=reg_lambda, scale_pos_weight=scale_pos_weight, seed=seed, silent=silent, subsample=subsample) self.test = None def fit(self, X, y): super().set_params(objective=partial(XGBQuantile.quantile_loss,alpha = self.quant_alpha,delta = self.quant_delta,threshold = self.quant_thres,var = self.quant_var) ) super().fit(X,y) return self def predict(self,X): return super().predict(X) def score(self, X, y): y_pred = super().predict(X) score = XGBQuantile.quantile_score(y, y_pred, self.quant_alpha) score = 1./score return score @staticmethod def quantile_loss(y_true,y_pred,alpha,delta,threshold,var): x = y_true - y_pred grad = (x<(alpha-1.0)*delta)*(1.0-alpha)- ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )*x/delta-alpha*(x>alpha*delta) hess = ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )/delta grad = (np.abs(x)<threshold )*grad - (np.abs(x)>=threshold )*(2*np.random.randint(2, size=len(y_true)) -1.0)*var hess = (np.abs(x)<threshold )*hess + (np.abs(x)>=threshold ) return grad, hess @staticmethod def original_quantile_loss(y_true,y_pred,alpha,delta): x = y_true - y_pred grad = (x<(alpha-1.0)*delta)*(1.0-alpha)-((x>=(alpha-1.0)*delta)& (x<alpha*delta) )*x/delta-alpha*(x>alpha*delta) hess = ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )/delta return grad,hess @staticmethod def quantile_score(y_true, y_pred, alpha): score = XGBQuantile.quantile_cost(x=y_true-y_pred,alpha=alpha) score = np.sum(score) return score @staticmethod def quantile_cost(x, alpha): return (alpha-1.0)*x*(x<0)+alpha*x*(x>=0) @staticmethod def get_split_gain(gradient,hessian,l=1): split_gain = list() for i in range(gradient.shape[0]): split_gain.append(np.sum(gradient[:i])/(np.sum(hessian[:i])+l)+np.sum(gradient[i:])/(np.sum(hessian[i:])+l)-np.sum(gradient)/(np.sum(hessian)+l) ) return np.array(split_gain)
https://gist.github.com/benoitdescamps/af5a8e42d5cfc7981e960e4d559dad19#file-xgboostquantile-py
对于LightGBM这里有一篇详细的实现文章:
http://jmarkhou.com/lgbqr/
-
分位数回归
2019-02-27 19:46:40分位数回归 做回归处理时的一种优化算法 数据处理方面 -
非参数检验:秩相关和分位数回归
2020-06-15 22:41:26非参数检验:秩相关和分为数回归非参数检验:秩相关和分为数回归一.Spearman秩相关检验1.Pearson相关系数2.Spearman相关系数二.Kendall 协同相关检验三.多变量Kendall 协和系数相关检验四.Kappa一致性检验五.中位数...引用书籍:非参数统计(第2版)王星 编著
非参数检验:秩相关和分位数回归
非参数检验:秩相关和分为数回归
一.Spearman秩相关检验
1.Pearson相关系数
Pearson相关系数一般用于参数推断中,而在一些非参数推断中我们一般采用Spearman相关系数来描述两个样本的相关程度。
2.Spearman相关系数
采用Spearman秩相关检验来研究大学成绩与高中成绩之间的关系
大学成绩与高中成绩的秩计算表
因此,我们接受H1,认为他们之间相关。R实现
High=c(65,79,67,66,89,85,84,73,88,80,86,75) University=c(62,66,50,68,88,86,64,62,92,64,81,80) cor.test(High,University,method = "spearman")
结果:
rho 是spearman相关系数
二.Kendall 协同相关检验
例如研究学生体重和肺活量的关系
三.多变量Kendall 协和系数相关检验
四.Kappa一致性检验
五.中位数回归系数估计法
1.Brown-Mood方法
2.Theil方法
五.线性分位回归模型
-
基于深度学习分位数回归模型的风电功率概率密度预测
2021-01-12 19:02:21针对风电功率预测问题,在现有预测方法和概率性区间预测的基础上,提出基于深度学习分位数回归的风电功率概率预测方法。该方法采用Adam随机梯度下降法在不同分位数条件下对长短期记忆神经网络(LSTM)的输入、遗忘、... -
Non-crossing polynomial quantile regression:非交叉多项式分位数回归-matlab开发
2021-05-30 03:42:18该算法使用使用非交叉约束的逐步多分位数回归估计(Wu 和 Liu,2009)。 从某种意义上说,该方法是逐步估计分位数函数的,因此它不会与前一步拟合的函数交叉。 该算法从中间分位数(即最接近 0.5 的分位数)开始,... -
基于分位数回归模型的沪深股市风险测量研究 (2008年)
2021-05-08 18:43:10探讨了分位数回归理论相对于传统最小二乘回归模型在金融时间序列建模和风险测量方面的应用特点...结果表明:分位数回归模型适用于金融时间序列厚尾数据在高置信水平下的VaR估计,是一个有效的半参数风险测量方法和认识 -
论文研究 - 基于不对称拉普拉斯分布的贝叶斯正则化分位数回归分析
2020-05-15 19:44:26近年来,基于惩罚似然法的变量选择引起了人们的广泛关注。... 并且基于非对称拉普拉斯分布,贝叶斯正则化分位数回归方法在参数估计和预测方面要比非贝叶斯方法更好。 通过实际数据分析,我们也证实了以上结论。 -
分位数回归及其Python源码
2020-12-06 14:51:03分位数回归及其Python源码天朗气清,惠风和畅。赋闲在家,正宜读书。前人文章,不得其解。代码开源,无人注释。你们不来,我行我上。废话少说,直入主题。o( ̄︶ ̄)o我们要探测自变量 与因变量 的关系,最简单的方法...分位数回归及其Python源码
天朗气清,惠风和畅。赋闲在家,正宜读书。前人文章,不得其解。代码开源,无人注释。你们不来,我行我上。废话少说,直入主题。o( ̄︶ ̄)o
我们要探测自变量
与因变量
的关系,最简单的方法是线性回归,即假设:
我们通过最小二乘方法 (OLS: ordinary least squares),
的可靠性问题,我们同时对残差
做了假设,即:
为均值为0,方差恒定的独立随机变量。
即为给定自变量
下,因变量
的条件均值。
假如残差
不满足我们的假设,或者更重要地,我们不仅仅想要知道
的在给定
下的条件均值,而且想知道是条件中位数(更一般地,条件分位数),那么OLS下的线性回归就不能满足我们的需求。分位数回归(Quantile Regression)[2]解决了这些问题,下面我先给出一个分位数回归的实际应用例子,再简述其原理,最后再分析其在Python实现的源代码。
1. 一个例子:收入与食品消费
这个例子出自statasmodels:Quantile Regression.[3] 我们想探索家庭收入与食品消费的关系,数据出自working class Belgian households in 1857 (the Engel data).我们用Python包statsmodels实现分位数回归。
1.1 预处理
%matplotlib inline
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
data = sm.datasets.engel.load_pandas().data
data.head()
income foodexp
0420.157651255.839425
1541.411707310.958667
2901.157457485.680014
3639.080229402.997356
4750.875606495.560775
1.2 中位数回归 (分位数回归的特例,q=0.5)
mod = smf.quantreg('foodexp ~ income', data)
res = mod.fit(q=.5)
print(res.summary())
QuantReg Regression Results
==============================================================================
Dep. Variable: foodexp Pseudo R-squared: 0.6206
Model: QuantReg Bandwidth: 64.51
Method: Least Squares Sparsity: 209.3
Date: Mon, 21 Oct 2019 No. Observations: 235
Time: 17:46:59 Df Residuals: 233
Df Model: 1
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 81.4823 14.634 5.568 0.000 52.649 110.315
income 0.5602 0.013 42.516 0.000 0.534 0.586
==============================================================================
The condition number is large, 2.38e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
由结果可以知道
,如何得到回归系数的估计?结果中的std err, t, Pseudo R-squared等是什么?我会在稍后解释。
1.3 数据可视化
我们先拟合10个分位数回归,分位数q分别在0.05到0.95之间。
quantiles = np.arange(.05, .96, .1)
def fit_model(q):
res = mod.fit(q=q)
return [q, res.params['Intercept'], res.params['income']] + \
res.conf_int().loc['income'].tolist()
models = [fit_model(x) for x in quantiles]
models = pd.DataFrame(models, columns=['q', 'a', 'b', 'lb', 'ub'])
ols = smf.ols('foodexp ~ income', data).fit()
ols_ci = ols.conf_int().loc['income'].tolist()
ols = dict(a = ols.params['Intercept'],
b = ols.params['income'],
lb = ols_ci[0],
ub = ols_ci[1])
print(models)
print(ols)
q a b lb ub
0 0.05 124.880096 0.343361 0.268632 0.418090
1 0.15 111.693660 0.423708 0.382780 0.464636
2 0.25 95.483539 0.474103 0.439900 0.508306
3 0.35 105.841294 0.488901 0.457759 0.520043
4 0.45 81.083647 0.552428 0.525021 0.579835
5 0.55 89.661370 0.565601 0.540955 0.590247
6 0.65 74.033435 0.604576 0.582169 0.626982
7 0.75 62.396584 0.644014 0.622411 0.665617
8 0.85 52.272216 0.677603 0.657383 0.697823
9 0.95 64.103964 0.709069 0.687831 0.730306
{'a': 147.47538852370562, 'b': 0.48517842367692354, 'lb': 0.4568738130184233,
这里拟合了10个回归,其中q是对应的分位数,a是斜率,b是回归系数。lb和ub分别是b的95%置信区间的下界与上界。
现在来画出这10条回归线:
x = np.arange(data.income.min(), data.income.max(), 50)
get_y = lambda a, b: a + b * x
fig, ax = plt.subplots(figsize=(8, 6))
for i in range(models.shape[0]):
y = get_y(models.a[i], models.b[i])
ax.plot(x, y, linestyle='dotted', color='grey')
y = get_y(ols['a'], ols['b'])
ax.plot(x, y, color='red', label='OLS')
ax.scatter(data.income, data.foodexp, alpha=.2)
ax.set_xlim((240, 3000))
ax.set_ylim((240, 2000))
legend = ax.legend()
ax.set_xlabel('Income', fontsize=16)
ax.set_ylabel('Food expenditure', fontsize=16);
上图中虚线是分位数回归线,红线是线性最小二乘(OLS)的回归线。通过观察,我们可以发现3个现象:
随着收入提高,食品消费也在提高。
随着收入提高,家庭间食品消费的差别拉大。穷人别无选择,富人能选择生活方式,有喜欢吃贵的,也有喜欢吃便宜的。然而我们无法通过OLS发现这个现象,因为它只给了我们一个均值。
对与穷人来说,OLS预测值过高。这是因为少数的富人拉高了整体的均值,可见OLS对异常点敏感,不是一个稳健的模型。
2.分位数回归的原理
这部分是数理统计的内容,只关心如何实现的朋友可以略过。我们要解决以下这几个问题:
什么是分位数?
如何求分位数?
什么是分位数回归?
分位数回归的回归系数如何求得?
回归系数的检验如何进行?
如何评估回归拟合优度?
2.1 分位数的定义]
是随机变量,
的累积密度函数是
.
的
分位数为:
,
假设有100个人,95%的人身高少于1.9m, 1.9m就是身高的95%分位数。
2.2 分位数的求法
通过选择不同的
值,使
最小,对应的
值即为
的
分位数的估计
.
2.3 分位数回归
对于OLS, 我们有:
为
最小化所对应的
,类比地,对于
分位数回归,我们有:
为最小化:
即最小化
所对应的
2.4 系数估计
由于
不能直接对
求导,我们只能用迭代的方法来逼近
最小时对应的
值。statsmodels采用了Iteratively reweighted least squares (IRLS)的方法。
假设我们要求
最小化形如下的
范数:
则第t+1步迭代的
值为:
是对角矩阵且初始值为
第t次迭代
以中位数回归为例子(q=0.5),我们求:
即
即最小化形如上的
范数,
为避免分母为0,我们取
,
是一个很小的数,例如0.0001.
2.5 回归系数的检验
我们通过2.4,多次迭代得出
的估计值,为了得到假设检验的t统计量,我们只需得到
的方差的估计。
分位数回归
的协方差矩阵的渐近估计为:
其中
是对角矩阵,
当
,
, 当
,
的估计为
其中
为核函数(Kernel),可取Epa,Gaussian等.
为根据Stata 12所选的窗宽(bandwidth)[5]
回归结果中的std err即由
获得,t统计量等于
。
2.6 拟合优度
对于OLS,我们用
来衡量拟合优度。对于
分位数回归,我们类比得到:
,其中
为所有
观察值的
分位数。
即为回归结果中的Pseudo R-squared。
3.Python源码分析
实现分位数回归的完整源码在 ,里面主要含有两个类QuantReg 和 QuantRegResults. 其中QuantReg是核心,包含了回归系数估计,协方差计算等过程。QuantRegResults计算拟合优度并组织回归结果。
3.1 QuantReg类
#QuantReg是包中RegressionModel的一个子类
class QuantReg(RegressionModel):
#计算回归系数及其协方差矩阵。q是分位数,vcov是协方差矩阵,默认robust即2.5的方法。核函数kernel默认
#epa,窗宽bandwidth默认hsheather.IRLS最大迭代次数默认1000,差值默认小于1e-6时停止迭代
def fit(self, q=.5, vcov='robust', kernel='epa', bandwidth='hsheather',
max_iter=1000, p_tol=1e-6, **kwargs):
"""
Solve by Iterative Weighted Least Squares
Parameters
----------
q : float
Quantile must be between 0 and 1
vcov : str, method used to calculate the variance-covariance matrix
of the parameters. Default is ``robust``:
- robust : heteroskedasticity robust standard errors (as suggested
in Greene 6th edition)
- iid : iid errors (as in Stata 12)
kernel : str, kernel to use in the kernel density estimation for the
asymptotic covariance matrix:
- epa: Epanechnikov
- cos: Cosine
- gau: Gaussian
- par: Parzene
bandwidth : str, Bandwidth selection method in kernel density
estimation for asymptotic covariance estimate (full
references in QuantReg docstring):
- hsheather: Hall-Sheather (1988)
- bofinger: Bofinger (1975)
- chamberlain: Chamberlain (1994)
"""
if q < 0 or q > 1:
raise Exception('p must be between 0 and 1')
kern_names = ['biw', 'cos', 'epa', 'gau', 'par']
if kernel not in kern_names:
raise Exception("kernel must be one of " + ', '.join(kern_names))
else:
kernel = kernels[kernel]
if bandwidth == 'hsheather':
bandwidth = hall_sheather
elif bandwidth == 'bofinger':
bandwidth = bofinger
elif bandwidth == 'chamberlain':
bandwidth = chamberlain
else:
raise Exception("bandwidth must be in 'hsheather', 'bofinger', 'chamberlain'")
#endog样本因变量,exog样本自变量
endog = self.endog
exog = self.exog
nobs = self.nobs
exog_rank = np.linalg.matrix_rank(self.exog)
self.rank = exog_rank
self.df_model = float(self.rank - self.k_constant)
self.df_resid = self.nobs - self.rank
#IRLS初始化
n_iter = 0
xstar = exog
beta = np.ones(exog_rank)
# TODO: better start, initial beta is used only for convergence check
# Note the following does not work yet,
# the iteration loop always starts with OLS as initial beta
# if start_params is not None:
# if len(start_params) != rank:
# raise ValueError('start_params has wrong length')
# beta = start_params
# else:
# # start with OLS
# beta = np.dot(np.linalg.pinv(exog), endog)
diff = 10
cycle = False
history = dict(params = [], mse=[])
#IRLS迭代
while n_iter < max_iter and diff > p_tol and not cycle:
n_iter += 1
beta0 = beta
xtx = np.dot(xstar.T, exog)
xty = np.dot(xstar.T, endog)
beta = np.dot(pinv(xtx), xty)
resid = endog - np.dot(exog, beta)
mask = np.abs(resid) < .000001
resid[mask] = ((resid[mask] >= 0) * 2 - 1) * .000001
resid = np.where(resid < 0, q * resid, (1-q) * resid)
resid = np.abs(resid)
#1/resid[:, np.newaxis]为更新权重W
xstar = exog / resid[:, np.newaxis]
diff = np.max(np.abs(beta - beta0))
history['params'].append(beta)
history['mse'].append(np.mean(resid*resid))
#检查是否收敛,若收敛则提前停止迭代
if (n_iter >= 300) and (n_iter % 100 == 0):
# check for convergence circle, should not happen
for ii in range(2, 10):
if np.all(beta == history['params'][-ii]):
cycle = True
warnings.warn("Convergence cycle detected", ConvergenceWarning)
break
if n_iter == max_iter:
warnings.warn("Maximum number of iterations (" + str(max_iter) +
") reached.", IterationLimitWarning)
#计算协方差矩阵
e = endog - np.dot(exog, beta)
# Greene (2008, p.407) writes that Stata 6 uses this bandwidth:
# h = 0.9 * np.std(e) / (nobs**0.2)
# Instead, we calculate bandwidth as in Stata 12
iqre = stats.scoreatpercentile(e, 75) - stats.scoreatpercentile(e, 25)
h = bandwidth(nobs, q)
h = min(np.std(endog),
iqre / 1.34) * (norm.ppf(q + h) - norm.ppf(q - h))
fhat0 = 1. / (nobs * h) * np.sum(kernel(e / h))
if vcov == 'robust':
d = np.where(e > 0, (q/fhat0)**2, ((1-q)/fhat0)**2)
xtxi = pinv(np.dot(exog.T, exog))
xtdx = np.dot(exog.T * d[np.newaxis, :], exog)
vcov = chain_dot(xtxi, xtdx, xtxi)
elif vcov == 'iid':
vcov = (1. / fhat0)**2 * q * (1 - q) * pinv(np.dot(exog.T, exog))
else:
raise Exception("vcov must be 'robust' or 'iid'")
#用系数估计值和协方差矩阵创建一个QuantResults对象,并输出结果
lfit = QuantRegResults(self, beta, normalized_cov_params=vcov)
lfit.q = q
lfit.iterations = n_iter
lfit.sparsity = 1. / fhat0
lfit.bandwidth = h
lfit.history = history
return RegressionResultsWrapper(lfit)
#核函数表达式
def _parzen(u):
z = np.where(np.abs(u) <= .5, 4./3 - 8. * u**2 + 8. * np.abs(u)**3,
8. * (1 - np.abs(u))**3 / 3.)
z[np.abs(u) > 1] = 0
return z
kernels = {}
kernels['biw'] = lambda u: 15. / 16 * (1 - u**2)**2 * np.where(np.abs(u) <= 1, 1, 0)
kernels['cos'] = lambda u: np.where(np.abs(u) <= .5, 1 + np.cos(2 * np.pi * u), 0)
kernels['epa'] = lambda u: 3. / 4 * (1-u**2) * np.where(np.abs(u) <= 1, 1, 0)
kernels['gau'] = lambda u: norm.pdf(u)
kernels['par'] = _parzen
#kernels['bet'] = lambda u: np.where(np.abs(u) <= 1, .75 * (1 - u) * (1 + u), 0)
#kernels['log'] = lambda u: logistic.pdf(u) * (1 - logistic.pdf(u))
#kernels['tri'] = lambda u: np.where(np.abs(u) <= 1, 1 - np.abs(u), 0)
#kernels['trw'] = lambda u: 35. / 32 * (1 - u**2)**3 * np.where(np.abs(u) <= 1, 1, 0)
#kernels['uni'] = lambda u: 1. / 2 * np.where(np.abs(u) <= 1, 1, 0)
#窗宽计算
def hall_sheather(n, q, alpha=.05):
z = norm.ppf(q)
num = 1.5 * norm.pdf(z)**2.
den = 2. * z**2. + 1.
h = n**(-1. / 3) * norm.ppf(1. - alpha / 2.)**(2./3) * (num / den)**(1./3)
return h
def bofinger(n, q):
num = 9. / 2 * norm.pdf(2 * norm.ppf(q))**4
den = (2 * norm.ppf(q)**2 + 1)**2
h = n**(-1. / 5) * (num / den)**(1. / 5)
return h
def chamberlain(n, q, alpha=.05):
return norm.ppf(1 - alpha / 2) * np.sqrt(q*(1 - q) / n)
3.2 QuantRegResults类
这里我只给出计算拟合优度的代码。
class QuantRegResults(RegressionResults):
'''Results instance for the QuantReg model'''
@cache_readonly
def prsquared(self):
q = self.q
endog = self.model.endog
#e为残差
e = self.resid
e = np.where(e < 0, (1 - q) * e, q * e)
e = np.abs(e)
ered = endog - stats.scoreatpercentile(endog, q * 100)
ered = np.where(ered < 0, (1 - q) * ered, q * ered)
ered = np.abs(ered)
return 1 - np.sum(e) / np.sum(ered)
4.总结
上文我先给出了一个分位数回归的应用例子,进而叙述了分位数回归的原理,最后再分析了Python实现的源码。
分位数回归对比起OLS回归,虽然较为复杂,但它有三个主要优势:
能反映因变量分位数与自变量的关系,而不仅仅反映因变量均值与自变量的关系。
分位数回归对残差不作任何假设。
分位数回归受异常点的影响较小。
参考
-
网络分位数自回归-研究论文
2021-06-09 17:13:30在这里,我们提出了一个网络分位数自回归模型(NQAR),它表征了动态分位数行为。 我们的 NQAR 模型由一个方程组组成,其中我们将响应与其连接的节点和分位数自回归过程中的节点特定特征相关联。 我们展示了 NQAR ... -
大数据-算法-含指标项半参数回归模型的分位数回归与变量选择.pdf
2022-04-16 21:34:33大数据-算法-含指标项半参数回归模型的分位数回归与变量选择.pdf -
大数据-算法-CD生产函数参数估计的分位数回归方法研究.pdf
2022-04-15 02:20:59大数据-算法-CD生产函数参数估计的分位数回归方法研究.pdf -
用R语言进行分位数回归
2018-12-04 21:22:00非线性分位数回归这里的非线性函数为Frank copula函数。 (六)非线性分位数回归 这里的非线性函数为Frank copula函数。 ## Demo of nonlinear quantile regression model based on ... -
分位数回归(quantile regression)R实现
2021-11-28 00:37:28分位数回归已经获得了巨大的发展,不仅可以进行简单的横截面数据的估计,而且还可以进行panel数据模型估计、干预效应模型估计、计数模型估计、因变量是区间值的logistic模型估计、工具变量估计等。 -
分位数回归(Quantile Regression)
2019-07-09 22:25:16在介绍分位数回归之前,先重新说一下回归分析,我们之前介绍了线性回归、多项式回归、核回归等等,基本上,都是假定一个函数,然后让函数尽可能拟合训练数据,确定函数的未知参数。尽可能拟合训练数据,一般是通过... -
如何使用MATLAB进行分位数回归?
2021-04-18 05:10:58function [p,stats]=quantreg(x,y,tau,order,Nboot)% Quantile Regression%% USAGE: [p,stats]=quantreg(x,y,tau[,order,nboot]);%% INPUTS:% x,y: data that is fitted. (x and y should be columns)% Not... -
基于分位数回归的剪切波速变化规律
2020-06-17 02:27:19本文收集了邯郸市区40个场地实测的剪切波速值,经过统计整理,采用分位数回归法对粉土、粉质粘土剪切波速随深度的变化规律进行分析,建立了分位数回归模型,并计算了回归参数,得出分位数回归曲线方程。结果表明,粉土的... -
拓端tecdat|R语言实现贝叶斯分位数回归、lasso和自适应lasso贝叶斯分位数回归分析
2021-06-07 18:09:00摘要 贝叶斯回归分位数在最近的文献中受到广泛关注,本文实现了贝叶斯系数估计和回归分位数(RQ)中的变量选择,带有lasso和自适应...自引入以来,分位数回归一直是理论界非常关注的话题,也在许多研究领域得到了. -
分位数回归 Quantile Regression,python 代码
2020-12-07 11:24:52偶尔在机器学习的论文中了解到了分位数回归,发现这个方法应用也满广的。 一般的回归方法是最小二乘法,即最小化误差的平方和: min∑(yi−y^i)2\min\quad \sum(y_i-\hat{y}_i)^2min∑(yi−y^i)2 其中,yiy_... -
python中的分位数回归(初探)
2021-11-08 16:04:17分位数回归 参考文献 Python statsmodels 介绍 - 树懒学堂 (shulanxt.com) Quantile Regression - IBM Documentation https://www.cnblogs.com/TMesh/p/11737368.html 传统的线性回归模型 其的求解方式是一个最小... -
分位数回归简介
2019-06-01 15:04:40分位数回归简介 同步于音尘杂记;Buracag的博客 最近在做一个比较有意思(难搞…)的项目。大致介绍一下相关背景:根据历史的一个工作情况(历史表现,也就是有多少人做了多少工作量),以及未来的一个预估工作量(预测值)... -
分位数回归--基于R
2019-10-16 17:21:39分位数回归 分位数回归是估计一组回归变量X与被解释变量Y的分位数之间线性关系的建模方法。...分位数回归估计量的计算也是基于一种非对称形式的绝对值残差最小化。 当我们使用0.9分位数回归,重新... -
多元线性模型的分位数回归
2021-04-11 10:26:42分位数回归学习笔记一、为什么要使用分位数回归?二、分位数回归基本模型三、分位数回归估计--单纯形法1.损失函数2.目标函数3.算法推导4.实际案例分析与python代码 一、为什么要使用分位数回归? ... -
分位数回归(Stata)
2020-01-08 20:53:30基于分位数回归的成都空气质量指数的数据分析 空气质量指数计算公式为: (1)线性回归模型得到的是一种条件均值,并未考虑到因变量总体上的分布特征,在需要了解因变量位置(分位数)上的信息时,线性回归就... -
论文研究-基于参数化分位回归模型的非寿险准备金评估.pdf
2019-09-20 20:56:53其次,根据模型参数的极大似然估计结果,借助分位数函数的表达式,计算了不同分位数水平下的准备金预测值;最后,利用极大似然估计的渐近性质,通过Delta方法给出了准备金预测值的误差.基于一组增量赔款数据的实证... -
分位数回归-Quantile regression
2018-12-16 12:09:21文章目录一、分位数回归概念二、相关推导2.1 分位数概念2.2 离差绝对值LAD2.3 分位数回归2.4 效果以及理解三、模型检验四、求解方法 一、分位数回归概念 分位数回归是估计一组回归变量X与被解释变量Y的分位数之间... -
GitHub - lei940324/Quantile: 介绍分位数回归,包括分位数Granger因果检验、QVAR及脉冲响应函数
2020-12-06 14:51:08分位数 VAR 模型估计:自回归分布滞后模型脉冲响应函数计算各分位点脉冲图绘制代码实现原理使用pyqt5生成 GUI 界面使用statsmodels进行分位数回归使用pandas将结果保存在 excel 文件Display主窗口界面主要包括:工具... -
分位数回归的实现方法
2020-08-06 17:04:01目录分位数回归简介实现方法参考文献 分位数回归简介 简介参照可参照参考文献【】 实现方法 MATLAB: quantreg R package:quantreg [外链图片转存失败,源站可能有防盗图片保存下来直1]Dhttps://px1dujblog.c-dnimg.... -
如何理解分位数回归风险价值 (VaR) 模型?
2020-12-06 14:50:58风险价值(下称VaR)的计算方法主要有历史模拟法(非参数法)、分析方法、蒙特-卡罗模拟法三类。不同的计算方法、计算参数下所得的VaR都是不同的。若某机构宣称其产品的VaR较低即投资风险较低,投资者还需在投前明确其...