方差和标准差的意义

news2024/10/5 17:39:54

文章目录

  • 案例:箭靶
  • 案例:身高
  • 案例:身高+体重

在此前一篇文章 《算法效果评估:均方根误差(RMSE)/ 标准误差》中,我们介绍了方差/标准差的计算方法,也点出了它们是用来“度量数据离散程度”的一种数学方法,但是对于它们的意义并没有给出更具体和形象的解释。本文,我们把这块内容补上。

一言以蔽之,方差/标准差是用来度量数据离散程度的,或者应该再精确一点说应该是:方差/标准差是用来度量一组数据距离某个中心位置(均值或数学期望)的离散程度的。反之,我们也可以在一些工具中通过设定方差/标准差的大小来生成离散程度不同的数据集,本文,我们就用这种方法来帮助我们理解方差/标准差的意义。

案例:箭靶

先不考虑任何数学知识,我们来看一个再形象不过的示例:枪靶

在这里插入图片描述

上图中蓝色和黄色的点位是两个人的射击成绩,我们把每一个点位的正负值考虑进去,蓝色和黄色的点到中心点的平均距离都为0,因为x,y轴有正负值,多点叠加会相互抵消,虽然实际情况未必会如此精准,但我们完全可以通过造数据的方式来生成一张到靶心的平均距离为0的图。注意:我们这里强调两种颜色的点到中心点的平均距离都为0实际上是在强调:两套样本的均值都是0(确切地说是(x=0,y=0)),也就是说:这些点是均匀地围绕靶心分布的,它反映的是“射击者在瞄准时总是尽量指向靶心”这一趋势,这也符合人们的直观感受。实际上,这里的靶心就是我们常说的“数学期望”,在保持相同数学期望(同一均值)的情况下去对比离散程度(方差)会更严谨也更直观一些。

现在,我们来看一下谁的射击成绩更好?答案是非常确定的:蓝色的成绩更好,不用计算具体的环数,只从视觉上就可以看到:蓝色的点位相比于黄色更加集中在圆心位置,它的离散程度远远小于黄色点位,那么箭靶上的这种点位的离散程度怎么用数据来说明(表征)呢?其实这就是方差/标准差。

案例:身高

由于箭靶的点位是一个由横纵坐标组成的二维数据,比较我们计算方差时使用的一维样本数据还是不太方便直接理解。我们再选一个一维数组来帮助我们理解方差/标准差。

考虑人类的身高数据,这是一个典型的符合正态分布的数据,我们假设正常人的身高集中在以170cm为中心,150cm- 190cm的区间内,则大多数人的身高会集中于170cm上下的区间内,越向两侧延伸(更高或更矮),人数越少。为此,我们可以利用numpy生成两个符合这一正态分布的数据集,但是设置不同的方差,然后观察一下它们的“离散”程度:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline

def gen_heights(sample_scale, sample_size):
    # 以170cm为正态分布的中心点,给定的样本数量和标准差,生成一维数组
    # 注:scale参数是指定的标准差,该值越大,样本越发散,越小,样本越集中
    heights = np.random.normal(loc=170, scale=sample_scale, size=sample_size)
    # print(f"heights variance = {heights.var()}")
    print(f"scale = {sample_scale}, heights standard deviation = {heights.std()}")
    # print(heights)
    # print(heights.shape)

    # 将其转置为二维表结构:n行1列,就是行转列操作,-1在reshape中的含义是:不手动计算这个维度的数量
    # 由numpy自动去计算。这里只需要控制列数=1即可
    heights = heights.reshape(-1, 1)
    # print(heights)
    # print(heights.shape)

    zeros = np.zeros(sample_size)

    # axis=1, 是在水平方向上插入zeros数组,所以效果上就是“扩列”
    # 插入位置是0(在第1个位置上插入),故最终的形式为[[0,a], [0,b], ...]
    heights = np.insert(heights, 0, zeros, axis=1)
    # print(heights)

    return pd.DataFrame(heights, columns=['0','height'])
    
df1 = gen_heights(2, 20)
df2 = gen_heights(6, 20)

# 设置图形属性及布局
plt.style.use('ggplot')
fig1 = plt.figure('身高分布')
axes1 = fig1.subplots(nrows=1, ncols=2)
ax1, ax2 = axes1.ravel()

df1.plot(kind="scatter", color="red", ax=ax1, x="height", y="0", figsize=(12,5), xlim=(150, 190))
df2.plot(kind="scatter", color="green", ax=ax2, x="height", y="0", figsize=(12,5), xlim=(150, 190))

程序输出:

scale = 2, heights standard deviation = 1.8318180277200293
scale = 6, heights standard deviation = 5.444879647398637

在这里插入图片描述

我们先看图片,两图都是随机生成的以170为中心符合正态分布的20个身高数据,从图上发现:图2明显比图1发散(两张图的横纵轴范围一样,无缩放)。同样是20个数据,是什么因素导致两者的离散程度有如此明显的差异呢?其实关键就是他们的“方差”不同。

在程序中,我们特别打印了生成数据的方差值:

  • 第一组数据设定的scale=2,实际生成数据的标准差是1.8
  • 第二组数据设定的scale=6,实际生成数据的标准差是5.4

将标准差和其对应的图形联系在一起,我们就可以很直观地感受到:方差所描述的正是数据的离散程度。

最后,补充解释一下为什么实际生成数据的标准差和通过scale设定的期望标准差有出入,原因是由于数据是随机生成的,很难保证精确的方差值,特别是在数据样本比较少的情况下,如果我们把样本数量从20提高到2000,我们就会发现,实际生成数据的标准差就会稳定在2左右,很少会出现大的波动。

案例:身高+体重

由于单纯的身高数据是一维的数组,他们的稀疏只能在数轴上体现,还是不够直观。我们现在把人的体重数据补充进来,以身高为横轴,体重为纵轴,一个点代表一个人(他的身高和体重),然后再次利用numpy生成这样的二维数组,让身高和体重都服从正态分布,其中身高数据与上例相同,体重数据以60KG为中心点,然后设置不同的标准差,观察它们的离散程度:

def gen_heights_weights(sample_scale, sample_size):
    # 分别生成height和weight的正态分布数据
    heights_weights = np.random.normal(loc=(60,170), scale=sample_scale, size=sample_size)
    print(f"scale = {sample_scale}, heights standard deviation = {heights_weights.std(axis=0)}")
    return pd.DataFrame(heights_weights, columns=['weight','height'])

df3 = gen_heights_weights((2,2),(100,2))
df4 = gen_heights_weights((6,6),(100,2))

# 设置图形属性及布局
plt.style.use('ggplot')
fig2 = plt.figure('身高-体重分布')
axes2 = fig2.subplots(nrows=1, ncols=2)
ax3, ax4 = axes2.ravel()

df3.plot(kind="scatter", color="red", ax=ax3, x="height", y="weight", figsize=(12,5), xlim=(150, 190), ylim=(40, 80))
df4.plot(kind="scatter", color="green", ax=ax4, x="height", y="weight", figsize=(12,5), xlim=(150, 190), ylim=(40, 80))

程序输出:

scale = (2, 2), heights standard deviation = [2.00995395 1.94059452]
scale = (6, 6), heights standard deviation = [6.06434877 5.58389361]

在这里插入图片描述

同样是先观察一下图片,升级为2维数据后,收敛和发散的趋势就更加鲜明了,如果这是枪靶数据,发散和收敛的含义非常清晰。但是由于这两组数据是我们人工制造的,所以数据本身并没有说明价值。只能说左侧的人群受到相同的先天和后天因素的影响,身高和体重较为集中在标准范围内;而右侧的人群由于先天和后天因素都有很大差异(可以假设是从不同地区,不同职业,不同生活习惯等维度选出的),所以身高和体重的差异非常大。


参考

https://www.cnblogs.com/traditional/p/12629050.html

https://www.sharpsightlabs.com/blog/numpy-random-normal/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux系统中wifi驱动的配置与编译实现方法

大家好,今天主要和大家聊一聊,如何使用linux系统中的WIFI驱动完成相应的实验。 目录 第一:WIFI驱动添加与编译方法 第二:将驱动代码添加到linux内核中 第三:配置Linux内核 第四:编译WIFI驱动 第一&…

YOLOv5更换骨干网络之 MobileNetV3

论文地址:https://arxiv.org/abs/1905.02244 代码地址:https://github.com/xiaolai-sqlai/mobilenetv3 我们展示了基于互补搜索技术和新颖架构设计相结合的下一代 MobileNets。MobileNetV3通过结合硬件感知网络架构搜索(NAS)和 N…

MySQL基础篇

MySQL数据库笔记 第一部分 MySQL基础篇 第01章 数据库概述 1. 为什么要使用数据库 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以“…

网络类型实验

1.先配ip [Huawei]sysname R1 [R1]interface GigabitEthernet 0/0/1 [R1-GigabitEthernet0/0/1]ip add 192.168.1.1 24 [R1-GigabitEthernet0/0/1]int s 4/0/0 [R1-Serial4/0/0]ip add 12.1.1.1 24 其他同理 2.写三条缺省指向R2来使网络通 [R1]ip route-static 0.0.0.0 0 12…

【王道操作系统】3.1.1 什么是内存?进程的基本原理,深入指令理解其过程

什么是内存?进程的基本原理,深入指令理解其过程 文章目录什么是内存?进程的基本原理,深入指令理解其过程1.什么是内存?有何作用?2.进程运行的基本原理2.1 指令的工作原理---操作码若干参数2.2 逻辑地址(相对…

C++类和对象3:关于类内部的更多细节

目录 初始化列表: explicit关键字 ​编辑 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化 我们已经接触过了构造函数,其功能可以很方便的帮助我们为变量赋值,但是在这里并不是初始化,因为一个构造函数可以为几…

02 Hadoop概述

Hadoop概述1、Hadoop是什么2、Hadoop版本3、HDFS、YARN、MapReduce(1) HDFS(2)YARN(3)MapReduce(3)Hadoop模块之间的关系1、Hadoop是什么 是一个由Apache基金会开发的分布式系统基础…

动态规划是个好东西:编辑距离

力扣:72. 编辑距离 这道题目让我狠狠的了解了动态规划,这玩意是真强。 题目描述很简单: 这道题正常来说,我们要考虑这个字符怎么换,长度不一怎么找…等等问题,但是这样做会发现很困难,显然这是…

Vert.x 核心概念及事件模型

Vert.x是基于事件的,提供一个事件驱动编程模型 使用Vert.x作为服务器时,程序员只要编写事件处理器event handler即可。(当TCP socket有数据时,event handler被创建调用) 另外它还可以在以下几种情况激活: …

反向迭代器

文章目录1. list的反向迭代器2. list的rbegin和rend3. 反向迭代器的实现3.1 复用vector反向迭代器3.2 反向迭代器的变化1. list的反向迭代器 我们先来看一看库里面的list的迭代器是如何写的: 这是list的正向迭代器。 这是list的反向迭代器。 其实大佬们是把正向迭…

【3.1】Eureka注册中心-提供者与消费者/原理分析

【3.1】Eureka-提供者与消费者/原理分析1 提供者与消费者2 服务调用出现的问题3 Eureka的作用3.1 消费者该如何获取服务提供者具体信息?3.2 如果有多个服务提供者,消费者该如何选择?3.3 消费者如何感知服务提供者健康状态?4 总结1…

A. The Enchanted Forest #769 div1

Problem - A - Codeforces 题意&#xff1a; 给你一串序列&#xff0c;任意从什么地方开始&#xff0c;给你k秒时间&#xff0c;让你算最大价值 每一秒时间按顺序你可以做&#xff1a; ①移动到|x-y|<1的地方 ②取走这个位置上所有的数 ③每个位置1 原来是0秒&#x…

opencv-python常用函数解析及参数介绍(七)——边缘检测

边缘检测前言1.基本概念1) 滤波2) 计算梯度3) 非极大值抑制4) 双阈值检测2.opencv中的边缘检测效果展示分析对比3.结尾前言 在之前的文章中我们介绍了使用膨胀和腐蚀、计算图像梯度的方式来获取图像的轮廓&#xff0c;本篇文章将介绍另外一种可以获取图像轮廓的方法——边缘检…

再说原型链

关于原型链&#xff0c;已经被无数次的提起&#xff0c;每次回顾都有新的理解&#xff0c;今天我们再来说说原型链。 我们知道&#xff0c;每一个javascript对象&#xff08;除了null&#xff09;在被创建的时候都会与另一个对象关联起来&#xff0c;这个对象就是我们所说的原型…

【C++进阶】二叉搜索树

文章目录二叉搜索树概念二叉搜索树操作二叉搜索树的实现每个节点的结构插入查找删除二叉搜索树的所有代码(包括测试)版本一版本二test.cpp二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&a…

Linux环境下gdb程序调试

目录gdb介绍进入gdb调试环境指令学习l(list)指令b(break)指令info b指令d指令r(run)指令n(next)指令s(step)指令c(continue)指令bt(breaktrace)指令finish指令p(print)指令display指令undisplay指令until指令disable命令enable命令这篇文章将会介绍gdb以及一些常用的gdb调试指令…

3.移动端百分比布局练习-京东首页

访问地址 https://youthddup.gitee.io/myproject/ 1、项目目录结构 2、注意 &#xff08;1&#xff09;设置视口标签以及引入初始化样式 &#xff08;2&#xff09;二倍精灵图缩放 先把精灵图等比缩放原来的一半 然后再测精灵图位置 代码里background-size置为原来的一半 &a…

typescript 数组操作

使用变量来存储值会带来以下限制&#xff1a; 变量本质上是标量。换言之&#xff0c;一个变量声明变量声明一次只能包含一个。这意味着在程序中存储n个值需要n个变量声明。因此&#xff0c;当需要存储更大的值集合时&#xff0c;使用变量是不可行的。 程序中的变量以随机顺序分…

当下一场数字化的浪潮,正在各行各业深刻上演着

一场数字化的浪潮&#xff0c;正在各行各业深刻上演着。在零售领域&#xff0c;亦不例外。以往&#xff0c;提及零售&#xff0c;我们更多地想到的是&#xff0c;各式各样的电商平台&#xff0c;我们看到的是&#xff0c;各式各样的电商模式&#xff1b;现在&#xff0c;提及零…

测试用例设计-淘宝购物车

测试人员和开发人员产生争执了怎么办&#xff1f; ① 先检查自身&#xff0c;是否BUG描述不清楚 ② 站在用户的角度考虑问题 ③ BUG定级要有理有据 ④ 提高自身的技术能力和业务水平&#xff0c;最好同时提出解决方案。 ⑤ 开发人员不接受时&#xff0c;不要争吵&#xff0c;可…