如何转换包含零的非负数据?


191

如果我偏向正数,我通常会记录日志。但是,对于包含零的高度偏斜的非负数据,我该怎么办?我已经看到使用了两种转换:

  • log(x+1)具有巧妙的功能,即0映射到0。
  • log(x+c)其中c被估计或设置为一些非常小的正值。

还有其他方法吗?是否有充分的理由选择一种方法而不是其他方法?



5
转换和提升stat.stackoverflow的绝佳方法!
罗宾吉拉德

是的,我同意@robingirard(由于Rob的博客文章,我现在才来到这里)!
Ellie Kesselman

另请参阅stats.stackexchange.com/questions/39042/…,了解针对左删节数据的应用程序(与当前问题完全一样,可以对它进行表征,直到位置发生变化)。
ub

2
在不首先说明转换目的的情况下询问如何转换似乎很奇怪。现在是什么状况?为什么需要进行转换?如果我们不知道你想达到什么样的,怎么能一个合理的建议什么?(显然,人们不可能指望转换为正态,因为存在(非零)精确零的概率意味着分布中的峰值为零,这种峰值不会被任何变换消除,它只能四处移动。)
Glen_b

Answers:


55

在我看来,最合适的转换选择取决于模型和上下文。

“ 0”点可能是由几种不同的原因引起的,每个原因都可能需要区别对待:

  • 截断(如Robin的示例):使用适当的模型(例如,混合物,生存模型等)
  • 数据丢失:归因数据/掉落观测值(如果适用)。
  • 自然零点(例如收入水平;失业者的收入为零):根据需要进行转换
  • 测量仪器的灵敏度:也许,向数据中添加少量?

我没有真正提供答案,因为我怀疑当您有零时,没有通用的“正确”变换。


6
我的问题的每一个答案都提供了有用的信息,我对它们全部进行了投票。但是我只能选择一个答案,而Srikant可以提供最佳的IMO概述。
罗伯·海恩德曼

2
还要注意,存在零膨胀模型(额外的零,并且您关心一些零:混合模型)和跨栏模型(零并且您在意非零:带有初始审查模型的两阶段模型)。
韦恩

82

没有人提到反双曲正弦变换。为了完整起见,我在这里添加它。

这是Box-Cox变换的替代方法,由 其中。对于任何值,零都映射为零。就像两参数BC转换一样,还有两个参数版本允许移动。Burbidge,Magee和Robb(1988)讨论了IHS转换,包括估计。θ > 0 θ θ

f(y,θ)=sinh1(θy)/θ=log[θy+(θ2y2+1)1/2]/θ,
θ>0θθ

IHS转换适用于在整个实线上定义的数据,包括负值和零。对于较大的值,其行为类似于对数变换,而不管的值(0除外)如何。极限情况为给出。θ θ 0 ˚F Ý θ ÿyθθ0f(y,θ)y

在我看来,IHS转型应该比现在更广为人知。


1
看起来是 / logistic转换的不错选择tanh
Firebug


3
那篇论文是关于反正弦变换的,而不是关于反双曲正弦的。
布赖恩

42

将变量用作回归中的独立因子时,一种有用的方法是用两个变量替换它:一个是二进制变量,指示它是否为零,另一个是原始变量的值或它的重新表达,例如其对数。Hosmer&Lemeshow在关于逻辑回归的书中对此技术进行了讨论(我敢肯定在其他地方)。原始变量正值的截断概率图可用于识别适当的重新表达。(有关示例,请参见https://stats.stackexchange.com/a/30749/919上的分析。)

当变量是线性模型中的因变量时,经过审查的回归(如Tobit)会很有用,从而避免了产生初始对数的需要。这种技术在计量经济学家中很常见。


1
将数据建模为零膨胀泊松是否是这种方法的特殊情况?
David LeBauer 2012年

4
@David,尽管看起来很相似,但事实并非如此,因为ZIP是变量而非自变量的模型。
ub

1
@whuber 在Hosmer&Lemeshow的关于逻辑回归的书中讨论了该技术。您是否有机会知道他们在哪一章讨论了该技术?我正在看他们的书,但似乎找不到正确的页面……
landroni 2015年

1
@landroni H&L是历历在目那时,所以我自信有东西在这本书中与此相关的话题。(我已经咨询过它以开发一些非常大的回归模型,并且必须以这种方式来处理许多自变量。)但是,我在这一点上也找不到参考。如果您正在寻找详细信息,我将在后续文章中对此技术进行撰写。站点搜索中显示的两个是stats.stackexchange.com/questions/6563stats.stackexchange.com/questions/4831
ub

1
@landroni是的,它们是等效的,就像任何二进制变量的所有数字编码都是等效的一样。选择您认为最方便解释的一种。
ub

37

带移位的对数变换是Box-Cox变换的特殊情况:

y(λ1,λ2)={(y+λ2)λ11λ1when λ10log(y+λ2)when λ1=0

这些是负值的扩展形式,但也适用于包含零的数据。Box and Cox(1964)提出了一种使用最大似然来找到的合适值的算法。这为您带来了最终的转变。 λ

选择Box-Cox转换的原因是开发它们是为了确保对线性模型的假设。有一些工作表明,即使您的数据无法转换为正态性,估计的仍会导致对称分布。λ

我不确定这对您的数据的处理效果如何,因为可能只是您提到的对数转换,但是可能值得估计所需的以查看是否改造是适当的。λλ=(0,1)λ

在R中,boxcox.fit包中的函数geoR将为您计算参数。


嗯,无法让乳胶“开始使用”来接受新行。:-/
ars

@ars我修复了eqns以使用开始情况。我希望我在此过程中不要弄错eqns。

1
@Rob:哦,对不起。Diggle的geoR是必经之路-但要lambda2=TRUE在的参数中指定boxcox.fit。(还更新了答案。)
ars

3
@ gd047:这里是一个很好的参考:elevatorlady.ca/doc/refcard/expressions.html
ARS

6
对于任何想知道此函数发生了什么的人,现在将其称为boxcoxfit
stragu 2012年

19

我假设零!=缺少数据,因为这是一个完全不同的问题。

在考虑如何在多元线性回归中处理零时,我倾向于考虑实际上有多少个零?

只有几个零

如果我在相当大的数据集中只有一个零,那么我倾向于:

  1. 移开点,取日志并拟合模型
  2. 给该点添加一个小,记录并拟合模型c

模型适合吗?参数值呢?如果模型对于删除点相当鲁棒,那么我将寻求添加快速而肮脏的方法。c

您可以简化此过程,并使用boxcox方法,并在ars的答案中进行介绍。

大量零

如果我的数据集包含大量零,那么这表明简单的线性回归并不是完成这项工作的最佳工具。相反,我会使用类似混合建模的方法(如Srikant和Robin所建议)。


15

如果您想要快速又脏的东西,为什么不使用平方根呢?


7
通常,多维数据集根转换效果很好,并且允许零和负数。我发现立方根在工作时特别有用,例如,测量单位是体积或每单位体积的颗粒计数。立方根会将其转换为线性尺寸。一种更灵活的方法是将受限制的三次样条曲线(自然样条曲线)拟合在立方根或平方根上,从而允许稍微偏离假定的形状。
Frank Harrell

2
+1。有关立方体根的小文章,请参见stata-journal.com/article.html?article=st0223(这是2014
Nick Cox

2
零的平方根为零,因此仅对非零值进行转换。如果零被夸大,这将无法处理峰值,并且如果成组的每个零都有不同的数量,则可能导致严重的问题。换句话说,如果某些组具有多个零,而另一些组具有很少的零,则此转换可能以负面方式影响许多事物。对于方差最大的组(也具有最小的零),几乎所有值都将被转换。相反,那些零最高的值不会被转换。这可以更改哪个组的方差最大。
D_Williams

在@D_Williams描述的情况下,没有任何转换将保持方差。在这种情况下,混合模型(在本线程的其他地方提到)可能是一个好方法。
MKT

10

我假设您有连续的数据。

如果数据包括零,则意味着您的零尖峰可能是由于数据的某些特定方面所致。例如出现在风能中,低于2 m / s的风产生零功率(称为切入),而超过25 m / s的风(大约绕过)也产生零功率(出于安全原因,被称为切断)。 。尽管产生的风能分布似乎是连续的,但峰值为零。

我的解决方案: 在这种情况下,我建议通过将零尖峰和计划用于连续分布部分的模型(wrt Lebesgue)混合使用,分别处理零点。


9

将@RobHyndman提供的答案与对数加一转换扩展为负值,格式为:

T(x)=sign(x)log(|x|+1)
r = -1000:1000

l = sign(r)*log1p(abs(r))
l = l/max(l)
plot(r, l, type = "l", xlab = "Original", ylab = "Transformed", col = adjustcolor("red", alpha = 0.5), lwd = 3)

#We scale both to fit (-1,1)
for(i in exp(seq(-10, 100, 10))){
  s = asinh(i*r)

  s = s / max(s)
  lines(r, s, col = adjustcolor("blue", alpha = 0.2), lwd = 3)
}
legend("topleft", c("asinh(x)", "sign(x) log(abs(x)+1)"), col = c("blue", "red"), lty = 1)

θθ1θ0

在此处输入图片说明


θx=0


8

由于已经提出了两参数拟合Box-Cox,因此这里有一些R可以拟合输入数据,对其运行任意函数(例如时间序列预测),然后返回倒相输出:

# Two-parameter Box-Cox function
boxcox.f <- function(x, lambda1, lambda2) {
  if (lambda1!=0) {
    return(((x + lambda2) ^ lambda1 - 1) / lambda1)
  } else {
    return(log(x + lambda2))
  }
}

# Two-parameter inverse Box-Cox function
boxcox.inv <- function(x, lambda1, lambda2) {
  if (lambda1!=0) {
    return((lambda1 * x + 1) ^ (1 / lambda1) - lambda2)
  } else {
    return(exp(x) - lambda2)
  }
}

# Function to Box-Cox transform x, apply function g, 
# and return inverted Box-Cox output y
boxcox.fit.apply <- function(x, g) {
  require(geoR)
  require(plyr)

  # Fit lambdas
  t <- try(lambda.pair <- boxcoxfit(x, lambda2=T)$lambda)

  # Estimating both lambdas sometimes fails; if so, estimate lambda1 only
  if (inherits(t, "try-error")) {
    lambda1 <- boxcoxfit(x)$lambda
    lambda2 <- 0
  } else {
    lambda1 <- lambda.pair[1]
    lambda2 <- lambda.pair[2]
  }
  x.boxcox <- boxcox.f(x, lambda1, lambda2)

  # Apply function g to x.boxcox. This should return data similar to x (e.g. ts)
  y <- aaply(x.boxcox, 1, g)

  return(boxcox.inv(y, lambda1, lambda2))
}

5

假设Y是每个美国人在给定年份在新车上花费的金额(总购买价)。Y将在0峰值;0到12,000之间的值将完全没有;并将采用其他价值观,主要是在十几岁,二十多岁和成千上万的人中。预测器将是进行此类购买的需求和/或兴趣水平的代理。对于没有购买商品的个人,几乎不能说需求或兴趣为零。在这些规模上,非购买者比Y甚至更接近Y的对数会更接近购买者。在类似这样的情况下,但在医疗保健领域,我发现通过测试集/训练集交叉验证判断出的最准确的预测是按递增顺序获得的,

  1. 对Y的二进制版本进行逻辑回归,
  2. Y上的OLS,
  3. Y上的有序回归(PLUM)分为5类(以便将购买者划分为4个均等大小的组),
  4. 将Y的多项式逻辑回归分为5类,
  5. Y的log(10)上的OLS(我没想到尝试使用多维数据集根),并且
  6. Y上的OLS分为5类。

有些人会反感连续因变量的这种分类。但是,尽管分类会牺牲一些信息,但是分类似乎可以通过恢复情况的一个重要基础方面来提供帮助-再次,“零”与其余部分比Y表示的要相似得多。


4
您还可以将其分为两个模型:购买汽车的概率(二进制响应)和购买后的汽车价值。这是在许多领域,如保险,信用风险等标准的做法
香港大井

1
@HongOoi-关于这种方法何时适用和不适用,您可以提出任何建议吗?
rolando2

4

讨论的汝约翰逊变电这里有专门用来处理零和底片,而在箱Cox幂转换的优势打造卓越性能。这是我处理零或负数据时通常要去的事情。

这是对优点/缺点进行转换的摘要,以说明为什么使用Yeo-Johnson是更可取的。

日志记录

优点:良好的正面数据。

缺点:不处理零。

> log(0)
[1] -Inf

日志加1

优点:加1的偏移量增加了处理正数据之外的零的能力。

缺点:负数据失败

> log1p(-1)
[1] -Inf
> log1p(-2)
[1] NaN
Warning message:
In log1p(-2) : NaNs produced

平方根

优点:使用能处理零和正数据的幂变换。

缺点:负数据失败

> sqrt(-1)
[1] NaN
Warning message:
In sqrt(-1) : NaNs produced

Box Cox

R代码:

box_cox <- function(x, lambda) {

    eps <- 0.00001
    if (abs(lambda) < eps)
        log(x)
    else
        (x ^ lambda - 1) / lambda

}

优点:实现按比例缩放的电源转换

缺点:遭受零和负数的问题(即只能处理正数数据)。

> box_cox(0, lambda = 0)
[1] -Inf
> box_cox(0, lambda = -0.5)
[1] -Inf
> box_cox(-1, lambda = 0.5)
[1] NaN

杨强森

R代码:

yeo_johnson <- function(x, lambda) {

    eps <- .000001
    not_neg <- which(x >= 0)
    is_neg  <- which(x < 0)

    not_neg_trans <- function(x, lambda) {
        if (abs(lambda) < eps) log(x + 1)
        else ((x + 1) ^ lambda - 1) / lambda
    }

    neg_trans <- function(x, lambda) {
        if (abs(lambda - 2) < eps) - log(-x + 1)
        else - ((-x + 1) ^ (2 - lambda) - 1) / (2 - lambda)
    }

    x[not_neg] <- not_neg_trans(x[not_neg], lambda)

    x[is_neg] <- neg_trans(x[is_neg], lambda)

    return(x)

}

优点:可以处理正,零和负数据。

缺点:我想不到的。属性与Box-Cox非常相似,但可以处理零和负数据。

> yeo_johnson(0, lambda = 0)
[1] 0
> yeo_johnson(0, lambda = -0.5)
[1] 0
> yeo_johnson(-1, lambda = 0.5)
[1] -1.218951

1
Yeo-Johnson的缺点:对正负值和lambda两侧的值进行复杂,单独的转换,即魔术调整值(epsilon;什么是lambda?)。与Firebug答案中所示的简单的负扩展对数变换相比,没有明显的优势,除非您需要按比例缩放的幂变换(如Box-Cox)。
康拉德·鲁道夫

1

为了阐明如何处理回归模型中的零对数,我们编写了一份教学论文,解释了最佳解决方案和人们在实践中常犯的错误。我们还提出了解决该问题的新解决方案。

您可以通过单击此处找到论文:https : //ssrn.com/abstract=3444996

log(y)=βlog(x)+εβyx

YY+c>0

在我们的文章中,我们实际上提供了一个示例,其中添加非常小的常数实际上可以提供最高的偏差。我们提供派生偏见的表达。

实际上,泊松伪极大似然(PPML)可以被视为解决此问题的好方法。必须考虑以下过程:

yi=aiexp(α+xiβ)E(ai|xi)=1

βaiyi=0E(ai|xi)=1E(yiexp(α+xiβ)|xi)=0

i=1N(yiexp(α+xiβ))xi=0

yi=0

β

log(yi+exp(α+xiβ))=xiβ+ηi

我们证明了该估计量是无偏的,并且可以使用GMM和任何标准统计软件简单地对其进行估计。例如,可以通过仅使用Stata执行一行代码来进行估计。

希望本文能对您有所帮助,我们希望能收到您的反馈。

ChristopheBellégo和Louis-Daniel Pape CREST-理工学院-ENSAE

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.