NearZeroVar在R中是什么意思?

6

我有一个相当庞大的数据集,我想排除方差较低的列,所以我想使用“NearZeroVar”短语。但是,我确实有些困难理解freqCut和uniqueCut的作用以及它们如何相互影响。我已经阅读了R中的说明,但这对我并没有什么帮助。 如果有人能够向我解释一下,我将非常感谢!

2个回答

4
我假设你在谈论的是`mixOmics`包中的函数,该函数参考了`caret`包中的类似函数。
该函数的想法是识别预测变量(矩阵列)中最常数值接近不变(具有“接近零方差”)的变量,例如几乎全部为0且只有很少的非零值; 这些预测变量是无趣的。
他们举了一个无趣的预测变量的例子,其中有1000个值,其中999个为0,1个为1。 为了定义您所说的“接近零方差”,作者使用了两个过滤器:
1)最常见值(在本例中为0)与次常见值(1)之间频率的比率(`freqRatio`) 2)唯一数据点占总数据点数的百分比(`percentUnique`)
在上面的例子中,频率比率为999,唯一值百分比为0.0001,两者都满足函数使用的默认值。
您可以想象这样的数据,其中有少量离散值,例如500个0和500个1。您可能希望将其保留为有用的预测变量,并且`percentUnique`会非常低(满足此过滤标准),但`freqRatio`太低,无法标记该预测变量。 另一方面,您可能会有500个0和500个不同的非零值,这些可能具有有用的预测特性,并且它们由高`freqRatio`和高`percentUnique`(也没有被标记)来表征。
这两个参数使您可以在绘制仍然被视为有用预测变量的线中提供一些灵活性。
根据您的数据,您还可以使用`matrixStats::colVars`(或`matrixStats::rowVars`,具体取决于您的数据结构)获取单个预测变量方差的分布,然后基于此定义一个截止点。当您绘制方差密度分布时,您可能会看到一个好的截止点,例如在双峰分布中,或者只需选择您要用作截止点的方差百分位数。

4

如果一个变量变化很小或变化不大,它就像一个常数,对于预测是没有用的。这将具有接近零的方差,因此该函数得名。

这两个参数互不影响,它们存在是为了处理导致接近零方差变量的常见情况。列需要同时不满足这两个标准才会被排除。

让我们使用一个示例:

mat = cbind(1,rep(c(1,2),c(8,1)),rep(1:3,3),1:9)
mat
      [,1] [,2] [,3] [,4]
 [1,]    1    1    1    1
 [2,]    1    1    2    2
 [3,]    1    1    3    3
 [4,]    1    1    1    4
 [5,]    1    1    2    5
 [6,]    1    1    3    6
 [7,]    1    1    1    7
 [8,]    1    1    2    8
 [9,]    1    2    3    9

如果我们使用默认设置,其中95/5用于最常见的到第二个和唯一值,你会发现只有第一列被删除:
nearZeroVar(mat)
[1] 1

让我们看看第二列,最常见的到第二常见的是8/1,它有2个独特的值,使得它为2/9 = 0.22。因此,要将其过滤掉,您需要更改这两个设置:

nearZeroVar(mat,freqCut=7/1,uniqueCut=30)
[1] 1 2

最后,您最好不要过滤掉第3或第4列,所以当我们设置某些无意义的内容时,将过滤掉第四列:
nearZeroVar(mat,freqCut=0.1,uniqueCut=50)
[1] 1 2 3

1
谢谢,这很有帮助!但是我仍然不明白为什么在第二个例子中将UniqueCut设置为30。当你有两个唯一值时,为什么不将其设置为3呢?在我的数据框中,有一个列new <- c(1,1,3700,1,1,1,1,1,1,2600,1,1,3000,1,1,1,1,1,1,1,1,1)。现在设置NearZeroVar(df, freqCut = 18/4, uniqueCut = 15),据我所知,这意味着如果有超过18个值相等且您的唯一值少于2个(2/22 = 0.091),则应将该列留出。我错在哪里了? - Jana
好的,针对您的例子,freqCut变量是counts = sort(table(new),decreasing=TRUE); counts[1]/counts[2]这将给出19,因此18/4已经足够了。唯一的切割是总数中独特值的数量,即length(counts)/sum(counts)这将给出0.181。所以您需要类似于0.2的东西。 - StupidWolf
nearZeroVar(data.frame(new),freqCut = 18,uniqueCut = 20) 请执行上述代码。 - StupidWolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接