概率密度函数是概率论核心概念之一,用于描述连续型随机变量所服从的概率分布,是概率计算的通用表达。研究一个随机变量,不只是要看它能取哪些值,更重要的是它取各种值的概率如何!在实际使用时对应离散化后的频率。也可以这样理解,概率密度函数是数学通用表达的频率,而统计学中的频率是将其离散化后的表达,二者本质上是一致的,所以可用直方图近似理解概率密度函数,我们经常将概率密度函数和直方图画在一起来对照。见下图:
一、概率(稳定的频率)
概率:概率亦称“或然率”。它反映随机事件出现的可能性(likelihood)大小。随机事件是指在相同条件下,可能出现也可能不出现的事件。
例如,从一批有正品和次品的商品中,随意抽取一件,“抽得的是正品”就是一个随机事件。设对某一随机现象进行了n次试验与观察,其中A事件出现了m次,即其出现的频率为m/n。经过大量反复试验,常有m/n越来越接近于某个确定的常数(此论断证明详见伯努利大数定律)。
该常数即为事件A出现的概率,常用$P (A) $表示。
二、概率密度函数(频率的通用整合)
如果对于随机变量\(X\),\(X\)的分布函数\(F(x)\),存在非负函数\(f(x)\),使对于任意实数\(x\),有\(F(x)=\int_{-\infty}^xf(t)dt\),则称\(X\)为连续型随机变量,其中函数\(f(x)\)称为\(X\)的概率密度函数,简称概率密度。
性质
- $ f(x)\ge0 $
- $ \int_{-\infty}^\infty f(x)dx=1$
- 对于任意实数\(x_1\),\(x_2\) (\(x_1\) ≤\(x_2\)),$ P\{x_1<X\le x_2\}=F(x_2)-F(x_1)=\int_{x_1}^{x_2}f(x)dx$
- 若\(f(x)\)在点\(x\)处连续,则有\(F′(x)=f(x)\)
三、直方图(频率的离散整合)
直方图表示一个变量的值在范围内的频率。直方图类似于条形图,但不同的是它将值分组到连续的范围内。直方图(Histogram)又称柱状图,直方图中的每个条表示该范围中的数值的个数,是由一系列高度不等的纵条纹或线段表示的数据分布情况。可以使用直方图估计数据的概率分布情况。 直方图是数值数据分布的精确图形表示。这是一个连续变量(定量变量)的概率分布的估计,并且被卡尔·皮尔逊(Karl Pearson)首先引入。它是一种条形图。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。这些值通常被指定为连续的,不重叠的变量间隔。间隔必须相邻,并且通常是(但不是必须的)相等的大小。
在绘制直方图时,可使用hist(x)函数,hist()函数有许多参数,可以使用?hist()来了解不同参数的作用及其使用方法。
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()