格拉布斯(Grubbs)准则法

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

格拉布斯(Grubbs)准则法就是剔除数据集中偏离较远的数据,可以减少异常值对总体数据的影响。

#include 
#include 
#include 
#include 
#include 

using namespace std;

// 格拉布斯表
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;
        }
    }
}

你可能感兴趣的:(C++,格拉布斯)