直方图和密度函数——Python实现

概率密度函数是概率论核心概念之一,用于描述连续型随机变量所服从的概率分布,是概率计算的通用表达。研究一个随机变量,不只是要看它能取哪些值,更重要的是它取各种值的概率如何!在实际使用时对应离散化后的频率。也可以这样理解,概率密度函数是数学通用表达的频率,而统计学中的频率是将其离散化后的表达,二者本质上是一致的,所以可用直方图近似理解概率密度函数,我们经常将概率密度函数和直方图画在一起来对照。见下图:

一、概率(稳定的频率)

概率:概率亦称“或然率”。它反映随机事件出现的可能性(likelihood)大小。随机事件是指在相同条件下,可能出现也可能不出现的事件。
例如,从一批有正品和次品的商品中,随意抽取一件,“抽得的是正品”就是一个随机事件。设对某一随机现象进行了n次试验与观察,其中A事件出现了m次,即其出现的频率为m/n。经过大量反复试验,常有m/n越来越接近于某个确定的常数(此论断证明详见伯努利大数定律)。
该常数即为事件A出现的概率,常用P(A)表示。

二、概率密度函数(频率的通用整合)

如果对于随机变量X,X的分布函数F(x),存在非负函数f(x),使对于任意实数x,有F(x)=xf(t)dt,则称X连续型随机变量,其中函数f(x)称为X概率密度函数,简称概率密度
性质

  • f(x)0
  • f(x)dx=1
  • 对于任意实数x1x2 (x1x2),P{x1<Xx2}=F(x2)F(x1)=x1x2f(x)dx
  • f(x)在点x处连续,则有F(x)=f(x)

三、直方图(频率的离散整合)

直方图表示一个变量的值在范围内的频率。直方图类似于条形图,但不同的是它将值分组到连续的范围内。直方图(Histogram)又称柱状图,直方图中的每个条表示该范围中的数值的个数,是由一系列高度不等的纵条纹或线段表示的数据分布情况。可以使用直方图估计数据的概率分布情况。 直方图是数值数据分布的精确图形表示。这是一个连续变量(定量变量)的概率分布的估计,并且被卡尔·皮尔逊(Karl Pearson)首先引入。它是一种条形图。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。这些值通常被指定为连续的,不重叠的变量间隔。间隔必须相邻,并且通常是(但不是必须的)相等的大小。
在绘制直方图时,可使用plt.hist(x)函数。plt.hist()函数有许多参数,可以使用help(plt.hist)【Python拥有强大的帮助体系,使得查找函数用法变得十分便捷。要查找一个函数的用法,可以采用以下方法:使用help()函数:在Python交互式环境中,可以直接调用help()函数,然后在括号内输入要查询的函数名或模块名,如help(print)help(list)。这将显示相关函数或模块的文档字符串,其中包含了用法、参数说明以及示例等信息。使用dir()函数dir()函数可以列出一个对象的所有属性和方法,包括函数。然后,通过查看特定函数的属性和方法列表,可以对其进行研究和了解。在线文档:Python官方网站提供了详尽的文档,包含了各种函数、模块和库的使用说明。通过浏览官方文档,可以获取关于函数用法的详细信息。网址为:https://docs.python.org搜索引擎:使用搜索引擎,比如Google,直接搜索函数名加上"Python"关键词,通常能够找到相关的文档、教程或问答,进而了解函数的用法。】来了解不同参数的作用及其使用方法。

plt.hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype=‘bar’, align=‘mid’, orientation=‘vertical’, rwidth=None, log=False, color=None, label=None, stacked=False)
参数 释义 参数 释义
x 指定要绘制直方图的数据 bins 指定直方图条形的个数
range 指定直方图数据的上下界,默认包含绘图数据的最大值和最小值 normed 是否将直方图的频数转换成频率
weights 该参数可为每一个数据点设置权重 cumulative 是否需要计算累计频数或频率
bottom 可以为直方图的每个条形添加基准线,默认为0 histtype 指定直方图的类型,默认为bar,除此还有’barstacked’, ‘step’, ‘stepfilled’
align 设置条形边界值的对其方式,默认为mid,除此还有’left’和’right’ orientation 设置直方图的摆放方向,默认为垂直方向
rwidth 设置直方图条形宽度的百分比 log 是否需要对绘图数据进行log变换
color 设置直方图的填充色 label 设置直方图的标签,可通过legend展示其图例
stacked 当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放
plt.hist(titanic.Age, # 绘图数据
        bins = 20, # 指定直方图的条形数为20个
        color = 'steelblue', # 指定填充色
        edgecolor = 'k', # 指定直方图的边界色
        label = '直方图' ) #为直方图呈现标签

四、数据分布的密度函数图

自至少 18 世纪以来,直方图一直是流行的可视化选项,部分原因在于它们很容易通过手工生成。现今由于笔记本电脑和手机等日常设备已经具备了广泛的计算能力,我们发现它们越来越多地被密度图取代。在密度图中,我们尝试通过绘制适当的连续曲线来显示数据的基本概率分布,见下图所示。该曲线需要从数据中估计,并且用于该估计过程的最常用方法称为核密度估计。在核密度估计中,我们在每个数据点的位置画一个较小宽度(由一个名为带宽的参数控制)的连续曲线(核),然后我们将所有这些曲线加起来以获得最终密度估计,最广泛使用的核是高斯核(即高斯钟形曲线)。

4.1 核密度估计

核密度估计(kernel density estimation,KDE)是根据已知的一列数据(x1,x2,…xn)估计其密度函数的过程,即寻找这些数的概率分布曲线。密度估计就是给定一列数据,分布未知的情况下估计其密度函数,例如上文的6个数据:c(x1 = −2.1,x2 = −1.3, x3 = −0.4, x4 = 1.9, x5 = 5.1, x6= 6.2),我们看下这列数据的“密度”如何。

画频率直方图就是一种密度估计的方法(如下图,组距为2),这里的“密度”(density)可以感性得理解为一个区间(直方图的组距)内数据数量的多少,右图即为这6个数据的密度曲线(这里简称为密度图),它是左图的外轮廓化,数据量越多,直方图的顶点也越接近一条线。与直方图的情况一样,密度图的确切视觉外观取决于核和带宽选择。带宽参数的行为类似于直方图中的箱宽。如果带宽太小,则密度估计可能变得过于尖锐并且视觉上嘈杂,并且数据中的主要趋势可能被掩盖。另一方面,如果带宽太大,则数据分布中的较小特征可能消失。此外,核的选择会影响密度曲线的形状。

4.2 核密度图的绘制

使用matplotlib模块或pandas模块绘制核密度图都会稍微复杂一些,这里推荐使用seaborn模块中的distplot函数,因为该函数的代码简洁而易懂。该函数的语法和参数含义如下:

sns.distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None,hist_kws=None, kde_kws=None, rug_kws=None, fit_kws=None, color=None, vertical=False, norm_hist=False, axlabel=None,label=None, ax=None)
参数 释义 参数 释义
a 指定绘图数据,可以是序列、一维数组或列表 bins 指定直方图条形的个数
hist bool类型的参数,是否绘制直方图,默认为True kde bool类型的参数,是否绘制核密度图,默认为True
rug bool类型的参数,是否绘制须图(如果数据比较密集,该参数比较有用),默认为False fit 指定一个随机分布对象(需调用scipy模块中的随机分布函数),用于绘制随机分布的概率密度曲线
hist_kws 以字典形式传递直方图的其他修饰属性,如填充色、边框色、宽度等 kde_kws 指以字典形式传递核密度图的其他修饰属性,如线的颜色、线的类型等
rug_kws 以字典形式传递须图的其他修饰属性,如线的颜色、线的宽度等 fit_kws 以字典形式传递概率密度曲线的其他修饰属性,如线条颜色、形状、宽度等
color 指定图形的颜色,除了随机分布曲线的颜色 vertical bool类型的参数,是否将图形垂直显示,默认为True(改为False即为horizontal)
norm_hist bool类型的参数,是否将频数更改为频率,默认为False axlabel 用于显示轴标签。 label:指定图形的图例,需结合plt.legend()一起使用
ax 指定子图的位置

从函数的参数可知,通过该函数,可以实现三种图形的合成,分别是直方图(hist参数)、核密度曲线(kde参数)以及指定的理论分布密度曲线(fit参数)。

sns.kdeplot(x,
            color='#098154',  # Line color
            fill=True,       # Fill area under the curve
            linewidth=1,     # Line width
            linestyle='--'   # Line style
            )

五、直方图和概率密度函数

数据train.zip下载链接,解压后train.csv放入当前路径即可

# 导入第三方包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as stats

# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 读取Titanic数据集
titanic = pd.read_csv('train.csv')
# 检查年龄是否有缺失
any(titanic.Age.isnull())
# 不妨删除含有缺失年龄的观察
titanic.dropna(subset=['Age'], inplace=True)

# 正态分布图
plt.hist(titanic.Age, # 绘图数据
        bins = np.arange(titanic.Age.min(),titanic.Age.max(),5), # 指定直方图的组距
        density = True, # 设置为频率直方图
        color = 'steelblue', # 指定填充色
        edgecolor = 'k') # 指定直方图的边界色

# 设置坐标轴标签和标题
plt.title('乘客年龄直方图')
plt.xlabel('年龄')
plt.ylabel('频率')

# 生成正态曲线的数据
x1 = np.linspace(titanic.Age.min(), titanic.Age.max(), 1000)
normal = stats.norm.pdf(x1, titanic.Age.mean(), titanic.Age.std())
# 绘制正态分布曲线
line1, = plt.plot(x1,normal,'r-', linewidth = 2)

# 生成核密度曲线的数据
kde = stats.gaussian_kde(titanic.Age)
x2 = np.linspace(titanic.Age.min(), titanic.Age.max(), 1000)
# 绘制
line2, = plt.plot(x2,kde(x2),'g-', linewidth = 2)

# 去除图形顶部边界和右边界的刻度
plt.tick_params(top=False, right=False)

# 显示图例
plt.legend([line1, line2],['正态分布曲线','核密度曲线'],loc='best')
# 显示图形
plt.show()

参考文献

  1. python数据可视化[4] matplotlib(直方图)
  2. Python数据可视化的例子——直方图(hist)和核密度曲线(kde)
posted @   郝hai  阅读(1110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示