减少大型分类变量的级别数

Reduce number of levels for large categorical variables

是否有一些现成的库或包用于 python 或 R 以减少大型分类因子的水平数量?

我想实现类似于 的结果,但编码为最常见的前 k 个因子和 "other"。

这里是 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"

这是一种使用 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 

R 包 forcatsfct_lump() 用于此目的。

library(forcats)
fct_lump(f, n)

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

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

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