统计问题|绘制任意分布的 QQ 图

简介: 统计问题|绘制任意分布的 QQ 图

简介

最近科研论文的审稿意见,需要对数据的拟合情况进行说明。分位数-分位数图[1](Quantile-Quantile plot,简称 QQ 图)是一种不错的选择。

研究动机

在 R 语言中常用 qqnorm() 绘制 QQ 图的散点图,qqline() 用于在图上添加一条参考直线。可支持与一些常见的理论分布进行比较,例如:正态分布 ("norm")、指数分布 ("exp")、伽马分布 ("gamma")、威布尔分布 ("weibull")、对数正态分布 ("lnorm")等。

但是绘制出来的图形可能不是很美观,如下所示:

本文贡献点

当然小编以前使用 ggplot 绘制过:绘制不同分布的 QQ 图,但内容不包括逆高斯分布以及其他比较“新”的分布。

基于这个痛点,本文小编将根据 QQ 图的定义,通过 ggplot2[2] 复现自己常用的三个分布(正态、伽马和逆高斯分布)的 QQ 图。

题外话:读者可以根据本文思路,拓展到任何自己感兴趣的分布。

教程

理论介绍

介绍:一种用于检查数据是否符合某个理论分布的统计图。

基本思想:比较观察数据的分位数与理论分布的分位数。

判断依据:如果数据符合理论分布,那么 QQ 图上的点将近似落在一条直线上。

绘制步骤

  1. 排序数据:将观察数据按照大小进行排序。
  2. 计算分位数:计算每个观察数据点对应的分位数。这可以通过排名除以总数据点的数量来实现。
  3. 计算理论分位数:使用所选择的理论分布的累积分布函数,计算对应于每个观察数据点的理论分位数。
  4. 绘制 QQ 图:将观察数据的分位数作为横坐标,理论分位数作为纵坐标,绘制散点图。如果数据符合理论分布,散点图将近似为一条直线。

代码实现

根据上面的理论结果,我们依次进行代码实现。假设数据来自于 gamma 分布。

y <- rgamma(200,10,1)
  1. 排序数据
sorted_data <- sort(y)
  1. 计算样本分位数
sample_quantiles <- (1:length(sorted_data) - 0.5) / length(sorted_data)
  1. 计算理论分位数

首先,对数据进行参数估计,得到估计之后,产生理论分位数。

3.1 参数估计

这里使用极大似然方法估计参数,首先定义对数似然函数:

library(statmod)
fn_ig <- function(par= c(mean, dispersion), data) {
  ll <- -sum(dinvgauss(data, mean= par[1], dispersion= par[2], log= TRUE))   
  return(ll)
}

3.2 参数估计,并计算理论分位数:

pp <- optim(par= c(1,1), fn_ig, data = y)
mq <- pp$par[1]; disp <- pp$par[2] 
theoretical_quantiles <- qinvgauss(sample_quantiles, mean= mq, dispersion= disp)
  1. 绘制 QQ 图

数据整理并绘制

#数据整理
data_ig = data.frame("x" = theoretical_quantiles, "y" = sorted_data)
#绘制
library(ggplot2)
ggplot(data_ig,aes(x=x, y=y)) +
  geom_point(color="#4CA6A3",size=1.2) + 
  geom_abline(intercept = 0, slope = 1,color="#693476",size=1) + 
  # facet_wrap(vars(factor(pc)),scales = "free") + 
  theme_bw() + theme(legend.position = "none") + 
  xlab("Theoretical") + ylab("Sample")

此时,给出了该数据使用逆高斯分布拟合的情况,结果还算可以!读者可以通过一些检验(Kolmogorov–Smirno[3]等),进行进一步检测。

拓展

根据这个思路,小编写了正态和 Gamma 的结果,并通过一个函数将三种分布的整合在一起。最后绘制出三种分布拟合该数据的结果。

还计算了三种分布拟合的 KS 检验的 p 值:

p 值均大于 0.05,接受原假设,即三种分布拟合该数据均可。读者可以将合并的图放到自己论文中,仅需将 y 修改成自己的数据即可!

汇总代码

y <- rgamma(200,10,1)
library(statmod)
fn_ig <- function(par= c(mean, dispersion), data) {
  ll <- -sum(dinvgauss(data, mean= par[1], dispersion= par[2], log= TRUE))   
  return(ll)
}
fn_normal <- function(par = c(mean, sd), data) {
  # 正态分布的对数似然函数
  ll <- -sum(dnorm(data, mean = par[1], sd = par[2], log = TRUE))
  return(ll)
}
fn_gamma <- function(par = c(shape, rate), data) {
  # 伽马分布的对数似然函数
  ll <- -sum(dgamma(data, shape = par[1], rate = par[2], log = TRUE))
  return(ll)
}
qqdat = function(den = "ig", y = diff_y_all, par= c(1, 1)){
  # 排序数据
  sorted_data <- sort(y)
  # 计算样本分位数
  sample_quantiles <- (1:length(sorted_data) - 0.5) / length(sorted_data)
  if(den == "ig"){
    # 参数估计
    pp <- optim(par= par, fn_ig, data = y)
    mq <- pp$par[1]; disp <- pp$par[2] 
    # 计算理论分位数
    theoretical_quantiles <- qinvgauss(sample_quantiles, mean= mq, dispersion= disp)
  } else if(den == "norm"){
    pp <- optim(par= par, fn_normal, data = y)
    mq <- pp$par[1]; disp <- pp$par[2] 
    theoretical_quantiles <- qnorm(sample_quantiles, mq, disp)
  } else if(den == "gamma"){
    pp <- optim(par= par, fn_gamma, data = y)
    mq <- pp$par[1]; disp <- pp$par[2] 
    theoretical_quantiles <- qgamma(sample_quantiles, shape = mq, rate = disp)
  }
  data_ig = data.frame("x" = theoretical_quantiles, "y" = sorted_data)
  return(list(data_ig,"Para"= c(mq,disp)))
}
# 数据处理
qqplot_den = function(den = "norm",data6 = y,par= c(10, 1)){
  u1 = qqdat(den = den, data6, par= par)
  ig_g = data.frame(u1[[1]])
  w1 = ggplot(ig_g,aes(x=x, y=y)) +
    geom_point(color="#4CA6A3",size=1.2) + 
    geom_abline(intercept = 0, slope = 1,color="#693476",size=1) + 
    theme_bw() + theme(legend.position = "none") + 
    xlab("Theoretical") + ylab("Sample")
  if(den=="norm"){
    kstest = ks.test(data6, "pnorm", mean = u1$Para[1], u1$Para[2])$p.value
  } else if(den=="ig"){
    library(fitdistrplus)
    kstest = ks.test(data6, "pinvgauss", mean = u1$Para[1], dispersion = u1$Para[2])$p.value
  } else if(den=="gamma"){
    kstest = ks.test(data6, "pgamma", u1$Para[1], u1$Para[2])$p.value
  }
  return(list(w1,kstest))
}
w1 = qqplot_den(den = "norm",data6 = y,par= c(10, 1))
w2 = qqplot_den(den = "ig",data6 =  y,par= c(1, 1))
w3 = qqplot_den(den = "gamma",data6 =  y,par= c(1, 1))
cowplot::plot_grid(w1[[1]],w2[[1]],w3[[1]],labels=c("N","IG","G"),nrow=1)
# ggsave("qqplot.pdf", width = 8,height = 4)

参考资料

[1]

分位数-分位数图: https://haomenghit.github.io/2019/08/04/Q-Q%E5%9B%BE%E4%BB%8B%E7%BB%8D/

[2]

ggplot2: https://ggplot2.tidyverse.org/

[3]

Kolmogorov–Smirno: https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
关系型数据库 PostgreSQL
|
机器学习/深度学习 数据可视化 算法
数据处理方法—— 7 种数据降维操作 !!
数据处理方法—— 7 种数据降维操作 !!
618 0
|
7月前
|
人工智能 开发者
文章和 PPT 配图有救了!SVG 绘图专家智能体大揭秘
本文分享如何使用 DeepSeek-V3-0324 和 Claude 3.5 或 3.7 绘制出高质量的图片,可以作为文章配图也可以为 PPT 配图,效率成倍增长。文章还介绍了原型图绘制、图片重绘修改和彩色报纸风的进阶案例。希望本文提供的技巧对大家有帮助,大家也可以修改提示词定制自己喜欢的风格。
436 13
|
11月前
|
机器学习/深度学习 数据采集 运维
数据分布检验利器:通过Q-Q图进行可视化分布诊断、异常检测与预处理优化
Q-Q图(Quantile-Quantile Plot)是一种强大的可视化工具,用于验证数据是否符合特定分布(如正态分布)。通过比较数据和理论分布的分位数,Q-Q图能直观展示两者之间的差异,帮助选择合适的统计方法和机器学习模型。本文介绍了Q-Q图的工作原理、基础代码实现及其在数据预处理、模型验证和金融数据分析中的应用。
1245 11
数据分布检验利器:通过Q-Q图进行可视化分布诊断、异常检测与预处理优化
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】探讨最新的深度学习算法、模型创新以及在图像识别、自然语言处理等领域的应用进展
深度学习作为人工智能领域的重要分支,近年来在算法、模型以及应用领域都取得了显著的进展。以下将探讨最新的深度学习算法与模型创新,以及它们在图像识别、自然语言处理(NLP)等领域的应用进展。
448 6
|
12月前
|
数据采集 人工智能 自然语言处理
万字干货|复杂表格多Agent方案:从LLM洞察、系统性 思考到实践经验总结
笔者结合实践经验以近期在负责的复杂表格智能问答为切入点,结合大模型的哲学三问(“是谁、从哪里来、到哪里去”),穿插阐述自己对大模型的一些理解与判断,以及面向公共云LLM的建设模式思考,并分享软件设计+模型算法结合的一些研发实践经验。
1082 43
|
安全 网络协议 Unix
使用SCP在Linux中安全复制文件:参数详解
使用SCP在Linux中安全复制文件:参数详解
569 0
|
存储 缓存 大数据
深入了解Linux文件系统
了解Linux文件系统的关键概念,包括其作为OS与硬件接口的角色,以及ext4、XFS、Btrfs、ZFS和JFS等常见类型。文件系统由超级块、inode和数据块组成,管理涉及创建、挂载、卸载及容量监控。性能优化可通过缓存策略、参数调整和碎片整理实现。文件系统安全依赖权限控制、加密和ACL。随着技术进步,新型文件系统将应对云计算和大数据的挑战。
315 3
|
机器学习/深度学习 人工智能 分布式计算
因果推断:效应估计的常用方法及工具变量讨论
日常工作中很多的策略/产品的效果是无法设计完美的随机实验的,要求我们从观察性数据中去(拟合随机试验)发现因果关系、测算因果效应。
2532 0
因果推断:效应估计的常用方法及工具变量讨论