乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      分層實驗原理

       醫(yī)學數據科學 2019-03-25
      1. 背景

      想要同一時間做N個實驗?

      想要同一份流量不同實驗之間不干擾?

      想要每個實驗都能得到100%流量?

      這里寫圖片描述 
      那么你就需要分層實驗。

      1.1 什么是分層實驗

      分層實驗概念:每個獨立實驗為一層,層與層之間流量是正交的。 
      簡單來講,就是一份流量穿越每層實驗時,都會再次隨機打散,且隨機效果離散。

      所有分層實驗的奠基石–Goolge論文

      《Overlapping Experiment Infrastructure More, Better, Faster Experimentation》

      下面將以一個簡單例子來解釋分層實驗核心原理,如果要了解全貌,可以看一下上面論文

      首先來看一下MD5的作為hash的特點,本文以最簡單得MD5算法來介紹分層實驗。(但一定要知道,實際應用場景復雜,需要我們設計更復雜的hash算法)

      1.2 MD5 特點 
      壓縮性:任意長度的數據,算出的MD5值長度都是固定的。

      容易計算:從原數據計算出MD5值很容易。

      抗修改性:對原數據進行任何改動,哪怕只修改1個字節(jié),所得到的MD5值都有很大區(qū)別。(重要理論依據!)

      弱抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。

      強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD5值,是非常困難的。

      正是由于上面的特性,MD5也經常作為文件是否被篡改的校驗方式。 
      所以, 
      理論上,如果我們采用MD5計算hash值,對每個cookie 加上某固定字符串(離散因子),求余的結果,就會與不加產生很大區(qū)別。加上離散因子后,當數據樣本夠大的時候,基于概率來看,所有cookie的分桶就會被再次隨機化。 
      下面我們將通過實際程序來驗證。

      1. 實戰(zhàn)講解

      2.1 我們的程序介紹 
      使用java SecureRandom模擬cookie的獲取(隨機化cookie,模擬真實場景)

      hash算法選用上文介紹的MD5。實驗分兩種:對cookie不做任何處理;對cookie采用增加離散因子離散化

      一共三層實驗(也就是3個實驗),我們會觀察第一層2號桶流量在第2層的分配,以及第2層2號桶流量在第3層的分配

      如果cookie加入離散因子后,一份流量經過三個實驗,按照如下圖比例每層平均打散,則證明實驗流量正交 
      這里寫圖片描述 
      從上圖可以看出,即使第1層的2號桶的實驗結果比其他幾個桶效果好很多,由于流量被離散化,這些效果被均勻分配到第2層。(第3層及后面層類同),這樣雖然實驗效果被帶到了下一層,但是每個桶都得到了相同的影響,對于層內的桶與桶的對比來說,是沒有影響的。而我們分析實驗數據,恰恰只會針對同一實驗內部的基準桶和實驗桶。

      =>與原來實驗方式區(qū)別?

      傳統方式,我們采用將100%流量分成不同的桶,假設有A,B兩個人做實驗,為了讓他們互不影響,只能約定0-3號桶給A做實驗,4-10號桶給B做實驗的方式,這樣做實驗,每個人拿到的只是總流量的一部分。

      上面基于MD5分層的例子告訴我們,分層實驗可以實現實驗與實驗之間“互不影響”,這樣我們就可以把100%流量給A做實驗,同時這100%流量也給B做實驗。(這里的A,B舉例來說,一個請求,頁面做了改版(實驗A)、處理邏輯中調用了算法,而算法也做了調整(實驗B)),如果采用不采用分層方式,強行將100%流量穿過A,B,那么最終看實驗報表時,我們無法區(qū)分,是由于改版導致轉化率提高,還是算法調整的好,導致轉化率提高。

      2.2 代碼 
      import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.ArrayList;import java.util.List;/** 
      * @author 九德 
      */public class MultiLayerExperiment { 
      private static String byteArrayToHex(byte[] byteArray) { 
      char[] hexDigits = {‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’}; 
      char[] resultCharArray = new char[byteArray.length * 2]; 
      int index = 0; 
      for (byte b : byteArray) { 
      resultCharArray[index++] = hexDigits[b >>> 4 & 0xf]; 
      resultCharArray[index++] = hexDigits[b & 0xf]; 

      return new String(resultCharArray); 

      private static long splitBucket(MessageDigest md5,long val,String shuffle){ 
      String key = String.valueOf(val) +((shuffle==null)?”“:shuffle); 
      byte[] ret = md5.digest(key.getBytes()); 
      String s = byteArrayToHex(ret) ; 
      long hash =Long.parseUnsignedLong(s.substring(s.length()-16,s.length()-1),16); 
      if(hash < 0){ 
      hash = hash * (-1); 

      return hash ; 

      private static void exp(SecureRandom sr,MessageDigest md5, 
      final int LevelOneBucketNumm,/第一層實驗桶數
      final int LevelTwoBucketNumm,/第二層實驗桶數
      final int LevelThreeBucketNumm,/第三層實驗桶數
      final int AllFlows,/所有流量數
      String shuffleLevel1,/第一層實驗離散因子
      String shuffleLevel2,/第二層實驗離散因子
      String shuffleLevel3/第三層實驗離散因子
      ){

          System.out.println("==第1層實驗 start!==");
          int[] bucketlevel1 = new int[LevelOneBucketNumm];
          for (int i=0; i<LevelOneBucketNumm; i++) {
              bucketlevel1[i] = 0;
          }
          List<Integer> level1bucket2 = new ArrayList<Integer>();
          for(int i=0; i<AllFlows; i++)
          {
              int cookie = sr.nextInt();
              long hashValue = splitBucket(md5, cookie, shuffleLevel1);
              int bucket =(int) (hashValue % LevelOneBucketNumm);
              if(bucket == 2){
                  /*將2號桶的流量記錄下來*/
                  level1bucket2.add(cookie);
              }
              bucketlevel1[bucket]++;
          }
          for(int i=0; i<LevelOneBucketNumm; i++){
              System.out.println("1層" + i + "桶:" + bucketlevel1[i]);
          }
          System.out.println("==第1層實驗 end!==");
      
          System.out.println("==第1層2號桶流量到達第2層實驗 start!==");
          int[] bucketlevel2 = new int[LevelTwoBucketNumm];
          for (int i=0; i<LevelTwoBucketNumm; ++i) {
              bucketlevel2[i] = 0;
          }
          List<Integer> level2bucket2 = new ArrayList<Integer>();
          for(int cookie : level1bucket2) {
              long hashValue = splitBucket(md5, cookie, shuffleLevel2);
              int bucket =(int) (hashValue % LevelTwoBucketNumm);
              if(bucket == 2){
                  /*將第2層2號桶的流量記錄下來*/
                  level2bucket2.add(cookie);
              }
              bucketlevel2[bucket]++;
          }
          for(int i=0; i<LevelTwoBucketNumm; i++){
              System.out.println("2層" + i + "桶:" + bucketlevel2[i]);
          }
          System.out.println("==第1層2號桶流量到達第2層實驗 end!==");
      
          System.out.println("==第2層2號桶流量到達第3層實驗 start!==");
          int[] bucketlevel3 = new int[LevelThreeBucketNumm];
          for (int i=0; i<LevelThreeBucketNumm; ++i) {
              bucketlevel3[i] = 0;
          }
          for(int cookie : level2bucket2) {
              long hashValue = splitBucket(md5, cookie, shuffleLevel3);
              int bucket =(int) (hashValue % LevelThreeBucketNumm);
      
              bucketlevel3[bucket]++;
          }
          for(int i=0; i<LevelThreeBucketNumm; i++){
              System.out.println("3層" + i + "桶:" + bucketlevel3[i]);
          }
          System.out.println("==第2層2號桶流量到達第3層實驗 end!==");
      
      }
      public static void main(String[] args) throws NoSuchAlgorithmException {
          SecureRandom sr =  SecureRandom.getInstance("SHA1PRNG");/*用來生成隨機數*/
          MessageDigest md5 =  MessageDigest.getInstance("MD5");/*用來生成MD5值*/
          /*1. 不對cookie做處理,一個cookie在每層實驗分到的桶是一致的*/
          exp(sr,md5,5,5,5,1000000,null,null,null);
          System.out.println("=======================");
          /*2. 每層加一個離散因子,這里只是簡單的a,b,c,就可以將多層了流量打散*/
          exp(sr,md5,5,5,5,1000000,"a","b","c");
      }
      • 1

      • 2

      • 3

      • 4

      • 5

      • 6

      • 7

      • 8

      • 9

      • 10

      • 11

      • 12

      • 13

      • 14

      • 15

      • 16

      • 17

      • 18

      • 19

      • 20

      • 21

      • 22

      • 23

      • 24

      • 25

      • 26

      • 27

      • 28

      • 29

      • 30

      • 31

      • 32

      • 33

      • 34

      • 35

      • 36

      • 37

      • 38

      • 39

      • 40

      • 41

      • 42

      • 43

      • 44

      • 45

      • 46

      • 47

      • 48

      • 49

      • 50

      • 51

      • 52

      • 53

      • 54

      • 55

      • 56

      • 57

      • 58

      • 59

      • 60

      • 61

      • 62

      • 63

      • 64

      • 65

      • 66

      • 67

      • 68

      }

      2.3 結果分析(重點) 
      2.3.1 不對cookie處理,每層實驗的分桶號一樣 
      因為hash%5中的hash保持不變,無論哪層,所以流量一直處于2號桶。

      ==第1層實驗 start!==

      1層0桶:199698

      1層1桶:199874

      1層2桶:199989

      1層3桶:200711

      1層4桶:199728

      ==第1層實驗 end!==

      ==第1層2號桶流量到達第2層實驗 start!==

      2層0桶:0

      2層1桶:0

      2層2桶:199989

      2層3桶:0

      2層4桶:0

      ===第1層2號桶流量到達第2層實驗 end!==

      ===第2層2號桶流量到達第3層實驗 start!==

      3層0桶:0

      3層1桶:0

      3層2桶:199989

      3層3桶:0

      3層4桶:0

      ===第2層2號桶流量到達第3層實驗 end!== 
      2.3.2. 對cookie做離散處理后,每層流量均勻分配 
      如下所示,

      流量到達第一層時,流量被均勻分配

      第2層實驗的2號桶流量到達第3層時,流量均勻分配到第2層的5個桶。

      第2層實驗的2號桶流量到達第3層時,流量均勻分配到第3層的5個桶。

      ==第1層實驗 start!==

      1層0桶:199951

      1層1桶:199536

      1層2桶:200127

      1層3桶:200938

      1層4桶:199448

      ==第1層實驗 end!==

      ==第1層2號桶流量到達第2層實驗 start!==

      2層0桶:40122

      2層1桶:40080

      2層2桶:39881

      2層3桶:40096

      2層4桶:39948

      ===第1層2號桶流量到達第2層實驗 end!==

      ===第2層2號桶流量到達第3層實驗 start!==

      3層0桶:8043

      3層1桶:7971

      3層2桶:7823

      3層3桶:7956

      3層4桶:8088

      ===第2層2號桶流量到達第3層實驗 end!==

      2.4 結論 
      我們觀測的第2層和第3層流量均來源于第一層的2號桶。 
      所以得出結論,第一層的流量在第2層、第3層均得到重新的離散分配。

      1. 總結 
        隨著個性化和算法不斷引入我們的應用,同一時間做多個實驗需求越來越多,更多人開始使用分層實驗

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多