談談統計學正態分布閾值原理在數據分析工作中的運用


一、背景

0.0 神說,要有正態分布,於是就有了正態分布。

0.1 神看正態分布是好的,就讓隨機誤差都隨了正態分布。

0.2 正態分布的奇妙之處,就是許多看似隨機事件竟然服從一個表達式就能表達的分布,如同上帝之手特意為之。

神覺得拋硬幣是好的,於是定義每個拋出硬幣正面記+1分,反面記-1分。創世紀從0分開始,神只拋1次硬幣,有2種可能:一半的概率+1分,一半的概率-1分。此時概率分布大概是這樣的:

 

神決定扔10個硬幣,此時概率分布如下:

 

如果畫圖來感受,數據分布大概如下:

如果是100個,甚至是無窮多個呢?平均分數分布情況大概是什么樣呢?畫個圖感受一下:

 

——《創世紀·數理統計·正態分布的前世今生》

 

開頭摘自統計學中非常經典的一本書籍,由此可見正態分布是非常經典和隨處可見的,為什么正態分布這么常見呢?因為通常情況下,一個事物的影響因素都是多個,好比每個人的學習成績,受到多個因素的影響,比如:

  • 本人的智商情況。
  • 上課聽講的認真程度,課前的預習程度,與老師的互動程度。
  • 課后是否及時復習,有沒有及時溫習知識點呢,有沒有做好作業鞏固。

每一天的因素,每天的行為,對於學生的成績不是產生正面因素就是負面因素,這些因素對於成績的影響不是正面就是負面的,反復累計加持就像上圖的拋硬幣一樣,讓成績最后呈現出正態分布。數據呈現正態分布其實背后是有中心極限定理原理支持,根據中心極限定理,如果事物受到多種因素的影響,不管每個因素單獨本身是什么分布,他們加總后結果的平均值就是正態分布。

二、引用

正是因為日常分析工作中數據呈現是正態分布的,處於兩個極端的值往往是異常的,與我們挑選異常值天然契合。在業務方尋求一種自動監控方案的過程中,我們選擇了該方案。根據數據分析工作中,結合統計學的數據閾值分布原理,通過自動划分數據級別范圍,確定異常值,如下圖箱線圖,箱線圖是一個能夠通過5個數字來描述數據的分布的標准方式,這5個數字包括:最小值,第一分位,中位數,第三分位數,最大值,箱線圖能夠明確的展示離群點的信息,同時能夠讓我們了解數據是否對稱,數據如何分組、數據的峰度。

 

箱線圖是一個能夠通過5個數字來描述數據的分布的標准方式,這5個數字包括:最小值,第一分位,中位數,第三分位數,最大值,箱線圖能夠明確的展示離群點的信息,同時能夠讓我們了解數據是否對稱,數據如何分組、數據的峰度,對於某些分布/數據集,會發現除了集中趨勢(中位數,均值和眾數)的度量之外,還需要更多信息。

(圖片來源於網絡)

需要有關數據變異性或分散性的信息。箱形圖是一張圖表,它很好地指示數據中的值如何分布,盡管與直方圖或密度圖相比,箱線圖似乎是原始的,但它們具有占用較少空間的優勢,這在比較許多組或數據集之間的分布時非常有用。——適用於大批量的數據波動監控。

(圖片來源於網絡)

 箱線圖是一種基於五位數摘要(“最小”,第一四分位數(Q1),中位數,第三四分位數(Q3)和“最大”)顯示數據分布的標准化方法。

  1. 中位數(Q2 / 50th百分位數):數據集的中間值;
  2. 第一個四分位數(Q1 / 25百分位數):最小數(不是“最小值”)和數據集的中位數之間的中間數;
  3. 第三四分位數(Q3 / 75th Percentile):數據集的中位數和最大值之間的中間值(不是“最大值”);
  4. 四分位間距(IQR):第25至第75個百分點的距離;
  5. 晶須(藍色顯示);
  6. 離群值(顯示為綠色圓圈);
  7. “最大”:Q3 + 1.5 * IQR;
  8. “最低”:Q1 -1.5 * IQR。

(圖片來源於網絡)

上圖是近似正態分布的箱線圖與正態分布的概率密度函數(pdf)的比較, 兩側0.35%的數據就能夠被視為異常數據。

回到這次的監控方案,由中位數向兩邊擴散,划分一級二級三級四級五級數據,傳入連續時間段內指標的同環比,根據同環比分布的區間確定四個異常類型:異常上漲(同環比分布同時大於等於正三級)、異常(同環比分布在一正一負大於等於三級的范圍)、異常下降(同環比分布低於等於負三級)、無異常(同環比分布低於三級的范圍)。

三、落地

實現三部曲

1. 代碼實現

/*

*數據分析API服務

*/

public class DataAnalysis{

    /*

*波動分析

*input:json,分析源數據(樣例)

{
"org_data": [
          { "date":"2020-02-01",  "data":"10123230" },  日期類型、long類型
          { "date":"2020-02-02", "data":"9752755" },
         { "date":"2020-02-03",  "data":"12123230" },
         .......
   ]
}
*output:json,分析結果

{
  "type": 1,  --調用正常返回1,異常返回0
  "message":"", --異常原因
"date": 2020-02-14,--輸入數據中按日期升序排列的最后一組的日期
"data": 6346231,--輸入數據中按日期升序排列的最后一組的數據值
"rate1": -0.3,--同比值
"rate2": -0.6,--環比值
"level1": 4,--同比等級,5個類型:1、2、3、4、5
"level2": 3,--環比等級,5個類型:1、2、3、4、5
"result":"異常下降",--四個類型:異常上漲、異常、異常下降、無異常
}
*/

    public String fluctuationAnalysis (String org_data){



        //第一步,校驗輸入數據

        if(checkOrgdata(org_data)) return {"result": 0, "message":""}



        //第二步,計算同環比

        computeOrgdata(org_data)



        //第三步,數據升序排序,獲取數組大小、最后數據中按日期升序排列的最后一組

        //以上面樣例為了,數組大小14,最后一組數據{ "date":"2020-02-14", "data":"6346231" ,同比:-0.3,環比:-0.6}

對同比、環比、(data暫不做)分別做如下處理

-------

        //第四步,按照數據升序排序及數據大小,將數據(不算上面找出的最后一組數據)平均分為4等份(這樣會在數組中插入三個樁),並計算出第一個樁和第三個樁的值,以上面為例子,原來數組大小14,去掉最后一個,13個

//判斷,給結論

(1) 如果同比等級> 2 and 環比等級 > 2 (表示一定有異常)

/*

*數據分析API服務

*/

public class DataAnalysis{

    /*

*波動分析

*input:json,分析源數據(樣例)

{
"org_data": [
          { "date":"2020-02-01",  "data":"10123230" },  日期類型、long類型
          { "date":"2020-02-02", "data":"9752755" },
         { "date":"2020-02-03",  "data":"12123230" },
         .......
   ]
}
*output:json,分析結果

{
  "type": 1,  --調用正常返回1,異常返回0
  "message":"", --異常原因
"date": 2020-02-14,--輸入數據中按日期升序排列的最后一組的日期
"data": 6346231,--輸入數據中按日期升序排列的最后一組的數據值
"rate1": -0.3,--同比值
"rate2": -0.6,--環比值
"level1": 4,--同比等級,5個類型:1、2、3、4、5
"level2": 3,--環比等級,5個類型:1、2、3、4、5
"result":"異常下降",--四個類型:異常上漲、異常、異常下降、無異常
}
*/

    public String fluctuationAnalysis (String org_data){



        //第一步,校驗輸入數據

        if(checkOrgdata(org_data)) return {"result": 0, "message":""}



        //第二步,計算同環比

        computeOrgdata(org_data)



        //第三步,數據升序排序,獲取數組大小、最后數據中按日期升序排列的最后一組

        //以上面樣例為了,數組大小14,最后一組數據{ "date":"2020-02-14", "data":"6346231" ,同比:-0.3,環比:-0.6}


對同比、環比、(data暫不做)分別做如下處理

-------
        //第四步,按照數據升序排序及數據大小,將數據(不算上面找出的最后一組數據)平均分為4等份(這樣會在數組中插入三個樁),並計算出第一個樁和第三個樁的值,以上面為例子,原來數組大小14,去掉最后一個,13個

//判斷,給結論

(1)   如果同比等級> 2 and 環比等級 > 2  (表示一定有異常)

And

case when 同比值<0 and 環比值<0 then '異常下降'

       when 同比值>0 and 環比值>0 then '異常上漲'

       else '異常'

end as res



return 
(2)其他,無異常波動 }
public bool checkOrgdata (String org_data){



        //檢驗數組中日期是否全部連續,數量至少要14天數據

        …

        if(日期不連續 || 數量小於14)

           return false;

        return ture;

}

public String computeOrgdata (String org_data){

// 計算輸入數據中,每一行的同環比
環比=(今日data/昨日data-1)*100%,

同比=(今日data/上周同日data-1)*100%

return

{
"org_data": [
          { "date":"2020-02-01",  "data":"10123230" ,同比:null,環比:null },
          { "date":"2020-02-02", "data":"9752755" ,同比:null,環比:0.9},
         { "date":"2020-02-03",  "data":"12123230" ,同比:null,環比:0.9},
          .......
   ]
}
}

對於輸入數據的幾個關鍵點:

(1)要求是連續的日期,並且至少14天的數據,建議100天的數據

(2)api中當同環比計算為null時,統一處理為0

(3)當傳入的數量大於90天,取最近90天作為樣本,當數量小於90天,拿所有上傳作為樣本

2. API封裝

(1)提供已封裝好的API服務為大家使用:

API使用:

傳入數據示例(json)

 {
        "org_data": [
          { "date":"2020-02-01",  "data":"10123230" ,同比:null,環比:null },
          { "date":"2020-02-02", "data":"9752755" ,同比:null,環比:0.9},
         { "date":"2020-02-03",  "data":"12123230" ,同比:null,環比:0.9},
         .....
      ]
    }

返回結果解釋:

{
       "type": 1,  --調用正常返回1,異常返回0
       "message":"", --異常原因
        "date": 2020-02-14,--輸入數據中按日期升序排列的最后一組的日期
        "data": 6346231,--輸入數據中按日期升序排列的最后一組的數據值
        "rate1": -0.3,--同比值
        "rate2": -0.6,--環比值
        "level1": 4,--同比等級,5個類型:1、2、3、4、5
        "level2": 3,--環比等級,5個類型:1、2、3、4、5
        "result":"異常下降",--四個類型:異常上漲、異常、異常下降、無異常
     }

注意問題點:

對於輸入數據的幾個關鍵點:

(1)要求是連續的日期,並且至少14天的數據,建議100天的數據

(2)api中當同環比計算為null時,統一處理為0

(3)當傳入的數量大於90天,取最近90天作為樣本,當數量小於90天,拿所有上傳作為樣本

3. JAR 包提供

大數據中心日常數據開發工作以HQL為主,我們將API服務封裝成JAR包,可直接適用於數倉開發使用。

四、運用場景

目前成功運用於大數據中心多個重點業務和平台,對其日常指標進行監控,以應用商店為例。

1、獲取da表數據到  da_appstore_core_data_di

2、監控數據統一處理  da_appstore_core_data_result_di

 

3、每條記錄調用上述UDF函數,輸出判定結果,異常值可對業務發送提醒,幫助排除業務風險

參考文獻

  1. 《創世紀·數理統計·正態分布的前世今生》
  2. 知乎朋友-小堯、jinzhao 關於正態分布閾值原理的部分闡述

作者:vivo 互聯網大數據團隊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM