识别用于计算虚拟变量的原始变量

机器算法验证 r 分类数据
2022-04-03 14:38:53

我有一个数据框,其中许多定量变量已被重新编码为虚拟变量。

这是使用 R 的可复制示例:

age <- round(runif(100, 15, 40), 0)

as.dummy <- function(variable, min, max){
  sapply(variable, function(x) 
    if((!is.null(min) && x> min | is.null(min)) & ((!is.null(max) && x <= max) | is.null(max) ) )
      1
    else
      0
  )
}

age2 <- as.dummy(age, NULL, 20)
age3 <- as.dummy(age, 20, 25)
age4 <- as.dummy(age, 25, 30)
age5 <- as.dummy(age, 30, NULL)
tab <- data.frame(age, age2, age3, age4, age5)

有没有办法检测到 age2...5 是从变量 age 构造的?我希望能够检测到这些虚拟变量并将它们从数据框中删除。

在这里,我给出了编码为 0/1 的变量的示例,但它也可以编码为“是/否”或其他任何内容。

3个回答

这个答案表明对变量之间的关系进行图形探索是有价值的,并说明了一种有用的方法。然后,它提供了一个简单的解决方案,可以快速自动识别可能由给定分类变量表示的所有可能变量。


您可以通过在数据框中绘制年龄类别和所有数值变量的散点图矩阵来以图形方式进行探索。如果有很多变量,请按年龄汇总每个变量,并检查它们是否属于非重叠区间。

这里有一些示例数据用于说明。分组变量是V1,但我们假设我们不知道。

#
# Create data for testing.
#
n.obs <- 100
n.vars <- 4
X <- as.data.frame(matrix(round(runif(n.obs*n.vars, 15, 40), 0), n.obs))
#
# Create the dummary variable.
#
cutpoints <- c(-Inf, 20, 25, 30, Inf)
Age <- data.frame(group=cut(X$V1, cutpoints))

这个散点图矩阵清楚地表明变量V1对应于 中的年龄组group,因为它是group行或列中由散点图清楚划分的唯一变量:

colors <- rainbow(length(cutpoints), alpha=0.6)
names(colors) <- unique(Age$group)
pairs(cbind(X, Age), pch=21, bg=colors[Age$group])

散点图矩阵

我建议在任何情况下都使用这种方法,因为如果没有找到与变量匹配的age变量(如下所示),您可以通过此图快速识别几乎匹配的任何变量。这对于取证活动很有用,例如识别数据表中的不一致。

R按年龄汇总的实现用于tapply将数据按年龄分组并by计算其范围。如果这些不重叠(按 排序by),则您有一个与年龄对应的候选人。

#
# Identify all columns of X that might match Age.
# The result is a logical vector indicating which fields of X match.
#
candidates <- sapply(names(X), function(f) {
  groups <- tapply(X[[f]], Age)
  boundaries <- unlist(by(X[f], groups, range))
  identical(order(boundaries), 1:length(boundaries))
})

message(paste0("Possible variables are (", paste(names(X)[candidates],
                collapse=","), ")."))

输出是

可能的变量是 (V1)。

尽管此示例使用了通常存储在数据库中的形式的数据(即,作为分类变量),但当数据框采用问题中给出的格式时,它不会改变工作Age:唯一的行Age用于分组。

如果您可以从候选预测器中完美地重建假人,那么假人和预测器携带相同的信息。如果假人对预测变量的间隔进行编码(离散化连续预测变量的最常见方法,这是一个坏主意,正如在 CV 上经常讨论的那样,但这不是重点),那么您应该能够使用预测变量的多项逻辑回归

library(nnet)
# encode the dummies into a single factor variable:
tab$age.level <- as.factor(apply(tab[,-1],1,function(xx)min(which(xx==1))))
model <- multinom(age.level~age,tab)
predict(model)
table(predict(model),tab$age.level)

     1  2  3  4
  1 12  0  0  0
  2  0 22  0  0
  3  0  0 25  0
  4  0  0  0 41

我们得到一个完美的混淆矩阵。这对我来说已经足够有说服力了。

要检测 age2...5 是由同一个变量构造的,您可以检查这些虚拟变量的总和是否等于 1 :

all(age2+age3+age4+age5==1)

但我不知道是否有办法检查它们是否专门来自变量年龄,它可能是数据框中的任何其他变量。