前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据分布检验利器:QQ plot

数据分布检验利器:QQ plot

原创
作者头像
皮大大
发布于 2025-01-22 09:24:47
发布于 2025-01-22 09:24:47
25600
代码可运行
举报
运行总次数:0
代码可运行

公众号:尤而小屋 编辑:Peter 作者:Peter

大家好,我是Peter~

机器学习数据分析中,验证数据是否符合特定分布(如正态分布)是一个关键步骤,因为它直接影响统计方法和机器学习模型的选择。

许多统计检验(如t检验、ANOVA)和机器学习算法(如线性回归、高斯朴素贝叶斯)都基于数据服从正态分布的假设:如果这一假设不成立,模型的性能可能会受到影响,此时我们需要对数据进行转换(如对数变换或标准化)或选择更适合的非参数方法。

Q-Q图(Quantile-Quantile Plot)正是为解决这一问题而设计的强大可视化工具。它通过将数据的分位数与理论分布的分位数进行对比,直观地展示数据分布与目标分布(如正态分布)之间的差异。这种可视化不仅帮助我们快速判断数据是否满足分布假设,还能为数据转换或模型选择提供重要依据,从而确保分析结果的准确性和可靠性。

数据分布

概念

数据分布描述了数据在不同取值上的频率或概率。它展示了数据在各个区间或类别中的分布情况,是统计和概率学中的核心概念。

常见分布类型

  1. 正态分布(高斯分布):对称的钟形曲线,均值、中位数、众数相等。
  2. 均匀分布:所有取值在区间内概率相等。
  3. 二项分布:描述n次独立试验中成功的次数,每次试验成功概率为p。
  4. 泊松分布:描述单位时间内某事件发生的次数,事件发生概率低且独立。
  5. 指数分布:描述事件发生的时间间隔,具有无记忆性。
  6. 卡方分布:由独立标准正态变量的平方和构成。
  7. t分布:类似正态分布,但尾部更厚,适用于小样本。
  8. F分布:由两个卡方分布的比值构成。

什么是分位数

分位数是将数据按大小排序后,分成若干等份的点。常见的分位数包括中位数、十分位数和百分位数等。

  • 中位数:将数据分成两等份的点(0.5分位数)
  • 四分位数:将数据分成四等份的点(0.25, 0.5, 0.75分位数)
  • 百分位数:将数据分成100等份的点(0.01, 0.02, ..., 0.99分位数)

为什么使用分位数?

分位数有几个重要特性:

  • 不受极端值影响:相比均值,分位数对异常值更稳健
  • 保持数据的顺序关系:反映了数据的分布特征
  • 易于比较不同尺度的数据:通过标准化后的位置进行比较

QQ图

工作原理

QQ图(Quantile-Quantile Plot,又称之为分位图)是一种用于比较两个概率分布是否相似的图形工具。它通过对比两个分布的分位数来判断它们是否一致,常用于检验数据是否服从某一理论分布(如正态分布)。

步骤

  1. 排序样本数据:将样本数据按升序排列。
  2. 计算经验分位数:对每个数据点计算其经验分位数。
  3. 计算理论分位数:根据理论分布计算对应分位数。
  4. 绘制图形:将样本分位数与理论分位数绘制在图中。
  5. 分析结果:通过点的分布判断样本数据是否符合理论分布。

Q-Q图的解读规则

  • 点落在直线上:两个分布非常相似
  • 点偏离直线但呈S形:数据可能需要简单变换
  • 点严重偏离直线:分布差异显著

QQ图在机器学习中的应用案例

比较多组数据集的分布

两个数据集的比较:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 生成两个数据集
np.random.seed(42)
data1 = np.random.normal(loc=0, scale=1, size=100)
data2 = np.random.normal(loc=0.5, scale=1.2, size=100)

# 绘制QQ图比较两个数据集
stats.probplot(data1, dist="norm", plot=plt)
stats.probplot(data2, dist="norm", plot=plt)
plt.title('QQ Plot: Comparing Two Datasets')
plt.legend(['Data 1', 'Data 2'])
plt.show()

三个数据集的比较:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

# 生成多组数据
np.random.seed(42)
data1 = np.random.normal(loc=0, scale=1, size=100)
data2 = np.random.normal(loc=1, scale=1.5, size=100)
data3 = np.random.normal(loc=-1, scale=0.8, size=100)

# 绘制多组QQ图
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for i, data in enumerate([data1, data2, data3]):
    stats.probplot(data, dist="norm", plot=axes[i])
    axes[i].set_title(f'Dataset {i+1}')
plt.tight_layout()
plt.show()

检查数据是否符合正态-均匀-指数分布

1、指数分布

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
# 设置支持中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] 
# 设置图像标题字体
plt.rcParams['axes.unicode_minus'] = False 

# 生成示例数据(假设为正态分布)
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=1000)

# 绘制QQ图
plt.figure(figsize=(8, 6))
stats.probplot(data, dist="norm", plot=plt)
plt.title('QQ Plot - 检查数据是否服从正态分布')
plt.show()

2、均匀分布

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 生成均匀分布样本数据
data = np.random.uniform(low=0, high=1, size=100)

# 绘制QQ图
stats.probplot(data, dist="uniform", plot=plt)
plt.title('Uniform QQ Plot')
plt.show()

3、指数分布

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 生成指数分布样本数据
data = np.random.exponential(scale=1, size=100)

# 绘制QQ图
stats.probplot(data, dist="expon", plot=plt)
plt.title('Exponential QQ Plot')
plt.show()

自定义数据分布

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 生成自定义分布样本数据
data = np.random.beta(a=2, b=5, size=100)

# 绘制QQ图
stats.probplot(data, dist="beta", sparams=(2, 5), plot=plt)
plt.title('Beta QQ Plot')
plt.show()

检查特征分布并进行转换

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 生成示例数据(假设为右偏分布)
np.random.seed(42)
data = np.random.exponential(scale=2, size=1000)

# 绘制原始数据的QQ图
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
stats.probplot(data, dist="norm", plot=plt)
plt.title('QQ Plot - 原始数据')

# 对数据进行对数变换
transformed_data = np.log1p(data)

# 绘制变换后的QQ图
plt.subplot(1, 2, 2)
stats.probplot(transformed_data, dist="norm", plot=plt)
plt.title('QQ Plot - 对数变换后数据')
plt.show()
  • 原始数据的 QQ 图显示数据不服从正态分布(右偏)。
  • 对数变换后,数据更接近正态分布,适合用于某些模型(如线性回归)。

检查残差是否符合正态分布

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import statsmodels.api as sm
import scipy.stats as stats

# 生成示例数据
np.random.seed(42)
X = np.random.normal(size=1000)
y = 2 * X + np.random.normal(size=1000)

# 拟合线性回归模型
X = sm.add_constant(X)  # 添加截距项
model = sm.OLS(y, X).fit()

# 获取残差!!!
residuals = model.resid

# 绘制残差的QQ图
plt.figure(figsize=(8, 6))
stats.probplot(residuals, dist="norm", plot=plt)
plt.title('QQ Plot - 线性回归残差')
plt.show()
  • 如果残差点大致落在红色对角线上,说明残差服从正态分布,模型假设成立。
  • 如果残差点偏离对角线,说明残差不服从正态分布,可能需要改进模型或进行数据变换。

KDE图&QQ图

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns

# 生成数据
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=100)

# 绘制KDE图
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
sns.kdeplot(data, shade=True, color='blue')
plt.title('Kernel Density Estimation (KDE)')

# 绘制QQ图
plt.subplot(1, 2, 2)
stats.probplot(data, dist="norm", plot=plt)
plt.title('QQ Plot')
plt.tight_layout()
plt.show()

参考

1、Understanding QQ Plots:https://library.virginia.edu/data/articles/understanding-q-q-plots

2、understand QQ plots:https://medium.com/@adarshmanojsingh/understand-q-q-plot-298d47da234e

3、kaggle QQ-plot: https://www.kaggle.com/code/gadaadhaarigeek/q-q-plot

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据分布
    • 概念
    • 常见分布类型
  • 什么是分位数
  • 为什么使用分位数?
  • QQ图
    • 工作原理
    • 步骤
    • Q-Q图的解读规则
  • QQ图在机器学习中的应用案例
    • 比较多组数据集的分布
    • 检查数据是否符合正态-均匀-指数分布
    • 自定义数据分布
    • 检查特征分布并进行转换
    • 检查残差是否符合正态分布
    • KDE图&QQ图
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档