R中混合物的拟合优度检验

机器算法验证 r 正态分布 拟合优度 混合分布
2022-03-29 18:00:46

我刚刚估计了两个具有不同均值和不同 sigma 的高斯混合的参数,我想测试数据是否能很好地适应混合的显式形式,我是否一定需要模拟来自混合的数据或者我怎么能测试拟合优度?我正在使用 mixtools 包。

1个回答

您可以编写一个函数,根据来自 的输出在零假设下计算给定测试的相关值normalmixEM,然后使用它进行测试。例如,对于 Kolmogorov-Smirnov 检验,我们需要给定一组参数的 CDF:

# CDF of mixture of two normals
pmnorm <- function(x, mu, sigma, pmix) {
  pmix[1]*pnorm(x,mu[1],sigma[1]) + (1-pmix[1])*pnorm(x,mu[2],sigma[2])
}

然后我们以通常的方式运行 KS 测试:

# Sample run
x <- c(rnorm(50), rnorm(50,2))

foo <- normalmixEM(x)
test <- ks.test(x, pmnorm, mu=foo$mu, sigma=foo$sigma, pmix=foo$lambda)
test

    One-sample Kolmogorov-Smirnov test

data:  x 
D = 0.0559, p-value = 0.914
alternative hypothesis: two-sided 

始终牢记这样一个事实,即我们根据用于测试的相同数据估计参数,从而使测试偏向于拒绝 H0。

我们可以通过参数引导在一定程度上克服后一种偏差 - 从由 的估计参数化的法线混合生成许多样本normalmixEM,然后估计样本的参数并使用估计的参数计算每个样本的测试统计量。在这种结构下,原假设总是正确的。在下面的代码中,我从样本的真实参数开始帮助 EM 算法,这也有点作弊,因为与原始样本相比,它使 EM 算法更有可能找到接近真实值的值,但大大减少了错误消息的数量。

# Bootstrap estimation of ks statistic distribution
N <- length(x)
ks.boot <- rep(0,1000)
for (i in 1:1000) {
  z <- rbinom(N, 1, foo$lambda[1])
  x.b <- z*rnorm(N, foo$mu[1], foo$sigma[1]) + (1-z)*rnorm(N, foo$mu[2], foo$sigma[2])
  foo.b <- normalmixEM(x.b, maxit=10000, lambda=foo$lambda, mu=foo$mu, sigma=foo$sigma)
  ks.boot[i] <- ks.test(x.b, pmnorm, mu=foo.b$mu, sigma=foo.b$sigma, pmix=foo.b$lambda)$statistic
}

mean(test$statistic <= ks.boot)
[1] 0.323

因此,我们得到的 p 值不是 0.914,而是 0.323。有趣,但在这种情况下并不是特别重要。