在 R 中拟合 t 分布:缩放参数

机器算法验证 r 分布 最大似然 配件 强大的
2022-01-31 08:53:53

如何拟合 t 分布的参数,即对应于正态分布的“均值”和“标准差”的参数。我假设它们被称为 t 分布的“平均”和“缩放/自由度”?

以下代码通常会导致“优化失败”错误。

library(MASS)
fitdistr(x, "t")

我必须先缩放 x 还是转换成概率?如何最好地做到这一点?

4个回答

fitdistr使用最大似然和优化技术来查找给定分布的参数。有时,特别是对于 t 分布,正如@user12719 所注意到的,优化形式如下:

fitdistr(x, "t")

失败并出现错误。

在这种情况下,您应该通过提供起点和下限来开始搜索最佳参数,从而帮助优化器:

fitdistr(x, "t", start = list(m=mean(x),s=sd(x), df=3), lower=c(-1, 0.001,1))

请注意,df=3您对“最佳”df可能是什么做出了最好的猜测。提供此附加信息后,您的错误将消失。

一些摘录可帮助您更好地了解以下内容的内部机制fitdistr

对于正态分布、对数正态分布、几何分布、指数分布和泊松分布,使用封闭式 MLE(和精确标准误差),start不应提供。

...

start对于以下命名分布,如果省略或仅部分指定,将计算合理的起始值:“cauchy”、“gamma”、“logistic”、“负二项式”(由 mu 和 size 参数化)、“t”和“weibull ”。请注意,如果拟合不佳,这些起始值可能不够好:特别是它们不能抵抗异常值,除非拟合分布是长尾分布。

MASS,这本书(第 4 版,第 110 页)建议不要试图估计ν, 中的自由度参数t- 最大似然分布(参考文献:Lange 等人 (1989),“使用 t 分布的稳健统计建模”,JASA , 84 , 408Fernandez & Steel (1999),“Multivariate Student- t回归模型: 陷阱和推理”,Biometrika , 86 , 1 )。

原因是似然函数ν基于 t 密度函数,可能是无界的,并且在这些情况下不会给出明确定义的最大值。让我们看一个已知位置和规模的人工示例(作为标准t-分布),只有自由度是未知的。下面是一些 R 代码,模拟一些数据,定义对数似然函数并绘制它:

set.seed(1234)
n <- 10
x <- rt(n,  df=2.5)

make_loglik  <-  function(x)
    Vectorize( function(nu) sum(dt(x, df=nu,  log=TRUE)) )

loglik  <-  make_loglik(x)
plot(loglik,  from=1,  to=100,  main="loglikelihood function for df     parameter", xlab="degrees of freedom")
abline(v=2.5,  col="red2")

在此处输入图像描述

如果您使用此代码,您会发现某些情况下存在明确定义的最大值,尤其是当样本量n很大。但是最大似然估计有什么好处吗?

让我们尝试一些模拟:

t_nu_mle  <-  function(x) {
    loglik  <-  make_loglik(x)
    res  <-  optimize(loglik, interval=c(0.01, 200), maximum=TRUE)$maximum
    res   
}

nus  <-  replicate(1000, {x <- rt(10, df=2.5)
    t_nu_mle(x) }, simplify=TRUE)

> mean(nus)
[1] 45.20767
> sd(nus)
[1] 78.77813

显示估计非常不稳定(查看直方图,估计值的相当大一部分处于优化的上限 200)。

以更大的样本量重复:

nus  <-  replicate(1000, {x <- rt(50, df=2.5)
    t_nu_mle(x) }, simplify=TRUE)
> mean(nus)
[1] 4.342724
> sd(nus)
[1] 14.40137

这要好得多,但平均值仍远高于 2.5 的真实值。

然后请记住,这是实际问题的简化版本,其中还必须估计位置和尺度参数。

如果使用的原因t-distribution 是“robustify”,然后估计ν从数据中很可能会破坏稳健性。

在 fitdistr 的帮助中是这个例子:

fitdistr(x2, "t", df = 9)

表明您只需要 df 的值。但这假设标准化。

为了获得更多控制,他们还显示

mydt <- function(x, m, s, df) dt((x-m)/s, df)/s
fitdistr(x2, mydt, list(m = 0, s = 1), df = 9, lower = c(-Inf, 0))

其中参数为 m = 平均值,s = 标准偏差,df = 自由度

根据维基百科上的这篇文章,您可以在基础 R 中扩展学生 t 的位置和缩放参数后使用 fitdistrplus 库下面是示例代码

library(fitdistrplus)
x<-rt(100,23)
dt_ls <- function(x, df=1, mu=0, sigma=1) 1/sigma * dt((x - mu)/sigma, df)
pt_ls <- function(q, df=1, mu=0, sigma=1)  pt((q - mu)/sigma, df)
qt_ls <- function(p, df=1, mu=0, sigma=1)  qt(p, df)*sigma + mu
rt_ls <- function(n, df=1, mu=0, sigma=1)  rt(n,df)*sigma + mu
fit.t<-fitdist(x, 't_ls', start =list(df=1,mu=mean(x),sigma=sd(x))) 
summary(fit.t)