深入解析累积频率曲线:从基础理论到Python可视化实战

在处理数据分析和统计学的过程中,我们经常需要面对海量的原始数据。盯着满屏的数字表格,不仅让人眼花缭乱,而且很难快速发现数据背后的规律。这时候,可视化图表就成了我们手中的利器。通过图表,我们可以直观地看到数据的分布趋势、中心位置以及离散程度。

在今天的这篇文章中,我们将深入探讨统计学中非常重要的一种图形工具——累积频率曲线(Cumulative Frequency Curve)。无论你是正在学习统计学的学生,还是希望在数据分析项目中更上一层楼的数据科学家,掌握这一技能都将帮助你更高效地理解和展示数据。

我们将从基础概念出发,带你一起理解什么是累积频率,如何手动计算,最终我们将使用 Python 这一强大的工具来自动化绘制这些专业的统计图表。让我们开始这段数据可视化的旅程吧。

什么是频率与累积频率?

在我们深入绘制曲线之前,必须先打好地基。让我们先来理清两个核心概念:频率和累积频率。

频率 指的是在某个特定的区间或类别中,事件发生的次数。比如,在一场考试中,分数在 0-10 分之间的人数是 2 人,这里的“2”就是频率。

累积频率 则更有意思,它体现了数据的累积过程。简单来说,它是从第一个区间开始,一直到当前区间的所有频率之和。这就像是我们走上楼梯,每上一层台阶,我们到达的总高度就是之前所有台阶高度加上当前台阶高度的总和。

#### 一个简单的入门示例

让我们看一个非常直观的例子,来手动计算一下累积频率。假设我们有以下一组关于区间分布的数据:

区间

频率

:—

:—

0-10

2

10-20

4

20-30

5在左边的表格中,我们列出了区间和对应的原始频率。现在,我们要计算“累积频率”。请记住这个核心逻辑:当前类别的累积频率 = 之前所有类别的频率之和 + 当前类别的频率

计算过程如下:

  • 区间 (0-10):这是第一个区间,没有之前的频率,所以它的累积频率就是它本身,即 2
  • 区间 (10-20):我们需要加上之前的频率。所以累积频率 = 2 (之前的) + 4 (当前的) = 6
  • 区间 (20-30):继续累加。累积频率 = 2 + 4 (之前的) + 5 (当前的) = 11

最终,我们得到了如下的 累积频率表

区间

频率

累积频率 :—

:—

:— 0-10

2

2 10-20

4

6 20-30

5

11

这种表格形式虽然准确,但还不够直观。为了更高效地展示数据分布,我们就需要引入图形的方法,也就是今天的主角:累积频率曲线,它还有一个学名叫做 卵形线

累积频率曲线的两种形态

在实际应用中,根据我们分析问题的角度不同,累积频率曲线主要分为两种类型:

  • “小于”累积频率曲线:最常用的一种,分析“小于某个数值的数据有多少”。
  • “大于”累积频率曲线:用于分析“大于某个数值的数据有多少”。

让我们详细拆解这两种类型,并结合 Python 代码来看看如何在实战中应用它们。

#### 1. “小于”累积频率曲线

这是最标准、最常见的累积频率曲线。它的逻辑是:计算并绘制小于各组上限的数据总个数。

计算逻辑

假设我们有一组新的数据:

区间

频率

:—

:—

5-10

2

10-15

4

15-20

5为了绘制“小于”曲线,我们需要关注区间的 上限,并将频率依次累加。我们来看看计算表:

区间

频率

累积频率计算

累积频率

对应上限 :—

:—

:—

:—

:— 5-10

2

2

2

10 10-15

4

2 + 4

6

15 15-20

5

2 + 4 + 5

11

20

绘图原理

在传统手工绘图中,我们会这样操作:

  • 建立坐标系,X 轴代表变量的数值(比如分数),Y 轴代表累积频率。
  • 在 X 轴上标记 上限 (10, 15, 20)。
  • 在 Y 轴上标记对应的累积频率 (2, 6, 11)。
  • 用平滑的曲线连接这些点。

Python 实战:绘制“小于”曲线

作为技术人员,手动画图太慢了。让我们用 Python 的 matplotlib 库来实现这一过程。这不仅准确,而且可以直接应用到大数据集上。

import matplotlib.pyplot as plt

# 1. 准备数据
intervals = [‘5-10‘, ‘10-15‘, ‘15-20‘]
frequencies = [2, 4, 5]
upper_limits = [10, 15, 20] # 对应 X 轴

# 2. 计算累积频率
cumulative_freq = []
current_sum = 0
for freq in frequencies:
    current_sum += freq
    cumulative_freq.append(current_sum)

# 打印一下计算结果,方便理解
print(f"区间: {intervals}")
print(f"累积频率: {cumulative_freq}")

# 3. 绘制图形
plt.figure(figsize=(10, 6))

# 绘制累积频率多边形(折线)
plt.plot(upper_limits, cumulative_freq, marker=‘o‘, linestyle=‘-‘, color=‘b‘, label=‘小于累积频率曲线‘)

# 添加标题和标签
plt.title(‘"小于"累积频率分布曲线示例‘, fontsize=14)
plt.xlabel(‘分数上限‘, fontsize=12)
plt.ylabel(‘累积频数‘, fontsize=12)
plt.grid(True, which=‘both‘, linestyle=‘--‘, linewidth=0.5)
plt.legend()

# 设置坐标轴范围,让图形更美观
plt.xlim(0, 25)
plt.ylim(0, max(cumulative_freq) + 2)

plt.show()

代码解析:

  • 数据准备:我们定义了区间和原始频率。
  • 计算逻辑:通过一个简单的 INLINECODEee449e14 循环,我们实现了频率的累加,得到了 INLINECODEa3584a4b 列表 [2, 6, 11]
  • 绘图:我们使用 INLINECODE7150c58e,将 X 轴设为上限值,Y 轴设为累积频率。INLINECODE5ee014da 让我们清晰地看到数据点在哪里。

如何利用图形求中位数?

这通常是考试或面试中的一个考点。假设我们手绘了一张累积频率曲线,如何快速找到中位数?

  • 计算 N/2(即总频率的一半)。在这个例子中,总频率 N=11,所以 N/2 = 5.5。
  • 在 Y 轴上找到数值 5.5,画一条平行于 X 轴的直线,直到与曲线相交。
  • 从交点向 X 轴引垂线,垂足在 X 轴上的数值就是中位数。

#### 2. “大于”累积频率曲线

“大于”累积频率曲线的逻辑正好相反。它关心的是:大于某个下限的数据还有多少。这在分析“淘汰率”或“剩余库存”时非常有用。

计算逻辑

在“大于”类型中,我们从最后一个区间开始,倒着向前累加(或者用总数依次减去当前频率)。让我们使用一组稍有不同的数据来演示:

区间

频率

:—

:—

5-10

20

10-15

4

15-20

5这里,总频数 N = 20 + 4 + 5 = 29。

我们关注的是区间的 下限。计算过程如下:

  • 区间 (5-10):下限是 5。大于 5 的所有数据就是总数本身,即 20。(注:通常从最后一个区间倒推更符合逻辑,但在“大于”表中,第一行通常代表“大于该组下限的所有频数”)。让我们使用更严谨的“倒推法”:

* 最后区间 (15-20):大于等于 15 的频数是 5

* 区间 (10-15):大于等于 10 的频数是 5 + 4 = 9

* 区间 (5-10):大于等于 5 的频数是 9 + 20 = 29

但在教科书给出的特定示例中,有时为了展示递减规律,会采用“从上往下减”的方式展示,这在视觉上是一条下降的曲线。让我们使用通用的数学定义来编写代码:计算大于或等于下限的累积频率

区间

频率

累积频率(大于)

对应下限

:—

:—

:—

:—

5-10

20

29 (总数)

5

10-15

4

9 (4+5)

10

15-20

5

5

15Python 实战:绘制“大于”曲线

让我们编写代码来处理这种情况。请注意,对于“大于”曲线,累积频率是递减的(从左到右看),或者是根据下限定义的递增趋势。为了避免混淆,我们通常画出一条表示“剩余数量”的曲线。

import matplotlib.pyplot as plt

# 1. 准备数据
intervals = [‘5-10‘, ‘10-15‘, ‘15-20‘]
frequencies = [20, 4, 5]
lower_limits = [5, 10, 15] # 对应 X 轴下限

# 2. 计算累积频率 (大于等于逻辑)
# 方法:从后往前累加
cumulative_freq_greater = []
current_sum = 0
# 倒序遍历频率列表
for freq in reversed(frequencies):
    current_sum += freq
    cumulative_freq_greater.insert(0, current_sum) # 插入到列表头部保持顺序

print(f"区间: {intervals}")
print(f"累积频率(大于): {cumulative_freq_greater}")

# 3. 绘制图形
plt.figure(figsize=(10, 6))

plt.plot(lower_limits, cumulative_freq_greater, marker=‘o‘, linestyle=‘-‘, color=‘r‘, label=‘大于累积频率曲线‘)

# 添加标题和标签
plt.title(‘"大于"累积频率分布曲线示例‘, fontsize=14)
plt.xlabel(‘分数下限‘, fontsize=12)
plt.ylabel(‘累积频数 (大于等于下限)‘, fontsize=12)
plt.grid(True, which=‘both‘, linestyle=‘--‘, linewidth=0.5)
plt.legend()

plt.show()

在这个代码中,我们使用了 reversed(frequencies) 来从最后一个区间开始累加。这非常符合“大于”的逻辑——最后一组只有自己,往前每一组都包含后面的所有组。

综合应用与最佳实践

在实际的数据分析工作中,我们很少只手算两三行数据。通常,我们需要处理成千上万条记录,比如分析网站用户的停留时长分布,或者工厂生产零件的尺寸误差分布。

场景:分析学生成绩

让我们假设我们要分析一个班级 50 名学生的数学成绩,并绘制“小于”累积频率曲线来查看成绩分布。

import numpy as np
import matplotlib.pyplot as plt

# 设置随机种子以保证结果可复现
np.random.seed(42)

# 模拟生成 50 个学生的成绩,范围在 0 到 100 之间
scores = np.random.randint(0, 101, 50)

# 定义分组区间
bins = [0, 20, 40, 60, 80, 100]

# 使用 numpy.histogram 计算频率分布
# hist: 各区间的频率数量
# bin_edges: 区间的边界
hist, bin_edges = np.histogram(scores, bins=bins)

# 计算累积频率
cumulative_freq = np.cumsum(hist)

# 获取区间的上限作为 X 轴
# bin_edges 包含所有边界,我们取从第二个元素开始的所有边界作为上限
upper_limits = bin_edges[1:]

print(f"成绩分数段分布: {hist}")
print(f"累积频数: {cumulative_freq}")

# 绘制专业的图表
plt.figure(figsize=(12, 7))

# 绘制平滑曲线(使用更细致的画笔风格)
plt.plot(upper_limits, cumulative_freq, 
         marker=‘D‘, 
         linestyle=‘-‘, 
         color=‘#2c3e50‘, 
         linewidth=2, 
         markersize=8, 
         label=‘累积频率曲线‘)

# 填充曲线下方区域,增加视觉效果
plt.fill_between(upper_limits, cumulative_freq, color=‘#3498db‘, alpha=0.2)

# 标注具体数值
for x, y in zip(upper_limits, cumulative_freq):
    plt.text(x, y + 1, f‘{y}‘, ha=‘center‘, va=‘bottom‘, fontsize=10)

plt.title(‘班级数学成绩累积频率分布图 (N=50)‘, fontsize=16, pad=20)
plt.xlabel(‘分数段上限‘, fontsize=14)
plt.ylabel(‘累积人数‘, fontsize=14)

# 优化网格和刻度
plt.xticks(bins)
plt.grid(axis=‘y‘, linestyle=‘--‘, alpha=0.7)
plt.legend(fontsize=12)

plt.show()

代码深度解析:

  • 数据模拟:我们用 numpy 生成了模拟数据,这比手动输入列表更贴近真实工作场景。
  • 直方图计算np.histogram 是一个强大的函数,它能自动将杂乱的数据分配到你定义的“桶”里,并计算出每个桶里的数量。
  • 累积求和np.cumsum 是专门用于计算累积和的函数,它比我们之前手写的循环更高效、更简洁。
  • 可视化增强:我们添加了 INLINECODEdc1674d0 来给曲线下方添加半透明颜色,这在做演示时能让图表看起来更专业。同时,我们添加了 INLINECODE24ea01dd 循环,直接在图表上标注具体的累积数值,让读者不用去对着 Y 轴估读。

常见问题与陷阱

在处理累积频率曲线时,作为开发者,你可能会遇到以下几个“坑”

  • X 轴定义模糊

* 对于“小于”曲线,必须使用 上限。如果你错误地使用了下限或中点,曲线的物理意义就会改变,导致无法正确读取分位数。

* 对于“大于”曲线,通常使用 下限

  • 分组不连续

* 如果你的数据分组是 0-10, 20-30 (中间跳过了 10-20),那么画出来的曲线在中间会有一段断裂或水平延伸。在统计上,我们通常建议使用连续的分组(组限相接),或者使用代码进行预处理(如插值),但在基础的累积频率曲线中,我们假设数据是连续分组的。

  • 首点处理

* 严格的“小于”累积频率曲线通常从第一组的下限开始(此时累积频率为0),或者直接从第一组的上限开始。为了美观和数学严谨性,有时我们会人为添加一个点 (第一组下限, 0)

总结与后续步骤

通过这篇文章,我们从零开始,探索了累积频率的数学定义,区分了“小于”和“大于”两种曲线类型,并最终使用 Python 编写了能够处理实际数据的自动化脚本。

核心要点回顾:

  • 累积频率 = 到目前为止的所有频率之和。
  • “小于”曲线:X 轴对应组上限,曲线呈上升趋势,用于求中位数、四分位数。
  • “大于”曲线:X 轴对应组下限,通常呈下降趋势(或随下限增加而减小),用于分析剩余数据。
  • Python 实现:利用 INLINECODEc7f1ccee 和 INLINECODEe5c1af26 可以极大地提高绘图效率和准确性。

给你的建议:

不要仅仅满足于看懂这篇文章。我强烈建议你打开你的 Jupyter Notebook 或 VS Code,找一份你感兴趣的公开数据集(比如 Kaggle 上的数据),试着对其中的一列数值型数据进行分组,并绘制出它的累积频率曲线。当你看到那条优美的曲线在屏幕上呈现出来时,你对数据的理解一定会更上一层楼。

希望这篇文章能帮助你更好地理解统计学中的这一重要工具。如果你在实践过程中有任何问题,欢迎随时回来查阅代码示例。祝你数据分析愉快!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/54283.html
点赞
0.00 平均评分 (0% 分数) - 0