中心度量

中心度量

中心度量

analytics 中心度量概述

中心度量是提供数据集中心或典型表示的统计测量。这些度量可以帮助指示数据的主要集中位置,通常被称为数据的集中趋势。数据科学中最常用的中心度量是均值(平均数)中位数众数

school学习目标

完成本节后,您应该能够:

  • 定义并计算数据集的均值、修剪均值、中位数和众数
  • 确定异常值对均值和中位数的影响
  • 使用Python计算数据集的中心度量

calculate 均值和修剪均值

functions 均值

均值(Mean),也称为平均数(Average)或算术平均数(Arithmetic Mean),是最常用的中心度量。计算均值的方法是将数据集中所有项目的值相加,然后除以项目的数量。

lightbulb 均值计算示例

例如,如果您最近三次考试的成绩分别是87、92和73,那么平均成绩为:

均值 = (87 + 92 + 73) / 3 = 252 / 3 = 84

如果您有大量数据值,计算方法也是相同的。例如,要计算50个考试分数的平均值,将50个分数相加,然后除以50。如果50个分数的总和为4,050,那么平均分数为:

均值 = 4,050 / 50 = 81

样本均值与总体均值

在数据科学应用中,您会遇到两种类型的数据集:样本数据总体数据。总体数据代表所有感兴趣的结果或测量值,而样本数据代表从感兴趣总体的子集(或部分)收集的结果或测量值。当然,在许多应用中,从整个总体收集数据是不切实际或不可行的,因此我们通常依赖样本数据。

符号(读作”x-bar”)用于表示样本均值,其中均值是基于从样本中获取的数据计算的。符号∑x表示数据值的总和,n表示样本中的数据值数量,也称为样本大小。样本均值可以使用以下公式计算:

x̄ = ∑x / n

符号μ(读作”mu”)用于表示总体均值,其中均值是基于从整个总体中获取的数据计算的,N表示总体中的数据值数量,也称为总体大小。总体均值可以使用以下公式计算:

μ = ∑x / N

使用频率分布计算均值

均值也可以通过其频率分布来确定。对于数据集中的每个唯一数据值,频率分布给出了该唯一值在数据集中出现的次数或频率。在这种情况下,均值可以通过将每个唯一值乘以其频率,将这些值相加,然后将此总和除以数据值的总数来计算。以下是使用频率分布计算样本均值的相应公式:

x̄ = ∑(x·f) / n

当数据集中的所有值都是唯一的时,这简化为前面给出的样本均值公式。

favorite 临床试验示例

问题:在临床试验期间,对10名患者进行采样,并以每分钟心跳数为单位测量脉搏率:68, 92, 76, 51, 65, 83, 94, 72, 88, 59。计算该样本的平均脉搏率。

解决方案:将10个数据值相加,总和为748。将此总和除以数据值的数量(10):

平均脉搏率 = 748 / 10 = 74.8 次/分钟

content_cut 修剪均值

修剪均值(Trimmed Mean)是一种对异常值不敏感的中心度量。计算修剪均值时,会从数据集的两端(最高值和最低值)移除一定比例的数据值,然后计算剩余数据值的均值。

修剪均值特别适用于存在异常值的数据集,这些异常值可能会使常规均值偏斜。通过移除极端值,修剪均值可以提供更具代表性的中心度量。

修剪均值的计算步骤

  1. 将数据集按升序排序
  2. 确定要修剪的比例(例如,5%、10%等)
  3. 从数据集的两端移除相应比例的数据值
  4. 计算剩余数据值的均值

lightbulb 修剪均值计算示例

考虑以下数据集:5, 8, 12, 15, 18, 22, 25, 30, 35, 100。最后一个值(100)明显是一个异常值。

常规均值 = (5 + 8 + 12 + 15 + 18 + 22 + 25 + 30 + 35 + 100) / 10 = 270 / 10 = 27

现在,让我们计算10%修剪均值(即从两端各移除10%的数据值):

  1. 数据集已排序:5, 8, 12, 15, 18, 22, 25, 30, 35, 100
  2. 10%修剪意味着从两端各移除1个值(因为10 × 10% = 1)
  3. 移除最小值(5)和最大值(100)
  4. 剩余数据集:8, 12, 15, 18, 22, 25, 30, 35
  5. 修剪均值 = (8 + 12 + 15 + 18 + 22 + 25 + 30 + 35) / 8 = 165 / 8 = 20.625

在这个例子中,修剪均值(20.625)比常规均值(27)更能代表数据集的中心,因为它不受异常值100的影响。

swap_vert 中位数

中位数(Median)是另一个常用的中心度量,它表示数据集的中间值。当数据集按升序或降序排列时,中位数是将数据集分成两个相等部分的值。中位数对异常值不敏感,因此当数据集包含异常值时,中位数通常比均值更能代表数据的中心。

中位数的计算方法

中位数的计算方法取决于数据值的数量是奇数还是偶数:

filter_1奇数个数据值

当数据值的数量为奇数时,中位数是排序后数据集的中间值。具体步骤如下:

  1. 将数据集按升序排序
  2. 找到中间位置的值,即第 (n+1)/2 个值,其中 n 是数据值的数量

filter_2偶数个数据值

当数据值的数量为偶数时,中位数是排序后数据集中间两个值的平均值。具体步骤如下:

  1. 将数据集按升序排序
  2. 找到中间两个值,即第 n/2 个值和第 (n/2)+1 个值,其中 n 是数据值的数量
  3. 计算这两个值的平均值

lightbulb 中位数计算示例

示例1(奇数个数据值):考虑以下数据集:5, 8, 12, 15, 18, 22, 25

  1. 数据集已排序:5, 8, 12, 15, 18, 22, 25
  2. 数据值的数量 n = 7(奇数)
  3. 中间位置 = (7+1)/2 = 4
  4. 第4个值是15
  5. 因此,中位数 = 15

示例2(偶数个数据值):考虑以下数据集:5, 8, 12, 15, 18, 22, 25, 30

  1. 数据集已排序:5, 8, 12, 15, 18, 22, 25, 30
  2. 数据值的数量 n = 8(偶数)
  3. 中间两个位置:n/2 = 4 和 (n/2)+1 = 5
  4. 第4个值是15,第5个值是18
  5. 中位数 = (15 + 18) / 2 = 33 / 2 = 16.5

中位数与均值的比较

中位数和均值都是中心度量,但它们有不同的特性和适用场景:

特性 均值 中位数
计算方法 所有值的总和除以值的数量 排序后数据集的中间值
对异常值的敏感性 高敏感度,异常值会显著影响均值 低敏感度,异常值对中位数影响很小
数据分布要求 适用于任何分布 要求数据至少是顺序尺度的
数学特性 具有良好的数学特性,便于进一步统计分析 数学特性不如均值,但更稳健
适用场景 对称分布,无异常值的数据集 偏斜分布,有异常值的数据集

bar_chart 众数

众数(Mode)是数据集中出现频率最高的值。与均值和中位数不同,众数不仅适用于数值数据,还适用于分类数据。一个数据集可以有一个众数(单峰)、两个众数(双峰)或多个众数(多峰),甚至没有众数(当所有值出现的频率相同时)。

众数的计算方法

计算众数的步骤如下:

  1. 统计数据集中每个值出现的频率
  2. 找到出现频率最高的值
  3. 如果有多个值具有相同的最高频率,则这些值都是众数

lightbulb 众数计算示例

示例1(单峰):考虑以下数据集:2, 3, 3, 5, 6, 6, 6, 8, 9

  1. 统计频率:2出现1次,3出现2次,5出现1次,6出现3次,8出现1次,9出现1次
  2. 最高频率是3,对应的值是6
  3. 因此,众数 = 6

示例2(双峰):考虑以下数据集:2, 3, 3, 5, 6, 6, 8, 8, 8

  1. 统计频率:2出现1次,3出现2次,5出现1次,6出现2次,8出现3次
  2. 最高频率是3,对应的值是8
  3. 因此,众数 = 8

示例3(多峰):考虑以下数据集:2, 2, 3, 3, 5, 6, 6, 8, 8

  1. 统计频率:2出现2次,3出现2次,5出现1次,6出现2次,8出现2次
  2. 最高频率是2,对应的值是2、3、6和8
  3. 因此,众数 = 2, 3, 6, 8

众数的特性

check_circle众数的优点

  • 适用于数值数据和分类数据
  • 不受异常值影响
  • 容易理解和解释
  • 可以识别数据集中的常见值或偏好

cancel众数的缺点

  • 可能不存在(当所有值出现的频率相同时)
  • 可能不唯一(可能有多个众数)
  • 不一定代表数据的中心,特别是对于偏斜分布
  • 数学特性不如均值,不便于进一步统计分析

众数的应用场景

众数在以下场景中特别有用:

  • 商业决策:确定最受欢迎的产品或服务
  • 市场研究:识别消费者的偏好和行为模式
  • 质量控制:识别生产过程中最常见的缺陷
  • 教育评估:确定考试中最常见的错误类型

warning 异常值的影响

异常值(Outliers)是数据集中与其他值显著不同的数据值。这些极端值可能会对某些中心度量产生显著影响,特别是均值。了解异常值对不同中心度量的影响对于选择合适的统计指标至关重要。

异常值对均值的影响

均值对异常值非常敏感,因为计算均值时考虑了所有数据值。一个或多个异常值可以显著地将均值拉向异常值的方向,使均值不再代表数据的典型中心。

lightbulb 异常值对均值的影响示例

考虑以下数据集,表示一组员工的年薪(单位:千元):45, 50, 55, 60, 65, 70, 75, 80, 500

最后一个值(500千元)明显是一个异常值,可能代表公司高管。

包含异常值的均值 = (45 + 50 + 55 + 60 + 65 + 70 + 75 + 80 + 500) / 9 = 1000 / 9 ≈ 111.1千元

排除异常值的均值 = (45 + 50 + 55 + 60 + 65 + 70 + 75 + 80) / 8 = 500 / 8 = 62.5千元

在这个例子中,包含异常值的均值(111.1千元)远高于排除异常值的均值(62.5千元),并且不能代表大多数员工的典型年薪。

异常值对中位数的影响

与均值不同,中位数对异常值不敏感,因为它只取决于数据值的排序位置,而不是实际值。除非异常值改变了中间位置的值,否则中位数通常不受异常值的影响。

lightbulb 异常值对中位数的影响示例

使用与上面相同的数据集:45, 50, 55, 60, 65, 70, 75, 80, 500

包含异常值的中位数:数据集已排序,中间值(第5个值)是65千元

排除异常值的中位数:数据集变为45, 50, 55, 60, 65, 70, 75, 80,中间两个值(第4和第5个值)是60和65,中位数 = (60 + 65) / 2 = 62.5千元

在这个例子中,包含异常值的中位数(65千元)与排除异常值的中位数(62.5千元)相差不大,都能较好地代表大多数员工的典型年薪。

异常值对众数的影响

众数对异常值也不敏感,因为它只关注值的出现频率,而不是实际值。除非异常值在数据集中出现多次,否则它不会影响众数。

处理异常值的策略

当数据集中存在异常值时,可以考虑以下策略:

filter_list使用稳健的中心度量

使用对异常值不敏感的中心度量,如中位数或众数,而不是均值。修剪均值也是一个不错的选择,因为它排除了极端值。

delete移除异常值

如果确定异常值是由于测量错误或数据录入错误造成的,可以考虑将其从数据集中移除。然而,这种方法需要谨慎使用,因为异常值可能包含重要信息。

transform数据转换

对数据进行转换,如对数转换、平方根转换等,可以减少异常值的影响。这种方法特别适用于右偏斜的数据。

category分组分析

将数据分成不同的组或子集,然后分别分析每个组。这种方法可以帮助识别异常值是否来自不同的总体或过程。

异常值的检测方法

在决定如何处理异常值之前,首先需要检测它们。以下是一些常用的异常值检测方法:

  • 箱线图法:将位于箱线图上下须之外的数据点视为异常值
  • Z分数法:将Z分数绝对值大于3(或2.5)的数据点视为异常值
  • IQR法:将位于Q1 – 1.5×IQR以下或Q3 + 1.5×IQR以上的数据点视为异常值,其中IQR = Q3 – Q1
  • 可视化方法:使用散点图、直方图等可视化工具识别异常值

code Python实现

Python提供了多种库和函数来计算中心度量,包括NumPy、Pandas和Statistics库。下面我们将展示如何使用这些库计算均值、修剪均值、中位数和众数。

functions 计算均值

Python
# 使用Statistics库计算均值
import statistics

data = [68, 92, 76, 51, 65, 83, 94, 72, 88, 59]
mean = statistics.mean(data)
print(f"均值: {mean}")  # 输出: 均值: 74.8

# 使用NumPy计算均值
import numpy as np

mean = np.mean(data)
print(f"均值: {mean}")  # 输出: 均值: 74.8

# 使用Pandas计算均值
import pandas as pd

s = pd.Series(data)
mean = s.mean()
print(f"均值: {mean}")  # 输出: 均值: 74.8

content_cut 计算修剪均值

Python
# 使用SciPy计算修剪均值
from scipy import stats

data = [5, 8, 12, 15, 18, 22, 25, 30, 35, 100]

# 计算10%修剪均值(从两端各移除10%的数据)
trimmed_mean = stats.trim_mean(data, 0.1)
print(f"10%修剪均值: {trimmed_mean}")  # 输出: 10%修剪均值: 20.625

# 计算20%修剪均值(从两端各移除20%的数据)
trimmed_mean = stats.trim_mean(data, 0.2)
print(f"20%修剪均值: {trimmed_mean}")  # 输出: 20%修剪均值: 19.5

# 手动实现修剪均值函数
def trimmed_mean_manual(data, proportion):
    """
    计算修剪均值
    :param data: 数据列表
    :param proportion: 要修剪的比例(0到1之间)
    :return: 修剪均值
    """
    sorted_data = sorted(data)
    n = len(sorted_data)
    k = int(n * proportion)  # 每端要移除的数据点数量
    
    if k > 0:
        trimmed_data = sorted_data[k:-k]
    else:
        trimmed_data = sorted_data
    
    return sum(trimmed_data) / len(trimmed_data)

# 使用手动实现的函数计算修剪均值
trimmed_mean = trimmed_mean_manual(data, 0.1)
print(f"10%修剪均值: {trimmed_mean}")  # 输出: 10%修剪均值: 20.625

swap_vert 计算中位数

Python
# 使用Statistics库计算中位数
import statistics

data_odd = [5, 8, 12, 15, 18, 22, 25]  # 奇数个数据值
data_even = [5, 8, 12, 15, 18, 22, 25, 30]  # 偶数个数据值

median_odd = statistics.median(data_odd)
median_even = statistics.median(data_even)

print(f"奇数个数据值的中位数: {median_odd}")  # 输出: 奇数个数据值的中位数: 15
print(f"偶数个数据值的中位数: {median_even}")  # 输出: 偶数个数据值的中位数: 16.5

# 使用NumPy计算中位数
import numpy as np

median_odd = np.median(data_odd)
median_even = np.median(data_even)

print(f"奇数个数据值的中位数: {median_odd}")  # 输出: 奇数个数据值的中位数: 15.0
print(f"偶数个数据值的中位数: {median_even}")  # 输出: 偶数个数据值的中位数: 16.5

# 使用Pandas计算中位数
import pandas as pd

s_odd = pd.Series(data_odd)
s_even = pd.Series(data_even)

median_odd = s_odd.median()
median_even = s_even.median()

print(f"奇数个数据值的中位数: {median_odd}")  # 输出: 奇数个数据值的中位数: 15.0
print(f"偶数个数据值的中位数: {median_even}")  # 输出: 偶数个数据值的中位数: 16.5

bar_chart 计算众数

Python
# 使用Statistics库计算众数
import statistics

data_unimodal = [2, 3, 3, 5, 6, 6, 6, 8, 9]  # 单峰
data_bimodal = [2, 2, 3, 3, 5, 6, 6, 8, 8]  # 多峰

mode_unimodal = statistics.mode(data_unimodal)
print(f"单峰数据的众数: {mode_unimodal}")  # 输出: 单峰数据的众数: 6

# 注意:Statistics库的mode函数在多峰情况下会抛出异常
try:
    mode_bimodal = statistics.mode(data_bimodal)
    print(f"多峰数据的众数: {mode_bimodal}")
except statistics.StatisticsError as e:
    print(f"多峰数据的众数: {e}")  # 输出: 多峰数据的众数: no unique mode; found 4 equally common values

# 使用NumPy计算众数
import numpy as np

# 对于单峰数据
values, counts = np.unique(data_unimodal, return_counts=True)
index = np.argmax(counts)
mode_unimodal = values[index]
print(f"单峰数据的众数: {mode_unimodal}")  # 输出: 单峰数据的众数: 6

# 对于多峰数据
values, counts = np.unique(data_bimodal, return_counts=True)
max_count = np.max(counts)
modes = values[counts == max_count]
print(f"多峰数据的众数: {modes}")  # 输出: 多峰数据的众数: [2 3 6 8]

# 使用Pandas计算众数
import pandas as pd

s_unimodal = pd.Series(data_unimodal)
s_bimodal = pd.Series(data_bimodal)

mode_unimodal = s_unimodal.mode()
mode_bimodal = s_bimodal.mode()

print(f"单峰数据的众数: {mode_unimodal.tolist()}")  # 输出: 单峰数据的众数: [6]
print(f"多峰数据的众数: {mode_bimodal.tolist()}")  # 输出: 多峰数据的众数: [2, 3, 6, 8]

warning 异常值检测与处理

Python
# 使用Z分数检测异常值
import numpy as np
from scipy import stats

data = [45, 50, 55, 60, 65, 70, 75, 80, 500]  # 包含异常值的数据

# 计算Z分数
z_scores = np.abs(stats.zscore(data))
threshold = 3  # 通常使用3作为阈值

# 找出异常值
outliers = np.where(z_scores > threshold)[0]
print(f"使用Z分数检测到的异常值索引: {outliers}")  # 输出: 使用Z分数检测到的异常值索引: [8]
print(f"异常值: {[data[i] for i in outliers]}")  # 输出: 异常值: [500]

# 使用IQR方法检测异常值
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

outliers = [i for i, x in enumerate(data) if x < lower_bound or x > upper_bound]
print(f"使用IQR方法检测到的异常值索引: {outliers}")  # 输出: 使用IQR方法检测到的异常值索引: [8]
print(f"异常值: {[data[i] for i in outliers]}")  # 输出: 异常值: [500]

# 使用箱线图可视化异常值
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.boxplot(data)
plt.title("箱线图 - 异常值检测")
plt.ylabel("值")
plt.show()

# 比较包含和排除异常值的中心度量
mean_with_outliers = np.mean(data)
median_with_outliers = np.median(data)

# 移除异常值
data_clean = [x for i, x in enumerate(data) if i not in outliers]
mean_without_outliers = np.mean(data_clean)
median_without_outliers = np.median(data_clean)

print(f"包含异常值的均值: {mean_with_outliers:.2f}")  # 输出: 包含异常值的均值: 111.11
print(f"排除异常值的均值: {mean_without_outliers:.2f}")  # 输出: 排除异常值的均值: 62.50
print(f"包含异常值的中位数: {median_with_outliers:.2f}")  # 输出: 包含异常值的中位数: 65.00
print(f"排除异常值的中位数: {median_without_outliers:.2f}")  # 输出: 排除异常值的中位数: 62.50

insights 综合示例

Python
# 综合示例:计算各种中心度量并比较
import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt

# 创建包含异常值的数据集
np.random.seed(42)
normal_data = np.random.normal(100, 15, 100)  # 均值为100,标准差为15的正态分布
data_with_outliers = np.append(normal_data, [250, 300])  # 添加两个异常值

# 计算各种中心度量
def calculate_central_measures(data):
    """计算并返回各种中心度量"""
    measures = {}
    
    # 均值
    measures['mean'] = np.mean(data)
    
    # 修剪均值(10%修剪)
    measures['trimmed_mean'] = stats.trim_mean(data, 0.1)
    
    # 中位数
    measures['median'] = np.median(data)
    
    # 众数
    values, counts = np.unique(data, return_counts=True)
    max_count = np.max(counts)
    modes = values[counts == max_count]
    measures['mode'] = modes[0] if len(modes) == 1 else modes
    
    return measures

# 计算原始数据和包含异常值的数据的中心度量
measures_normal = calculate_central_measures(normal_data)
measures_with_outliers = calculate_central_measures(data_with_outliers)

# 打印结果
print("原始数据的中心度量:")
for measure, value in measures_normal.items():
    print(f"{measure}: {value:.2f}" if isinstance(value, (int, float)) else f"{measure}: {value}")

print("\n包含异常值的数据的中心度量:")
for measure, value in measures_with_outliers.items():
    print(f"{measure}: {value:.2f}" if isinstance(value, (int, float)) else f"{measure}: {value}")

# 可视化比较
plt.figure(figsize=(15, 6))

# 原始数据的直方图
plt.subplot(1, 2, 1)
plt.hist(normal_data, bins=20, alpha=0.7, color='blue')
plt.axvline(measures_normal['mean'], color='red', linestyle='dashed', linewidth=2, label=f"均值: {measures_normal['mean']:.2f}")
plt.axvline(measures_normal['median'], color='green', linestyle='dashed', linewidth=2, label=f"中位数: {measures_normal['median']:.2f}")
plt.title("原始数据的分布")
plt.xlabel("值")
plt.ylabel("频率")
plt.legend()

# 包含异常值的数据的直方图
plt.subplot(1, 2, 2)
plt.hist(data_with_outliers, bins=20, alpha=0.7, color='blue')
plt.axvline(measures_with_outliers['mean'], color='red', linestyle='dashed', linewidth=2, label=f"均值: {measures_with_outliers['mean']:.2f}")
plt.axvline(measures_with_outliers['median'], color='green', linestyle='dashed', linewidth=2, label=f"中位数: {measures_with_outliers['median']:.2f}")
plt.title("包含异常值的数据的分布")
plt.xlabel("值")
plt.ylabel("频率")
plt.legend()

plt.tight_layout()
plt.show()

# 箱线图比较
plt.figure(figsize=(12, 6))
plt.boxplot([normal_data, data_with_outliers], labels=['原始数据', '包含异常值的数据'])
plt.title("箱线图比较")
plt.ylabel("值")
plt.show()

summarize 总结

中心度量是数据分析中的基本工具,它们提供了数据集的中心或典型表示。在本节中,我们讨论了四种主要的中心度量:均值、修剪均值、中位数和众数。

calculate均值

均值是最常用的中心度量,计算方法是将所有数据值相加然后除以数据值的数量。均值具有良好的数学特性,便于进一步统计分析,但对异常值敏感。

content_cut修剪均值

修剪均值是通过从数据集的两端移除一定比例的数据值后计算得到的均值。修剪均值对异常值不敏感,在存在异常值的情况下可以提供更具代表性的中心度量。

swap_vert中位数

中位数是排序后数据集的中间值。中位数对异常值不敏感,特别适用于偏斜分布或包含异常值的数据集。

bar_chart众数

众数是数据集中出现频率最高的值。众数不仅适用于数值数据,还适用于分类数据,可以识别数据集中的常见值或偏好。

选择合适的中心度量

选择哪种中心度量取决于数据的特性和分析的目的:

场景 推荐的中心度量 原因
对称分布,无异常值 均值 均值充分利用所有数据信息,具有良好的数学特性
偏斜分布,有异常值 中位数 中位数对异常值不敏感,更能代表数据的典型中心
有少量极端异常值 修剪均值 修剪均值排除了极端值,提供了平衡的表示
分类数据或识别常见值 众数 众数适用于分类数据,可以识别最常见的值
需要全面了解数据分布 多种中心度量的组合 不同中心度量提供不同的视角,组合使用可以更全面地理解数据

实际应用中的考虑

在实际应用中,选择中心度量时还应考虑以下因素:

  • 数据质量:数据中是否存在错误、缺失值或异常值
  • 数据类型:数据是数值型、分类型还是顺序型
  • 分析目的:是描述数据、比较组间差异还是预测未来值
  • 受众:结果将呈现给谁,他们对统计概念的理解程度如何

通过理解各种中心度量的特性和适用场景,数据科学家可以选择最合适的统计指标来分析和解释数据,从而得出准确和有意义的结论。

发表评论

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 知差(chai)网 🐾 DeepracticeX 社区 🐾 老薛主机 🐾