基于R語言的卡方分箱

在做風(fēng)控策略分析時(shí)雄妥,我們經(jīng)常要對(duì)某個(gè)變量進(jìn)行離散化赵讯,查看不同階段的好壞用戶分布情況巡揍,好的離散化方法可以讓我們找到比較好的策略分界點(diǎn)镊辕。
本片文章主要講述卡方分箱

一油够、理論

基本思想:卡方分箱是依賴于 卡方檢驗(yàn)的分箱方法,在統(tǒng)計(jì)指標(biāo)上選擇卡方統(tǒng)計(jì)量(chi-Square)進(jìn)行判別征懈∈В卡方分箱的基本思想是判斷相鄰的兩個(gè)區(qū)間是否有分布差異,如果兩個(gè)相鄰的區(qū)間具有非常類似的分布卖哎,則這兩個(gè)區(qū)間可以合并鬼悠;否則,它們應(yīng)當(dāng)保持分開亏娜』牢眩基于卡方統(tǒng)計(jì)量的結(jié)果進(jìn)行自下而上的合并,直到滿足分箱的限制條件為止维贺。

卡方分箱的實(shí)現(xiàn)步驟:

1. 預(yù)先設(shè)定一個(gè)卡方的閾值或者分箱個(gè)數(shù)的閾值它掂。

在做分箱處理時(shí)可以使用兩種限制條件:

  • 分箱個(gè)數(shù):限制最終的分箱個(gè)數(shù)結(jié)果,每次將樣本中具有最小卡方值的區(qū)間與相鄰的最小卡方區(qū)間進(jìn)行合并溯泣,直到分箱個(gè)數(shù)達(dá)到限制條件為止虐秋。

  • 卡方閾值:根據(jù)自由度和顯著性水平得到對(duì)應(yīng)的卡方閾值,如果分箱的各區(qū)間最小卡方值小于卡方閾值垃沦,則繼續(xù)合并客给,直到最小卡方值超過設(shè)定閾值為止。

通過顯著性水平和自由度計(jì)算出這個(gè)閾值栏尚,然后數(shù)據(jù)的卡方值與這個(gè)閾值進(jìn)行比較起愈,如果卡方值大于閾值只恨,就可以推翻原假設(shè)(兩個(gè)相鄰區(qū)間的分布無差異);如果卡方值小于閾值,則不能推翻原假設(shè)(兩個(gè)相鄰區(qū)間的分布無差異),即可合并抬虽。

  • 顯著性水平官觅,當(dāng)置信度90%時(shí)顯著性水平為10%,ChiMerge算法推薦使用置信度為0.90阐污、0.95休涤、0.99。

  • 自由度笛辟,比分類數(shù)量小1功氨。例如:有3類,自由度為2。

類別和屬性獨(dú)立時(shí),有90%的可能性,計(jì)算得到的卡方值會(huì)小于4.6(在excel中用CHIINV(0.1,2)算出)手幢。大于閾值4.6的卡方值就說明屬性和類不是相互獨(dú)立的捷凄,不能合并。如果閾值選的大,區(qū)間合并就會(huì)進(jìn)行很多次,離散后的區(qū)間數(shù)量少围来、區(qū)間大跺涤。

2. 初始化:根據(jù)要離散化的數(shù)據(jù)對(duì)實(shí)例進(jìn)行排序,每個(gè)實(shí)例屬于一個(gè)區(qū)間

3. 合并區(qū)間:

  1. 計(jì)算每一對(duì)相鄰區(qū)間的卡方值

  2. 將卡方值最小的一對(duì)區(qū)間合并(合并需要符合以下兩個(gè)條件之一)

image.png

4.評(píng)估指標(biāo)

分完箱之后需要評(píng)估监透,常用的評(píng)估手段是計(jì)算出WOE和IV值桶错。對(duì)于WOE和IV值的含義,看 數(shù)據(jù)挖掘模型中的IV和WOE詳解

分箱的注意點(diǎn)

對(duì)于連續(xù)型變量胀蛮,

? 使用ChiMerge進(jìn)行分箱(默認(rèn)分成5個(gè)箱)

? 檢查分箱后的bad rate單調(diào)性院刁;倘若不滿足,需要進(jìn)行相鄰兩箱的合并粪狼,直到bad rate為止

? 上述過程是收斂的退腥,因?yàn)楫?dāng)箱數(shù)為2時(shí),bad rate自然單調(diào)

? 分箱必須覆蓋所有訓(xùn)練樣本外可能存在的值鸳玩!

? 原始值很多時(shí)阅虫,為了減小時(shí)間的開銷,通常選取較少(例如50個(gè))初始切分點(diǎn)不跟。但是要注意分布不均勻!

對(duì)于類別型變量米碰,

? 當(dāng)類別數(shù)較少時(shí)窝革,原則上不需要分箱

? 當(dāng)某個(gè)或者幾個(gè)類別的bad rate為0時(shí),需要和最小的非0 的bad rate的箱進(jìn)行合并

? 當(dāng)該變量可以完全區(qū)分目標(biāo)變量時(shí)吕座,需要認(rèn)真檢查該變量的合理性

要求分箱完之后:

(1)不超過5箱

(2)Bad Rate單調(diào)

(3)每箱同時(shí)包含好壞樣本

(4)特殊值如-1虐译,單獨(dú)成一箱

連續(xù)型變量可直接分箱

類別型變量:

(a)當(dāng)取值較多時(shí),先用bad rate編碼吴趴,再用連續(xù)型分箱的方式進(jìn)行分箱

(b)當(dāng)取值較少時(shí):

(b1)如果每種類別同時(shí)包含好壞樣本漆诽,無需分箱

(b2)如果有類別只包含好壞樣本的一種,需要合并

二、代碼

2.1 R包--discretization

discretization包厢拭,是一個(gè)用來做有監(jiān)督離散化的工具集兰英,主要用于卡方分箱算法,它提供了幾種常用的離散化工具函數(shù)供鸠,可以按照自上而下或自下而上畦贸,實(shí)施離散化算法。

項(xiàng)目主頁: https://cran.r-project.org/web/packages/discretization/

提供了幾個(gè)主要的離散化的工具函數(shù):

  • chiM楞捂,ChiM算法進(jìn)行離散化

  • chi2, Chi2算法進(jìn)行離散化薄坏,在chiM的基礎(chǔ)上進(jìn)行優(yōu)化

  • mdlp琐谤,最小描述長度原理(MDLP)進(jìn)行離散化

  • modChi2戴卜,改進(jìn)的Chi2方法離散數(shù)值屬性

  • disc.Topdown,自上而下的離散化

  • extendChi2叔壤,擴(kuò)展Chi2算法離散數(shù)值屬性

chiM算法進(jìn)行離散化(根據(jù)卡方閾值來設(shè)定合并停止條件)

ChiM()函數(shù)繁堡,使用ChiMerge算法基于卡方檢驗(yàn)進(jìn)行自下而上的合并涵但。通過卡方檢驗(yàn)判斷相鄰閾值的相對(duì)類頻率,是否有明顯不同帖蔓,或者它們是否足夠相似矮瘟,從而合并為一個(gè)區(qū)間。
chiM(data,alpha)函數(shù)解讀塑娇。
* 第一個(gè)參數(shù)data澈侠,是輸入數(shù)據(jù)集,要求最后一列是分類屬性埋酬。
* 第二個(gè)參數(shù)alpha哨啃,表示顯著性水平。
* 自由度写妥,通過數(shù)據(jù)計(jì)算獲得是2拳球,一共3個(gè)分類減去1。


image.png

2.2 自定義函數(shù)ChiMerge

#初始化劃分
SplitData <- function(df,col,numOfSplit,special_attribute=NULL){
  library(dplyr)
  #當(dāng)連續(xù)變量的初始取值集合太多時(shí)(>100),我們先對(duì)其進(jìn)行初步劃分
  #:param df: 按照col排序后的數(shù)據(jù)集
  #:param col: 待分箱的變量
  #:param numOfSplit: 切分的組別數(shù)
  #:param special_attribute: 在切分?jǐn)?shù)據(jù)集的時(shí)候珍特,某些特殊值需要排除在外
  #:return: 在原數(shù)據(jù)集上增加一列祝峻,把原始細(xì)粒度的col重新劃分成粗粒度的值,便于分箱中的合并處理
  df2 <- df
  if(length(special_attribute)>0){
    df2 <- filter(df,! col %in% special_attribute)
  }
  N <- dim(df2)[1] #行數(shù)
  n <- floor(N/numOfSplit) #每組樣本數(shù)
  splitPointIndex <- seq(1,numOfSplit-1,1)*n #分割點(diǎn)的下標(biāo)
  rawValues <- sort(df2[,col]) #對(duì)取值進(jìn)行升序排序
  splitPoint <- rep(0,length(rawValues))
  for(i in splitPointIndex){
    splitPoint[i] <- rawValues[i]  #分割點(diǎn)的取值
  }
  splitPoint <- sort(unique(splitPoint)) #對(duì)取值進(jìn)行升序排序
  if(splitPoint[1]==0){
    splitPoint<- splitPoint[-1]
  }
  return(splitPoint)
}

#計(jì)算每個(gè)值的好壞比率
BinBadRate <- function(df,col,target,grantRateIndicator=0){
  library(dplyr)
  #:param df:需要計(jì)算好壞比率的數(shù)據(jù)集
  #:param col:需要計(jì)算好壞比率的特征
  #:param target:好壞標(biāo)簽
  #:param grantRateIndicator:1返回總體的壞樣本率扎筒,0不返回
  #:return:每箱的壞樣本率以及總體的壞樣本率(當(dāng)grantRateIndicator=1時(shí))
  #total <- df %>% group_by(col) %>% summarise(total=n())
  #bad <- df %>% group_by(col) %>% summarise(bad=sum(target))
  total <- data.frame(table(df[,col]))
  names(total) <- c(col,'total')
  bad <- data.frame(tapply(df[,target],df[,col],FUN = sum))
  bad$bad <- row.names(bad)
  names(bad) <- c('bad',col)
  regroup <- left_join(total,bad,by=col)
  #regroup$bad_rate  <- bad/total
  regroup <- mutate(regroup,bad_rate = bad/total)
  dicts <- regroup[,'bad_rate'] #每箱對(duì)應(yīng)的壞樣本率組成的向量
  names(dicts) <- regroup[,col]
  if(grantRateIndicator==0){
    return(list(dicts,regroup))
  }else{
    N =sum(regroup[,'total'])
    B = sum(regroup[,'bad'])
    overallRate = B*1.0/N
    return(list(dicts,regroup,overallRate))
  }
}

#計(jì)算卡方值
Chi2 <- function(df,total_col,bad_col){
  library(dplyr)
  df2 <- df
  # 求出df中莱找,總體的壞樣本率和好樣本率
  badRate <- sum(df2[,bad_col])/sum(df2[,total_col])
  # 當(dāng)全部樣本只有好或者壞樣本時(shí),卡方值為0
  if(badRate %in% c(0,1)){
    return(0)
  }
  good=df2[,total_col]-df2[,bad_col]
  df2 <- cbind(df2,good)
  goodRate = sum(df2[,'good'])/ sum(df2[,total_col])
  # 期望壞(好)樣本個(gè)數(shù)=全部樣本個(gè)數(shù)*平均壞(好)樣本占比
  badExpected=df2[,total_col]*badRate
  goodExpected=df2[,total_col]*goodRate
  df2 <- cbind(df2,badExpected)
  df2 <- cbind(df2,goodExpected)
  badChi <- sum(((df2[,bad_col]-df2[,'badExpected'])^2)/df2[,'badExpected'])
  goodChi <- sum(((df2[,'good']-df2[,'goodExpected'])^2)/df2[,'goodExpected'])
  chi2 <- badChi+goodChi
  return(chi2)
}
AssignBin <- function(x,cutOffPoints,special_attribute=NULL){
  # :param x: 某個(gè)變量的某個(gè)取值
  # :param cutOffPoints:上述變量的分箱結(jié)果嗜桌,用切分點(diǎn)表示
  # :param special_attribute:不參與分箱的特殊取值
  # :return:分箱后的對(duì)應(yīng)的第幾個(gè)箱奥溺,從0開始
  # for example, if cutOffPoints = c(10,20,30), if x = 7, return Bin 0. If x = 35, return Bin 3
  
  
  numBin = length(cutOffPoints)+1+length(special_attribute)
  if(x %in% special_attribute){
    i <-  which(special_attribute==x)
    return(paste('Bin',0-i))
  }
  if(x<= cutOffPoints[1]){
    return('Bin 0')
  }else if(x>cutOffPoints[length(cutOffPoints)]){
    return(paste("Bin",numBin-1))
  }else{
    for(i in seq(1,numBin-1)){
      if(cutOffPoints[i] < x & x<= cutOffPoints[i+1]){
        return(paste('Bin',i))
      }
    }
  }
}
AssignGroup <- function(x,bin){
  # '
  #   :param x:某個(gè)變量的某個(gè)取值
  #   :param bin:上述變量的分箱結(jié)果
  #   :return:x在分箱結(jié)果下的映射
  #  
  N = length(bin)
  if(x<=min(bin)){
    return(min(bin))
  }else if(x>max(bin)){
    return(10e10)
  }else{
    for(i in 1:N-1){
      if(bin[i]<x && x<=bin[i+1]){
        return(bin[i+1])
      }
    }
  }
}

ChiMerge <- function(df,col,target,max_interval=5,special_attribute=NULL,minBinPcnt=0,numOfSplit=100){
  # '''
  #   通過指定最大分箱數(shù),使用卡方值分割連續(xù)變量
  #   :param df:包含目標(biāo)變量和分箱變量的數(shù)據(jù)框
  #   :param target:目標(biāo)變量骨宠,取值0或1
  #   :param col:需要分箱的變量
  #   :param max_interval:最大分箱數(shù)浮定,如果原始變量的取值個(gè)數(shù)低于該參數(shù)相满,不執(zhí)行這個(gè)函數(shù)
  #   :param special_attribute:不參與分箱的變量取值,注意:必須是向量形式
  #   :param minBinPcnt:最小箱的占比,默認(rèn)為0
  #   :param numOfSplit:當(dāng)連續(xù)變量的初始取值集合太多時(shí)(>100),我們先對(duì)其進(jìn)行初步劃分桦卒,切分的組別數(shù)
  #   :return :分箱結(jié)果
  #   '''
  library(dplyr)
  colLevels=sort(unique(df[,col])) #升序排序變量值
  N_distinct = length(colLevels) #不同取值的個(gè)數(shù)
  if(N_distinct<=max_interval){ #如果原始變量的取值個(gè)數(shù)低于max_interval,不執(zhí)行這個(gè)函數(shù)
    print(paste(col,'變量的取值個(gè)數(shù)低于設(shè)定的最大分箱數(shù)max_interval:',max_interval))
    return(colLevels[-length(colLevels)]) #去掉最后一個(gè)值
  }else{
    if(length(special_attribute)>=1){
      df1 <- filter(df,col %in% special_attribute)
      df2 <- filter(df,!col %in% special_attribute)
    }else{
      df2 <- df
    }
    
    N_distinct <- length(unique(df2[,col])) #該變量的不同取值個(gè)數(shù)
    
    
    #步驟一:通過col對(duì)數(shù)據(jù)集進(jìn)行分組立美,求出每組的總樣本數(shù)和壞樣本數(shù)
    if(N_distinct>numOfSplit){
      split_x <- SplitData(df2,col,numOfSplit)
      #temp <- cut(df2[,col],breaks = split_x,include.lowest = TRUE)
      temp <- apply(df2[col],1,AssignGroup,split_x)
      df2 <- cbind(df2,temp)
    }else{
      temp <- df2[,col]
      df2 <- cbind(df2,temp)
      
    }
    #總體bad rate將被用來計(jì)算expected bad count
    ha <- BinBadRate(df2,'temp',target)
    regroup <- ha[[2]]
    binBadRate<- ha[[1]]
    #首先,每個(gè)單獨(dú)的屬性值將被分為單獨(dú)的一組
    #對(duì)屬性值進(jìn)行排序闸盔,然后兩兩組別進(jìn)行合并
    colLevels<- sort(unique(df2[,'temp']))
    
    groupIntervals <- list()
    for(i in 1:length(colLevels)){
      groupIntervals[i] <-list(colLevels[i])
    }
    
    # #步驟二悯辙,建立循環(huán),不斷合并最優(yōu)的相鄰的兩個(gè)組別迎吵,直到:
    # #1.最終分裂出來的分箱數(shù)<=預(yù)設(shè)的最大分箱數(shù)
    # #2.每箱的占比不低于預(yù)設(shè)值(可選)
    # #3.每箱同時(shí)包含好壞樣本
    # #如果有特殊屬性躲撰,那么最終分裂出來的分箱數(shù)=預(yù)設(shè)的最大分箱數(shù)-特殊屬性的個(gè)數(shù)
    split_intervals= max_interval-length(special_attribute)

    while(length(groupIntervals)>=split_intervals){ #終止條件
      #每次循環(huán)時(shí),計(jì)算合并相鄰組別后的卡方值击费。具有最小卡方值值的合并方案拢蛋,是最優(yōu)方案
      chisqList <- rep(100000000,length(groupIntervals)-1)
      for(k in 1:(length(groupIntervals)-1)){
        temp_group <- c(groupIntervals[[k]],groupIntervals[[k+1]])
        df2b <- filter(regroup, temp %in% temp_group)
        chisq = Chi2(df2b,'total','bad')
        chisqList[k] <- chisq
      }
      best_combined <- order(chisqList)[1] #找到最小值的位置
      #合并
      groupIntervals[[best_combined]] = c(groupIntervals[[best_combined]],groupIntervals[[best_combined+1]])
      # after combining two intervals, we need to remove one of them
      groupIntervals[[best_combined+1]] <- NULL
      
    }
    
    for(i in 1:length(groupIntervals)){
      groupIntervals[[i]]<- sort(groupIntervals[[i]])
    }
    
    cutOffPoints <- rep(0,length(groupIntervals)-1)
    for(i in 1:(length(groupIntervals)-1)){
      cutOffPoints[i] <- max(groupIntervals[[i]])
    }
    
    # 檢查是否有箱沒有好或者壞樣本。如果有蔫巩,需要跟相鄰的箱進(jìn)行合并谆棱,直到每箱同時(shí)包含好壞樣本
    groupedvalues <-  apply(df2['temp'],1,AssignBin,cutOffPoints,special_attribute)
    temp_Bin<-groupedvalues
    df2 <- cbind(df2,temp_Bin)
    #返回(每箱壞樣本率列表,和包含“列名圆仔、壞樣本數(shù)垃瞧、總樣本數(shù)、壞樣本率的數(shù)據(jù)框”)
    middle <- BinBadRate(df2,'temp_Bin',target)
    binBadRate <- middle[[1]]
    regroup <- middle[[2]]
    minBadRate <- min(binBadRate)
    maxBadRate <- max(binBadRate)
while(minBadRate ==0 || maxBadRate == 1){
   # 找出全部為好/壞樣本的箱
   indexForBad01 <- filter(regroup,bad_rate %in% c(0,1))[,'temp_Bin']
   bin <- indexForBad01[1]
   return(bin)
   # 如果是最后一箱坪郭,則需要和上一個(gè)箱進(jìn)行合并个从,也就意味著分裂點(diǎn)cutOffPoints中的最后一個(gè)需要移除
   if(bin==max(regroup[,'temp_Bin'])){
     cutOffPoints <- cutOffPoints[1:length(cutOffPoints)-1]
   }else if(bin == min(regroup[,'temp_Bin'])){
     # 如果是第一箱,則需要和下一個(gè)箱進(jìn)行合并歪沃,也就意味著分裂點(diǎn)cutOffPoints中的第一個(gè)需要移除
     cutOffPoints[1] <- NULL
   }else{
     # 如果是中間的某一箱嗦锐,則需要和前后中的一個(gè)箱進(jìn)行合并,依據(jù)是較小的卡方值
     # 和前一箱進(jìn)行合并沪曙,并且計(jì)算卡方值
     currentIndex <- which(regroup[,'temp_Bin']==bin)
     prevIndex <- regroup[,'temp_Bin'][currentIndex - 1]
     df3 <- filter(df2,temp_Bin %in% c(prevIndex,bin))
     middle <- BinBadRate(df3, 'temp_Bin', target)
     binBadRate <- middle[[1]]
     df2b <- middle[[2]]
     chisq1 = Chi2(df2b, 'total', 'bad')
     # 和后一箱進(jìn)行合并奕污,并且計(jì)算卡方值
     laterIndex <- regroup[,'temp_Bin'][currentIndex + 1]
     df3b <- filter(df2,temp_Bin %in% c(prevIndex,bin))
     middle <- BinBadRate(df3b, 'temp_Bin', target)
     binBadRate <- middle[[1]]
     df2b <- middle[[2]]
     chisq2 = Chi2(df2b, 'total', 'bad')
     if(chisq1 < chisq2){
       cutOffPoints[currentIndex - 1] <- NULL
     }else{cutOffPoints[currentIndex] <- NULL}
   }
   # 完成合并之后,需要再次計(jì)算新的分箱準(zhǔn)則下液走,每箱是否同時(shí)包含好壞樣本
   groupedvalues <- apply(df2['temp'],1,AssignBin,cutOffPoints,special_attribute)
   temp_Bin = groupedvalues
   df2 <- cbind(df2,temp_Bin)
   middle <- BinBadRate(df2, 'temp_Bin', target)
   binBadRate <- middle[[1]]
   regroup <- middle[[2]]
   minBadRate <- min(binBadRate)
   maxBadRate <- maxmax(binBadRate)
}


if(minBinPcnt > 0){
   groupedvalues <- apply(df2['temp'],1,AssignBin,cutOffPoints,special_attribute)
   temp_Bin = groupedvalues
   df2 <- cbind(df2,temp_Bin)
   valueCounts <- data.frame(table(groupedvalues))
   names(valueCounts)[2] <- 'temp'
   pcnt=valueCounts[,'temp']/sum(valueCounts[,'temp'])
   valueCounts <- cbind(valueCounts,pcnt)
   valueCounts <- arrange(valueCounts,Var1)
   minPcnt = min(valueCounts[,'pcnt'])
   while(minPcnt < minBinPcnt & len(cutOffPoints) > 2){
     # 找出占比最小的箱
     indexForMinPcnt = filter(valueCounts,valueCounts[,'pcnt'] == minPcnt)[,'var1'][1]
     # 如果占比最小的箱是最后一箱碳默,則需要和上一個(gè)箱進(jìn)行合并,也就意味著分裂點(diǎn)cutOffPoints中的最后一個(gè)需要移除
     if(indexForMinPcnt==max(valueCounts[,'var1'])){
       cutOffPoints[length(cutOffPoints)] <- NULL
     }else if(indexForMinPcnt==min(valueCounts[,'var1'])){
       # 如果占比最小的箱是第一箱育灸,則需要和下一個(gè)箱進(jìn)行合并腻窒,也就意味著分裂點(diǎn)cutOffPoints中的第一個(gè)需要移除
       cutOffPoints[1] <- NULL
     }else{
       # 如果占比最小的箱是中間的某一箱,則需要和前后中的一個(gè)箱進(jìn)行合并磅崭,依據(jù)是較小的卡方值
       # 和前一箱進(jìn)行合并,并且計(jì)算卡方值
       currentIndex <- which(valueCounts[,'pcnt']==indexForMinPcnt)
       prevIndex <- valueCounts[,'var1'][currentIndex-1]
       df3 <- filter(df2,var1 %in% c(prevIndex, indexForMinPcnt))
       middle <- BinBadRate(df3, 'temp_Bin', target)
       binBadRate <- middle[[1]]
       df2b <- middle[[2]]
       chisq1 = Chi2(df2b, 'total', 'bad')
       # 和后一箱進(jìn)行合并瓦哎,并且計(jì)算卡方值
       laterIndex <- valueCounts[,'var1'][currentIndex-1]
       df3b <- filter(df2,temp_Bin %in% c(laterIndex, indexForMinPcnt))
       middle <- BinBadRate(df3b, 'temp_Bin', target)
       binBadRate <- middle[[1]]
       df2b <- middle[[2]]
       chisq2 = Chi2(df2b, 'total', 'bad')
       if(chisq1<chisq2){
         cutOffPoints[currentIndex - 1] <- NULL
       }else{cutOffPoints[currentIndex] <- NULL}
     }
     groupedvalues <- apply(df2['temp'],1,AssignBin,cutOffPoints,special_attribute)
     temp_Bin = groupedvalues
     df2 <- cbind(df2,temp_Bin)
     valueCounts <- data.frame(table(groupedvalues))
     names(valueCounts)[2] <- 'temp'
     pcnt=valueCounts[,'temp']/sum(valueCounts[,'temp'])
     valueCounts <- cbind(valueCounts,pcnt)
     valueCounts <- arrange(valueCounts,Var1)
     minPcnt = min(valueCounts[,'pcnt'])
   }
}
cutOffPoints = c(special_attribute , cutOffPoints)
return(cutOffPoints)
  }
  }
image.png

2. 3自定義并行化分箱函數(shù)

有時(shí)候數(shù)據(jù)量大的時(shí)候卡方分箱的計(jì)算大會(huì)導(dǎo)致運(yùn)行速度慢砸喻,所以我們可以合理利用我們電腦的多核


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柔逼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子割岛,更是在濱河造成了極大的恐慌愉适,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件癣漆,死亡現(xiàn)場(chǎng)離奇詭異维咸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惠爽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門癌蓖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人婚肆,你說我怎么就攤上這事租副。” “怎么了较性?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵用僧,是天一觀的道長。 經(jīng)常有香客問我赞咙,道長责循,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任攀操,我火速辦了婚禮院仿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崔赌。我一直安慰自己意蛀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布健芭。 她就那樣靜靜地躺著县钥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慈迈。 梳的紋絲不亂的頭發(fā)上若贮,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音痒留,去河邊找鬼谴麦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伸头,可吹牛的內(nèi)容都是我干的匾效。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼恤磷,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼面哼!你這毒婦竟也來了野宜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤魔策,失蹤者是張志新(化名)和其女友劉穎匈子,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闯袒,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虎敦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了政敢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片其徙。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖堕仔,靈堂內(nèi)的尸體忽然破棺而出擂橘,到底是詐尸還是另有隱情,我是刑警寧澤摩骨,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布通贞,位于F島的核電站,受9級(jí)特大地震影響恼五,放射性物質(zhì)發(fā)生泄漏昌罩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一灾馒、第九天 我趴在偏房一處隱蔽的房頂上張望茎用。 院中可真熱鬧,春花似錦睬罗、人聲如沸轨功。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽古涧。三九已至,卻和暖如春花盐,著一層夾襖步出監(jiān)牢的瞬間羡滑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工算芯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柒昏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓熙揍,卻偏偏與公主長得像职祷,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容