在处理数据分析和统计学的过程中,我们经常需要面对海量的原始数据。盯着满屏的数字表格,不仅让人眼花缭乱,而且很难快速发现数据背后的规律。这时候,可视化图表就成了我们手中的利器。通过图表,我们可以直观地看到数据的分布趋势、中心位置以及离散程度。
在今天的这篇文章中,我们将深入探讨统计学中非常重要的一种图形工具——累积频率曲线(Cumulative Frequency Curve)。无论你是正在学习统计学的学生,还是希望在数据分析项目中更上一层楼的数据科学家,掌握这一技能都将帮助你更高效地理解和展示数据。
我们将从基础概念出发,带你一起理解什么是累积频率,如何手动计算,最终我们将使用 Python 这一强大的工具来自动化绘制这些专业的统计图表。让我们开始这段数据可视化的旅程吧。
什么是频率与累积频率?
在我们深入绘制曲线之前,必须先打好地基。让我们先来理清两个核心概念:频率和累积频率。
频率 指的是在某个特定的区间或类别中,事件发生的次数。比如,在一场考试中,分数在 0-10 分之间的人数是 2 人,这里的“2”就是频率。
而 累积频率 则更有意思,它体现了数据的累积过程。简单来说,它是从第一个区间开始,一直到当前区间的所有频率之和。这就像是我们走上楼梯,每上一层台阶,我们到达的总高度就是之前所有台阶高度加上当前台阶高度的总和。
#### 一个简单的入门示例
让我们看一个非常直观的例子,来手动计算一下累积频率。假设我们有以下一组关于区间分布的数据:
频率
:—
2
4
5在左边的表格中,我们列出了区间和对应的原始频率。现在,我们要计算“累积频率”。请记住这个核心逻辑:当前类别的累积频率 = 之前所有类别的频率之和 + 当前类别的频率。
计算过程如下:
- 区间 (0-10):这是第一个区间,没有之前的频率,所以它的累积频率就是它本身,即 2。
- 区间 (10-20):我们需要加上之前的频率。所以累积频率 = 2 (之前的) + 4 (当前的) = 6。
- 区间 (20-30):继续累加。累积频率 = 2 + 4 (之前的) + 5 (当前的) = 11。
最终,我们得到了如下的 累积频率表:
频率
:—
2
4
5
这种表格形式虽然准确,但还不够直观。为了更高效地展示数据分布,我们就需要引入图形的方法,也就是今天的主角:累积频率曲线,它还有一个学名叫做 卵形线。
累积频率曲线的两种形态
在实际应用中,根据我们分析问题的角度不同,累积频率曲线主要分为两种类型:
- “小于”累积频率曲线:最常用的一种,分析“小于某个数值的数据有多少”。
- “大于”累积频率曲线:用于分析“大于某个数值的数据有多少”。
让我们详细拆解这两种类型,并结合 Python 代码来看看如何在实战中应用它们。
#### 1. “小于”累积频率曲线
这是最标准、最常见的累积频率曲线。它的逻辑是:计算并绘制小于各组上限的数据总个数。
计算逻辑
假设我们有一组新的数据:
频率
:—
2
4
5为了绘制“小于”曲线,我们需要关注区间的 上限,并将频率依次累加。我们来看看计算表:
频率
累积频率
:—
:—
2
2
4
6
5
11
绘图原理
在传统手工绘图中,我们会这样操作:
- 建立坐标系,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. “大于”累积频率曲线
“大于”累积频率曲线的逻辑正好相反。它关心的是:大于某个下限的数据还有多少。这在分析“淘汰率”或“剩余库存”时非常有用。
计算逻辑
在“大于”类型中,我们从最后一个区间开始,倒着向前累加(或者用总数依次减去当前频率)。让我们使用一组稍有不同的数据来演示:
频率
:—
20
4
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。
但在教科书给出的特定示例中,有时为了展示递减规律,会采用“从上往下减”的方式展示,这在视觉上是一条下降的曲线。让我们使用通用的数学定义来编写代码:计算大于或等于下限的累积频率。
频率
对应下限
:—
:—
20
5
4
10
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 上的数据),试着对其中的一列数值型数据进行分组,并绘制出它的累积频率曲线。当你看到那条优美的曲线在屏幕上呈现出来时,你对数据的理解一定会更上一层楼。
希望这篇文章能帮助你更好地理解统计学中的这一重要工具。如果你在实践过程中有任何问题,欢迎随时回来查阅代码示例。祝你数据分析愉快!