R: 使用0.05和0.95分位数清除数据框中每列的异常值

3

我是一个R语言初学者。在将样本放入随机森林之前,我希望进行一些异常值清理和整体缩放,使数据范围在0到1之间。

g<-c(1000,60,50,60,50,40,50,60,70,60,40,70,50,60,50,70,10)

如果我简单地从0到1进行缩放,结果将是:

> round((g - min(g))/abs(max(g) - min(g)),1)

 [1] 1.0 0.1 0.0 0.1 0.0 0.0 0.0 0.1 0.1 0.1 0.0 0.1 0.0 0.1 0.0 0.1 0.0

因此,我的想法是用比0.95分位数小的下一个值替换每个列中大于0.95分位数的值,对于0.05分位数同理。

因此,预缩放结果将如下:

g<-c(**70**,60,50,60,50,40,50,60,70,60,40,70,50,60,50,70,**40**)

并进行了扩展:

> round((g - min(g))/abs(max(g) - min(g)),1)

 [1] 1.0 0.7 0.3 0.7 0.3 0.0 0.3 0.7 1.0 0.7 0.0 1.0 0.3 0.7 0.3 1.0 0.0

我需要对整个数据框应用这个公式,因此在R中实现的函数应该是这样的:

> apply(c, 2, function(x) x[x`<quantile(x, 0.95)]`<-max(x[x, ... max without the quantile(x, 0.95))

有人能帮忙吗?

顺便说一句:如果有一种直接完成此任务的函数,请告诉我。我已经尝试过 cutcut2。因为断点不唯一,cut 失败了;cut2 可以工作,但只返回字符串值或平均值,而我需要一个从 0 到 1 的数字向量。

供试用:

a<-c(100,6,5,6,5,4,5,6,7,6,4,7,5,6,5,7,1)

b<-c(1000,60,50,60,50,40,50,60,70,60,40,70,50,60,50,70,10)

c<-cbind(a,b)

c<-as.data.frame(c)

感谢您的帮助和关注,

Rainer


在CRAN上有几个包可能适合您的需求:outliersmvoutliersheavyextremevalues...只需前往贡献包并找到一个合适的即可。 - aL3xa
谢谢您的建议,我会查看这些软件包!敬礼,Rainer - Rainer
2个回答

11

请不要这样做。这不是处理异常值的好策略 - 特别是因为你的数据中很少有10%是异常值!


你好,Hadley, 示例数据框只是一个例子。尽管如此:您为什么认为这种策略不好,您更喜欢哪种更好的策略? - Rainer
嗯...你可以始终使用箱线图规则来筛选异常值。请注意,“筛选”而不是删除。根据John Tukey的说法,您应该预期数据中会有异常值,但几乎永远不应该将它们删除。请查看此帖子:http://goo.gl/Ywbo8 - aL3xa
@Rainer 异常值是模型相关的 - 现在丢弃极端数据点只是一种错误的做法 - 如果拟合了一个模型,那么大多数这些“异常值”可能只是在模型中给定协变量的条件分布的极端值?或者使用一种对异常值具有鲁棒性的方法。最后,如果将其投入RF中,如果您的数据具有合理的信号,则我怀疑它不会对所选的决策规则产生任何或很大的影响。简而言之,保留数据中的异常值,因为在RF中重新缩放是无关紧要的,因为它仅使用排名排序... - Gavin Simpson

3

我想不到在R语言中有这样的函数,但是你可以自己定义一个小函数:

foo <- function(x)
{
    quant <- quantile(x,c(0.05,0.95))
    x[x < quant[1]] <- min(x[x >= quant[1]])
    x[x > quant[2]] <- max(x[x <= quant[2]])
    return(round((x - min(x))/abs(max(x) - min(x)),1))
}

然后将此应用于数据框中的每个变量:

sapply(c,foo)
       a   b
 [1,] 1.0 1.0
 [2,] 0.7 0.7
 [3,] 0.3 0.3
 [4,] 0.7 0.7
 [5,] 0.3 0.3
 [6,] 0.0 0.0
 [7,] 0.3 0.3
 [8,] 0.7 0.7
 [9,] 1.0 1.0
[10,] 0.7 0.7
[11,] 0.0 0.0
[12,] 1.0 1.0
[13,] 0.3 0.3
[14,] 0.7 0.7
[15,] 0.3 0.3
[16,] 1.0 1.0
[17,] 0.0 0.0

编辑:这个答案的目的是解决编程问题。关于实际使用它,我完全同意Hadley的看法。


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