Python解释数学系列——分位数Quantile

跳转到我的博客

1. 分位数计算案例与Python代码

案例1

Ex1: Given a data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36],求Q1, Q2, Q3, IQR
Solving:
步骤:
1. 排序,从小到大排列data,data = [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49]
2. 计算分位数的位置
3. 给出分位数

分位数计算法一

pos = (n+1)*p,n为数据的总个数,p为0-1之间的值
Q1的pos = (11 + 1)*0.25 = 3 (p=0.25) Q1=15
Q2的pos = (11 + 1)*0.5 = 6 (p=0.5) Q2=40
Q3的pos = (11 + 1)*0.75 = 9 (p=0.75) Q3=43
IQR = Q3 - Q1 = 28

import math
def quantile_p(data, p):
    pos = (len(data) + 1)*p
    #pos = 1 + (len(data)-1)*p
    pos_integer = int(math.modf(pos)[1])
    pos_decimal = pos - pos_integer
    Q = data[pos_integer - 1] + (data[pos_integer] - data[pos_integer - 1])*pos_decimal
    return Q

data = [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49]
Q1 = quantile_p(data, 0.25)
print("Q1:", Q1)
Q2 = quantile_p(data, 0.5)
print("Q2:", Q2)
Q3 = quantile_p(data, 0.75)
print("Q3:", Q3)

分位数计算法二

pos = 1+ (n-1)*p,n为数据的总个数,p为0-1之间的值
Q1的pos = 1 + (11 - 1)*0.25 = 3.5 (p=0.25) Q1=25.5
Q2的pos = 1 + (11 - 1)*0.5 = 6 (p=0.5) Q2=40
Q3的pos = 1 + (11 - 1)*0.75 = 8.5 (p=0.75) Q3=42.5

import math
def quantile_p(data, p):
    pos = 1 + (len(data)-1)*p
    pos_integer = int(math.modf(pos)[1])
    pos_decimal = pos - pos_integer
    Q = data[pos_integer - 1] + (data[pos_integer] - data[pos_integer - 1])*pos_decimal
    return Q
data = [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49]
Q1 = quantile_p(data, 0.25)
print("Q1:", Q1)
Q2 = quantile_p(data, 0.5)
print("Q2:", Q2)
Q3 = quantile_p(data, 0.75)
print("Q3:", Q3)

案例2

给定数据集 data = [7, 15, 36, 39, 40, 41],求Q1,Q2,Q3

分位数计算法一

import math
def quantile_p(data, p):
    data.sort()
    pos = (len(data) + 1)*p
    pos_integer = int(math.modf(pos)[1])
    pos_decimal = pos - pos_integer
    Q = data[pos_integer - 1] + (data[pos_integer] - data[pos_integer - 1])*pos_decimal
    return Q

data = [7, 15, 36, 39, 40, 41]
Q1 = quantile_p(data, 0.25)
print("Q1:", Q1)
Q2 = quantile_p(data, 0.5)
print("Q2:", Q2)
Q3 = quantile_p(data, 0.75)
print("Q3:", Q3)

计算结果:
Q1 = 7 +(15-7)×(1.75 - 1)= 13
Q2 = 36 +(39-36)×(3.5 - 3)= 37.5
Q3 = 40 +(41-40)×(5.25 - 5)= 40.25

分位数计算法二

结果:
Q1: 20.25
Q2: 37.5
Q3: 39.75

2. 分位数解释

四分位数
概念:把给定的乱序数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
第1四分位数 (Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字。
第2四分位数 (Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字。
第3四分位数 (Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。
四分位距(InterQuartile Range, IQR)= 第3四分位数与第1四分位数的差距

确定p分位数位置的两种方法
position = (n+1)*p
position = 1 + (n-1)*p

3. 分位数在pandas中的解释

在python中计算分位数位置的方案采用position=1+(n-1)*p

案例1

import pandas as pd
import numpy as np
df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]), columns=['a', 'b'])
print("数据原始格式:")
print(df)
print("计算p=0.1时,a列和b列的分位数")
print(df.quantile(.1))

程序计算结果:

序号ab
011
1210
23100
34100

计算p=0.1时,a列和b列的分位数
a 1.3
b 3.7
Name: 0.1, dtype: float64

手算计算结果:
计算a列
pos = 1 + (4 - 1)*0.1 = 1.3
fraction = 0.3
ret = 1 + (2 - 1) * 0.3 = 1.3
计算b列
pos = 1.3
ret = 1 + (10 - 1)* 0.3 = 3.7

案例二

利用pandas库计算data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36]的分位数。

import pandas as pd
import numpy as np
dt = pd.Series(np.array([6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36])
print("数据格式:")
print(dt)
print('Q1:', df.quantile(.25))
print('Q2:', df.quantile(.5))
print('Q3:', df.quantile(.75))

计算结果
Q1: 25.5
Q2: 40.0
Q3: 42.5

4. 概括总结

自定义分位数python代码程序

import math
def quantile_p(data, p, method=1):
    data.sort()
    if method == 2:
        pos = 1 + (len(data)-1)*p
    else:
        pos = (len(data) + 1)*p
    pos_integer = int(math.modf(pos)[1])
    pos_decimal = pos - pos_integer
    Q = data[pos_integer - 1] + (data[pos_integer] - data[pos_integer - 1])*pos_decimal
    Q1 = quantile_p(data, 0.25)
    Q2 = quantile_p(data, 0.5)
    Q3 = quantile_p(data, 0.75)
    IQR = Q3 - Q1
    return Q1, Q2, Q3, IQR

pandas中的分位数程序

直接调用.quantile(p)方法,就可以计算出分位数,采用method=2方法。

参考文献:

1. 分位数概念
2. pandas中的quantile

转载于:https://www.cnblogs.com/brightyuxl/p/9815780.html

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分位数回归是一种回归分析方法,可以用于探究自变量对因变量不同分位数的影响。在C++中,可以通过面向对象编程的方式来实现分位数回归模型。下面是一个简单的实现及案例。 1. 定义类 首先,我们需要定义一个类来表示分位数回归模型。这个类中应该包括以下成员变量和成员函数: - 成员变量:自变量和因变量的向量,以及一个表示分位数的 double 类型变量。 - 成员函数:读取数据、拟合模型、预测、计算残差等。 下面是这个类的定义: ``` #include <vector> class QuantileRegression { public: QuantileRegression(double tau) : tau(tau) {} void readData(const std::vector<double>& x, const std::vector<double>& y); void fitModel(); double predict(double x); std::vector<double> getResiduals(); private: std::vector<double> x; std::vector<double> y; double tau; std::vector<double> residuals; double slope; double intercept; void computeResiduals(); }; ``` 2. 实现成员函数 接下来,我们需要实现这个类中的成员函数。首先是读取数据的函数: ``` void QuantileRegression::readData(const std::vector<double>& x, const std::vector<double>& y) { this->x = x; this->y = y; } ``` 然后是拟合模型的函数。这里我们使用梯度下降算法来求解最小二乘回归问题,以便得到斜率和截距。在每一步迭代中,我们需要计算残差和梯度,以更新参数: ``` void QuantileRegression::fitModel() { int n = x.size(); double learning_rate = 0.1; int num_iterations = 1000; slope = 0.0; intercept = 0.0; for (int i = 0; i < num_iterations; i++) { computeResiduals(); double sum_resid = 0.0; double sum_xresid = 0.0; for (int j = 0; j < n; j++) { if (residuals[j] >= 0) { sum_resid += (1 - tau) * residuals[j]; sum_xresid += (1 - tau) * residuals[j] * x[j]; } else { sum_resid += tau * residuals[j]; sum_xresid += tau * residuals[j] * x[j]; } } double grad_slope = sum_xresid / n; double grad_intercept = sum_resid / n; slope -= learning_rate * grad_slope; intercept -= learning_rate * grad_intercept; } } ``` 接下来是预测函数。根据拟合出来的斜率和截距来计算预测值: ``` double QuantileRegression::predict(double x) { return slope * x + intercept; } ``` 最后是计算残差的函数。残差的公式为 y - (slope * x + intercept): ``` void QuantileRegression::computeResiduals() { int n = x.size(); residuals.resize(n); for (int i = 0; i < n; i++) { residuals[i] = y[i] - (slope * x[i] + intercept); } } ``` 3. 编写测试代码 最后,我们需要编写测试代码来验证分位数回归模型的实现是否正确。下面是一个简单的测试案例: ``` #include <iostream> #include "quantile_regression.h" int main() { std::vector<double> x = {1, 2, 3, 4, 5}; std::vector<double> y = {1, 3, 2, 5, 4}; QuantileRegression model(0.5); model.readData(x, y); model.fitModel(); std::cout << "Slope: " << model.getSlope() << std::endl; std::cout << "Intercept: " << model.getIntercept() << std::endl; std::cout << "Residuals:" << std::endl; std::vector<double> residuals = model.getResiduals(); for (double r : residuals) { std::cout << r << std::endl; } std::cout << "Predictions:" << std::endl; std::cout << "x=6: " << model.predict(6) << std::endl; std::cout << "x=7: " << model.predict(7) << std::endl; return 0; } ``` 在这个测试案例中,我们使用了一个包含5个样本的数据集来拟合一个分位数为0.5的回归模型。我们首先调用了 `fitModel()` 函数来拟合模型,并打印出了得到的斜率和截距。然后我们调用了 `getResiduals()` 函数来计算残差,并打印出来。最后,我们使用 `predict()` 函数来预测新的数据点的因变量值,并输出结果。 总结 分位数回归是一种有用的回归分析方法,可以用于探究自变量对因变量不同分位数的影响。在C++中,我们可以通过面向对象编程来实现分位数回归模型,并且可以使用梯度下降算法来求解最小二乘回归问题。本文提供了一个简单的实现及案例,读者可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值