计算(分析\画出)给定数据的分布(概率密度函数) | 您所在的位置:网站首页 › stata画概率密度图 › 计算(分析\画出)给定数据的分布(概率密度函数) |
目录 一、背景知识 1.累积分布函数 2.概率密度函数 3.核密度估计 二、画出一组数据的分布(概率密度函数) 1.数据的频率分布直方图 2.画出给定数据的频率分布直方图 3.画出给定数据的概率密度函数 做ML时,往往需要先分析手头的数据,比如数据集中某个特征的分布特性。很多时候,拿到的数据分布不那么尽如人意,比如长尾分布,这时就需要做数据变换(比如box-cox变换),来得到分布特性好的数据(比如正态分布)。 为什么很多模型要假设变量服从正太分布?参考这里 一、背景知识 1.累积分布函数累积分布函数(Cumulative Distribution Function),又叫分布函数,是概率密度函数的积分,能完整描述一个实随机变量X的概率分布。 参考百度百科 2.概率密度函数是累积分布函数的导数: ▲概率密度等于一段区间(事件的取值范围)的概率除以该段区间的长度 ▲概率密度函数在R上的积分为1 ▲几个性质 , , 3.核密度估计核密度估计是在概率论中用来估计未知的概率密度函数,属于非参数检验方法之一。 假设有n个数据a1,a2,…an,互相独立同分布,设其概率密度函数为f(x),则通过核密度估计出来的f(x)为: K()是核函数(非负、积分为1,符合概率密度性质,并且均值为0) h>0为一个平滑参数,称作带宽(bandwidth),也看到有人叫窗口。核密度函数的原理比较简单:在我们知道某一事物的概率分布的情况下,如果某一个数在观察中出现了,我们可以认为这个数的概率密度很大,和这个数比较近的数的概率密度也会比较大,而那些离这个数远的数的概率密度会比较小。 基于这种想法,针对观察中的第一个数,我们可以用K去拟合我们想象中的那个远小近大概率密度。对每一个观察数拟合出的多个概率密度分布函数,取平均。如果某些数是比较重要的,则可以取加权平均。需要说明的一点是,核密度的估计并不是找到真正的分布函数。 如果使用高斯核函数(标准正态分布): (1) 那么估计的密度函数为:(下面式子去掉求和符号以及n之后,就和正态分布的一般形式一样) (2) 以上参考这里 总结一句:核密度估计其实就是通过核函数(如高斯)将每个数据点的数据+带宽当作核函数的参数,得到n个核函数,再线性叠加取平均就形成了核密度的估计函数(参考这里) 计算时,给定核函数,只需要一组数据an和带宽h 二、画出一组数据的分布(概率密度函数) 1.数据的频率分布直方图1.1 定义可查看百度百科,具体例子可参考这里 1.2 各组频率之和的值为1,在频率分布直方图中表现为所有矩形的面积之和等于1 2.画出给定数据的频率分布直方图2.1找到最大值max 最小值min, 将区间[min, max]等分, 得到几个bin(因为是等分, 所以bin的宽度是一样的) 2.2根据点的值大小, 统计落在各个bin中的点的个数, 即频数 2.3计算各个bin的频率=频数/全部数据点的个数 2.4画直方图, 其中bin的高度=频率/bin的宽度 例子: import numpy as np import seaborn as sns import matplotlib.pyplot as plt x = np.arange(10, step=1) n = len(x) print('x= ',x) nbins = 3 freq, bins = np.histogram(x, bins=nbins) print('bin划分:{}, 分成{}个bin'.format(bins, len(bins)-1)) print('各个bin的频数', freq) freq_rate = freq / n print('各个bin的频率', freq_rate) bin_w = bins[1]-bins[0] bin_h = freq_rate / bin_w print('各个bin的高度', bin_h) ax= sns.distplot(x, bins=nbins, hist=True, # Whether to plot a (normed) histogram. kde=False, norm_hist=True, # norm_hist = norm_hist or kde or (fit is not None); 如果为False且kde=False, 则高度为频数 # kde_kws={"label": "density_est_by_sns", # "bw": bin_w} ) ax.grid(True) ax.set_yticks(np.arange(0.16, step=0.01))下面是结果图 x是一组数据,分成了[0,3), [3,6), [6,9)(第三个后面是开区间闭区间?),带宽h=3 3.画出给定数据的概率密度函数假设核函数使用高斯核函数(公式(1)),则密度函数的估计式子就是(公式(2)). 带宽h就是上面频率分布直方图中每个bin的宽度: bin_w 那就可以手动算出这个密度函数了(在density_est中实现) 此外,seaborn的distplot可以直接画出概率密度函数(kde=True, kde_kws是相关的参数) 并且,distplot其实是调用了kdeplot来画图 下面是代码: # -*- coding: utf-8 -*- import numpy as np import seaborn as sns import matplotlib.pyplot as plt x = np.arange(10, step=1) n = len(x) print('x= ',x) nbins = 3 freq, bins = np.histogram(x, bins=nbins) print('bin划分:{}, 分成{}个bin'.format(bins, len(bins)-1)) print('各个bin的频数', freq) freq_rate = freq / n print('各个bin的频率', freq_rate) bin_w = bins[1]-bins[0] bin_h = freq_rate / bin_w print('各个bin的高度', bin_h) # ==================1. 通过distplot ax= sns.distplot(x, bins=nbins, hist=True, # Whether to plot a (normed) histogram. kde=True, norm_hist=True, # norm_hist = norm_hist or kde or (fit is not None); 如果为False且kde=False, 则高度为频数 kde_kws={"label": "density_est_by_sns.distplot", "bw": bin_w # 带宽h, 确保和density_est的h一样, 和kdeplot的bw一样 } ) ax.grid(True) ax.set_yticks(np.arange(0.16, step=0.01)) # ==================2. 通过手动计算density_est def density_est(x, xs, h): """ 给定一组数据xs和带宽h, 计算概率密度函数, x: 是f(x)的自变量 """ f = 0 n=len(xs) # 观测点的个数 a = 1/(np.sqrt(2*np.pi)*n*h) for xi in xs: f = f + np.exp(-(x-xi)**2/(2*(h**2))) f = a*f return f dots = np.linspace(x.min()-bin_w*n*0.5, x.max()+bin_w*n*0.5, num=1000) ax.plot(dots, density_est(dots, x, h=bin_w), c='r', label='density_est_manual') ax.legend(loc='best') # ==================3. 通过kdeplot sns.kdeplot(x, bw=bin_w, ax=ax, label='density_est_by_sns.kdeplot')下面是结果图 可以看出,三种方法画出来的曲线完全重合 最后,整理一下,计算给定数据的概率密度函数(概率分布),需要1数据2核函数3带宽。扩展: 1.qq图,全称quantile-quantile plot,用来 检验一组数据是否服从某一分布 或者 两个分布是否服从同一分布,参考这里和这里 2.scipy的stats.probplot可以画qq图,参考这里,默认参数dist='norm'表示检验给定的数据是否服从正态分布 |
CopyRight 2018-2019 实验室设备网 版权所有 |