格拉布斯(Grubbs)準則法

原理參考:https://wenku.baidu.com/view/90cc05a7c8d376eeafaa3151.html

格拉布斯(Grubbs)準則法就是剔除數據集中偏離較遠的數據,可以減少異常值對總體數據的影響。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>

// 格拉布斯表
double table[] = {0.0, 0.0, 0.0, 1.153,1.463,1.672,1.822,1.938,2.032,2.110,2.176,
        2.234,2.285,2.331,2.371,2.409,2.443,2.475,2.501,2.532,2.557,
        2.580,2.603,2.624,2.644,2.663,2.681,2.698,2.714,2.730,2.745,
        2.759,2.773,2.786,2.799,2.811,2.823,2.835,2.846,2.857,2.866,
        2.877,2.887,2.896,2.905,2.914,2.923,2.931,2.940,2.948,2.956,
        2.943,2.971,2.978,2.986,2.992,3.000,3.006,3.013,3.019,3.025,
        3.032,3.037,3.044,3.049,3.055,3.061,3.066,3.071,3.076,3.082,
        3.087,3.092,3.098,3.102,3.107,3.111,3.117,3.121,3.125,3.130,
        3.134,3.139,3.143,3.147,3.151,3.155,3.160,3.163,3.167,3.171,
        3.174,3.179,3.182,3.186,3.189,3.193,3.196,3.201,3.204,3.207};

// 結構體數據結構
struct data_sort
{
    double  data;       // 原始數據
    int     id;         // 數據對應ID,便於回查原始數據列表
};

// 排序法則,其中:< 升序    >降序
bool comparison(data_sort a,data_sort b)
{
 return a.data < b.data ;
}

/**
 * @brief My_Grubbs 格拉布斯剔除法
 * @param data      待處理數據
 * @return
 */
bool My_Grubbs(vector<data_sort> &data)
{
    sort(data.begin(), data.end(), comparison);
    // 計算平均值
    double data_sum = 0;
    for(int i=0; i<data.size(); i++)
    {
        data_sum += data.at(i).data;
    }
    double data_ave = data_sum/data.size(); // 平均值

    // 計算標準差
    data_sum = 0;
    for(int i=0; i<data.size(); i++)
    {
        data_sum += pow((data.at(i).data - data_ave), 2);
    }
    double data_s = sqrt(data_sum/(data.size() - 1));   // 標準差

    if(abs(data_ave - data.at(0).data) > abs(data.at(data.size()-1).data - data_ave))   // 當最小值與均值大於最大值與均值
    {
        if(abs(data.at(0).data - data_ave)/data_s > table[3])           // 滿足Gn大於Gp(n)時,爲異常值,剔除最小值
        {
            data.erase(data.begin());   // 剔除最小值
            My_Grubbs(data);            // 進行遞歸處理
        }
        else                            // 條件滿足,可以結束
        {
            return true;
        }
    }
    else if(abs(data_ave - data.at(0).data) < abs(data.at(data.size()-1).data - data_ave))  // 當最大值與均值大於最小值與均值
    {
        if(abs(data.at(data.size()-1).data - data_ave)/data_s > table[data.size()-1])   // 滿足Gn大於Gp(n)時,爲異常值,剔除最大值
        {
            data.erase(data.begin()+data.size()-1);     // 剔除最大值
            My_Grubbs(data);                            // 進行遞歸處理
        }
        else                                            // 條件滿足,可以結束
        {
            return true;
        }
    }
    else    // 當最大值與均值等於最小值與均值
    {
        if(abs(data.at(0).data - data_ave)/data_s > table[3])   // 滿足Gn大於Gp(n)時,爲異常值,剔除最大值和最小值
        {
            data.erase(data.begin());                       // 剔除最小值
            data.erase(data.begin() + data.size()-1);       // 剔除最大值
            My_Grubbs(data);                                // 進行遞歸處理
        }
        else                                                // 條件滿足,可以結束
        {
            return true;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章