【问题标题】:Reduce number of levels for large categorical variables减少大型分类变量的级别数
【发布时间】:2016-08-21 16:26:41
【问题描述】:

是否有一些现成的用于 python 或 R 的库或包来减少大型分类因素的级别数?

我想实现与R: "Binning" categorical variables 类似的目标,但将其编码为最常见的 top-k 因素和“其他”。

【问题讨论】:

  • 您的意思是将所有“不经常”级别替换为“其他”?
  • 是的,这是另一种表达方式,因为否则在使用这些高级分类变量中的几个时,我的数据矩阵会在单热编码的情况下爆炸。
  • 查看link

标签: python r encoding categorical-data binning


【解决方案1】:

R 包forcatsfct_lump() 用于此目的。

library(forcats)
fct_lump(f, n)

其中f 是因子,n 是要保留的最常见级别的数量。其余的被重新编码为Other

【讨论】:

    【解决方案2】:

    这是R 中使用data.table 的示例,但如果没有data.table 也应该很容易。

    # Load data.table
    require(data.table)
    
    # Some data
    set.seed(1)
    dt <- data.table(type = factor(sample(c("A", "B", "C"), 10e3, replace = T)),
                     weight = rnorm(n = 10e3, mean = 70, sd = 20))
    
    # Decide the minimum frequency a level needs...
    min.freq <- 3350
    
    # Levels that don't meet minumum frequency (using data.table)
    fail.min.f <- dt[, .N, type][N < min.freq, type]
    
    # Call all these level "Other"
    levels(dt$type)[fail.min.f] <- "Other"
    

    【讨论】:

    【解决方案3】:

    我不认为你想这样做。将许多级别分组为一组可能会使该功能的预测性降低。您要做的是根据相似性度量将所有将进入 Other 的级别放入一个集群中。其中一些可能会与您的前 K 级别聚集在一起,而另一些可能会聚集在一起以提供最佳性能。

    我遇到了类似的问题,最后我自己回答了here。对于我的相似性度量,我使用了随机森林回归中的邻近矩阵,该矩阵适用于除该特征之外的所有特征。我的解决方案的不同之处在于,我最常见的一些 top-K 可能会聚集在一起,因为我使用 k-mediods 进行聚类。您可能希望更改集群算法,以便您的媒体是您选择的前 K 个。

    【讨论】:

    • 有趣的方法。根据我同时了解到的情况,我认为对比编码stats.idre.ucla.edu/r/library/… 更合适。
    • 我认为对比编码只允许将分类输入到模型中。它只是将具有 k 个级别的 1 个特征转换为具有 2 个级别的 k-1 个特征。我只使用了虚拟编码,我错过了什么吗?
    • 二进制虚拟编码也是如此。但正如链接的网站所示,还有更多的可能性。一些方法,例如让我们称之为一个百分比编码将计算组/级别明智的百分比或其他一些函数,以将每个级别转换为从数据中测量的数值。这并不一定会导致更多列,如虚拟编码。
    • 好的,知道了。因此,它更像是一种近似级别之间的顺序和距离的方法。谢谢
    • 请查看nipy.bic.berkeley.edu/nightly/statsmodels/doc/html/… with > 事实上,虚拟编码在技术上并不是对比编码。这是因为虚拟变量加一并且在功能上不独立于模型的截距。另一方面,具有 k 个水平的分类变量的一组对比是因子水平的一组 k-1 个功能独立的线性组合
    【解决方案4】:

    这是一种使用base R 的方法:

    set.seed(123)
    d <- data.frame(x = sample(LETTERS[1:5], 1e5, prob = c(.4, .3, .2, .05, .05), replace = TRUE))
    
    recat <- function(x, new_cat, threshold) {
        x <- as.character(x)
        xt <- prop.table(table(x))
        factor(ifelse(x %in% names(xt)[xt >= threshold], x, new_cat))
    }
    
    d$new_cat <- recat(d$x, "O", 0.1)
    table(d$new_cat)
    #     A     B     C     O 
    # 40132 29955 19974  9939 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2015-10-07
      • 2021-09-28
      • 1970-01-01
      相关资源
      最近更新 更多