Q 方法求稳健标准差——理论和 Python实现

Posted zhuo木鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Q 方法求稳健标准差——理论和 Python实现相关的知识,希望对你有一定的参考价值。


本文的参考文献为: ISO 13528 中的 C.5.2 条款。

设样本为: x 1 , x 2 , ⋯   , x n x_1, x_2, \\cdots, x_n x1,x2,,xn n n n 为样本容量。

Qn 方法估计标准差

理论

Qn 算法的步骤为:

  1. 求取样本间两两的绝对差值:
    d i j = ∣ x i − x j ∣    对每个 i = 1 , 2 , ⋯   , n d_{ij} = |x_i - x_j| \\text{ ~ 对每个} i=1,2,\\cdots, n dij=xixj   对每个i=1,2,,n
    从而产生 n ( n − 1 ) / 2 n(n-1)/2 n(n1)/2KaTeX parse error: Expected '}', got 'EOF' at end of input: d_{ij
  2. 求解修正系数 b p b_p bp 为:
    b p = 1 r p + 1 b_p = \\frac{1}{r_p+1} bp=rp+11
    其中 r p r_p rp 为:
    r p = { 1 n [ 1 , 6019 + 1 n ( − 2 , 128 − 5 , 172 n ) ] n  是奇数 1 n [ 3 , 6756 + 1 n ( 1 , 965 + 1 n ( 6 , 987 − 77 n ) ) ] n  是偶数 r_{p}=\\left\\{\\begin{array}{c} \\frac{1}{n}\\left[1,6019+\\frac{1}{n}\\left(-2,128-\\frac{5,172}{n}\\right)\\right] & n \\text { 是奇数} \\\\ \\frac{1}{n}\\left[3,6756+\\frac{1}{n}\\left(1,965+\\frac{1}{n}\\left(6,987-\\frac{77}{n}\\right)\\right)\\right] & n \\text { 是偶数} \\end{array}\\right. rp={n1[1,6019+n1(2,128n5,172)]n1[3,6756+n1(1,965+n1(6,987n77))]n 是奇数n 是偶数
  3. 于是 Qn 为:
    Q n = 2.2219 × d { k } b p Q_n = 2.2219 \\times d_{\\{k\\}} b_p Qn=2.2219×d{k}bp
    其中 d { k } d_{\\{k\\}} d{k} 是按照升序排序后的第 k 个值,而 k 的取值为 k = ( h 2 ) ≈ ( n 2 ) / 4 k=\\left(\\begin{array}{c} h \\\\ 2 \\end{array}\\right) \\approx\\left(\\begin{array}{l} n \\\\ 2 \\end{array}\\right) / 4 k=(h2)(n2)/4 ,其中 h = ⌊ n / 2 ⌋ + 1 h=\\lfloor n / 2\\rfloor+1 h=n/2+1, ⌊ n / 2 ⌋ \\lfloor n / 2\\rfloor n/2 为取整函数,取 ≤ n / 2 \\leq n/2 n/2 的最大整数 1

Python 代码

from scipy.stats import norm
import numpy as np
import pandas as pd
def return_factor(n):
    '''
    产生校正因子 bp

    Parameters
    ----------
    n : int
        样本的个数.

    Returns
    -------
    float
        校正因子 bp.

    '''
    
    correction_factor = {2:0.9937, 3:0.9937, 4:0.5132, 5:0.8840, 6:0.6122, \\
                         7:0.8588, 8:0.6699, 9:0.8734, 10:0.7201, 11:0.8891,\\
                        12:0.7574}
    n = int(n)
    # 若 n 小于 12
    if n <= 12:
        return correction_factor[n]
    # 若 n 大于 12
    if n%2:
        # n 是奇数
        rp = 1/n*(1.6019+1/n*(-2.128-5.172/n))
    else:
        # n 是偶数
        rp = 1/n*(3.6756+1/n*(1.965+1/n*(6.987-77/n)))
        
    bp = 1/(rp+1)
    return bp


def perform_Qn_estimate(x):
    '''
    计算 Qn,算法和应用条件见 C.5.1

    Parameters
    ----------
    x : Series, np.array
        样本数据.

    Returns
    -------
    Qn : float
        稳健标准差的 Qn 估计.

    '''
    if isinstance(x, pd.Series):
        x = x.astype('float').values
    
    d_arr = []
    # 样本的个数
    n = len(x)
    # 若数据只有一个
    if n == 1:
        print('数据太少只有 1 个,无法使用 Qn')
        return 0 
    
    for i in range(n-1):
        for j in range(i+1, n):
            d = np.abs(x[i]-x[j])
            d_arr.append(d)
    # 求 dij
    d_arr = np.array(d_arr)
    # 排序
    d_arr.sort()
    
    if n%2:
        h = (n-1)/2
    else:
        h = n/2
    
    k = h*(h-1)/2
    # Python 的 index 从 0 开始
    k = k - 1
    k = int(k)
    # 校正因子 bp
    bp = return_factor(n)
  
    Qn = 2.2219*d_arr[k]*bp

    return Qn

Q 方法估计标准差

理论

Q 方法的求解理论步骤如下:

  1. 求取样本间绝对差值的分布函数:
    H ( x ) = 2 n ( n − 1 ) × ∑ 1 ≤ i < j ≤ n I { ∣ x i − x j ∣ ≤ x } H(x) = \\frac{2}{n(n-1)} \\times \\sum_{1\\leq i< j \\leq n} I\\{|x_i-x_j| \\leq x\\} H(x)=n(n1)2×1i<jnI{xixjx}
    其中 I { ∣ x i − x j ∣ ≤ x } I\\{|x_i-x_j|\\leq x\\} I{xixjx} 为指示函数,即
    I { ∣ x i − x j

    以上是关于Q 方法求稳健标准差——理论和 Python实现的主要内容,如果未能解决你的问题,请参考以下文章

    Trimmed 稳健均值估计与 中位数-中位数配对偏差法估计标准差——理论与 Python 实现

    Trimmed 稳健均值估计与 中位数-中位数配对偏差法估计标准差——理论与 Python 实现

    算法 A 求稳健平均值和稳健标准差

    算法 A 求稳健平均值和稳健标准差

    Hampel 估计稳健均值——理论和Python实现

    简单稳健估计法——原理与 Python 实现