上个实例讲解了直方图的制作,本文讲解另一个表示分布的方法——概率质量函数(probability mass function, PMF)。概率质量函数将每个值映射到其概率,概率是频数的分数表示,样本量为n。Hist和Pmf的区别是,Hist将值映射到整型的计数值,Pmf将值映射到浮点型的概率值。

课堂规模悖论

在很多美国大学和学院里,学生与教师的比率约为10:1。但是学生们经常会惊讶地发现自己课上的平均学生数大于10.

造成这一现象的原因有两个:

  • 学生通常每学期修4到5门课,但是教授经常只教1门或2门;
  • 上小课的学生少,但上大课的学生人数非常多。

假设一所学院某学期开了65门课,选课人数分布如下:

size count
5-9 8
10-14 8
15-19 14
20-24 4
25-29 6
30-34 12
35-39 8
40-44 3
45-49 2

每门课平均选课人数为23.7,具体实现代码如下:

import ThinkStats2_PMFd = {7: 8, 12: 8, 17: 14, 22: 4,27: 6, 32: 12, 37: 8, 42: 3, 47: 2}pmf = ThinkStats2_PMF.Pmf(d, label='actual')
print('mean', pmf.Mean())

上面实现的ThinkStats2_PMF具体内容为:

import pandas
import numpy as npfrom collections import Counter
import copy
import loggingclass _DictWrapper(object):#此处代码请参考《统计思维(实例1)》#下面为该类新加代码def __iter__(self):return iter(self.d)#返回keys迭代器def iterkeys(self):return iter(self.d)#返回浅拷贝def Copy(self, label=None):new = copy.copy(self)new.d = copy.copy(self.d)new.label = label if label is not None else self.labelreturn new#计算值和频率乘积def Mult(self, x, factor):self.d[x] = self.d.get(x, 0) * factor#返回Map中频率的总和def Total(self):total = sum(self.d.values())return total#Pmf对象
class Pmf(_DictWrapper):def Prob(self, x, default=0):return self.d.get(x, default)#计算PMF的均值 def Mean(self):mean = 0.0for x, p in self.d.items():mean += p * xreturn mean#PMF的归一化 def Normalize(self, fraction=1.0):if self.log:raise ValueError("Normalize: Pmf is under a log transform")total = self.Total()if total == 0.0:raise ValueError('Normalize: total probability is zero.')factor = fraction / totalfor x in self.d:self.d[x] *= factorreturn total

但如果对一组学生进行调查,询问他们的课堂上有多少学生,然后计算出均值,那么会发现选课人数的平均值比23.7大,具体大多少?

首先,计算出学生观察到的分布,其中每个课堂规模值的概率受到选课的学生人数的“影响”。对每个课堂规模值x,我们将其概率乘以p,即观察该课堂规模的学生人数,最终能得到一个新的Pmf,代表这个偏倚分布。

def BiasPmf(pmf, label):new_pmf = pmf.Copy(label=label)for x, p in pmf.Items():new_pmf.Mult(x, p)new_pmf.Normalize()return new_pmf

现在我们绘制出实际分布和观察到的分布。

biased_pmf = BiasPmf(pmf, label='observed')
ThinkStats2_PMF_Plot.PrePlot(2)
ThinkStats2_PMF_Plot.Pmfs([pmf, biased_pmf])
ThinkStats2_PMF_Plot.Show(xlabel='class size', ylabel='PMF')

上文ThinkStats2_PMF_Plot的具体实现为:

import pandas
import matplotlib.pyplot as plt
import numpy as npimport warnings#封装一套颜色序列
class _Brewer(object):#此处代码请参考《统计思维(实例1)》#此处主要涉及颜色生成及配置设置#下文为新加的代码#绘制线的过程
def Plot(obj, ys=None, style='', **options):options = _UnderrideColor(options)label = getattr(obj, 'label', '_nolegend_')options = _Underride(options, linewidth=3, alpha=0.7, label=label)xs = objif ys is None:if hasattr(obj, 'Render'):xs, ys = obj.Render()if isinstance(obj, pandas.Series):ys = obj.valuesxs = obj.indexif ys is None:plt.plot(xs, style, **options)else:plt.plot(xs, ys, style, **options)#绘制PMF对象
def Pmf(pmf, **options):xs, ys = pmf.Render()low, high = min(xs), max(xs)width = options.pop('width', None)if width is None:try:width = np.diff(xs).min()except TypeError:warnings.warn("Pmf: Can't compute bar width automatically.""Check for non-numeric types in Pmf.""Or try providing width option.")points = []lastx = np.nanlasty = 0for x, y in zip(xs, ys):if (x - lastx) > 1e-5:points.append((lastx, 0))points.append((x, 0))points.append((x, lasty))points.append((x, y))points.append((x+width, y))lastx = x + widthlasty = ypoints.append((lastx, 0))pxs, pys = zip(*points)align = options.pop('align', 'center')if align == 'center':pxs = np.array(pxs) - width/2.0if align == 'right':pxs = np.array(pxs) - widthoptions = _Underride(options, label=pmf.label)Plot(pxs, pys, **options)#绘制一系列PMF
def Pmfs(pmfs, **options):for pmf in pmfs:Pmf(pmf, **options)#绘制前的准备
#数据量、行列数
def PrePlot(num=None, rows=None, cols=None):if num:_Brewer.InitIter(num)if rows is None and cols is None:returnif rows is not None and cols is None:cols = 1if cols is not None and rows is None:rows = 1# resize the image, depending on the number of rows and colssize_map = {(1, 1): (8, 6),(1, 2): (12, 6),(1, 3): (12, 6),(1, 4): (12, 5),(1, 5): (12, 4),(2, 2): (10, 10),(2, 3): (16, 10),(3, 1): (8, 10),(4, 1): (8, 12),}if (rows, cols) in size_map:fig = plt.gcf()fig.set_size_inches(*size_map[rows, cols])# create the first subplotif rows > 1 or cols > 1:ax = plt.subplot(rows, cols, 1)global SUBPLOT_ROWS, SUBPLOT_COLSSUBPLOT_ROWS = rowsSUBPLOT_COLS = colselse:ax = plt.gca()return ax

在偏倚分布中,小课更少,大课更多。偏倚分布的均值为29.1,比实际的均值高出约25%。


PMF适用于变量值数量较少的情况。但随着值的数量增加,每个值对应得概率会变得越来越小,随机噪声的影响就会变大。

避免上述问题的一个方法就是使用累积分布函数(cumulative distribution function, CDF),在此之前,需要了解百分位数。

百分位秩以一个值为参数,计算这个值在一组值中的百分位秩;百分位数以一个百分位秩为参数,计算对应得值。

CDF是x的函数,其中x是可能出现在分布中的任意值。要获得某个特定值x的CDF(x),需要计算出小于或等于x的值在此分布中所占的比例。

下面代码中的函数参数为一个序列t和一个值x,这个函数的结果为0到1的概率。

def EvalCdf(t, x):count = 0.0for value in t:if value <= x:count +=1prob = count / len(t)return prob

在进行分布比较时,CDF尤为有用。下面代码绘制了第一胎和其他胎新生儿体重的CDF。

import ThinkStats2_Hist
import ThinkStats2_CDF
import ThinkStats2_CDF_Plotfirst_cdf = ThinkStats2_CDF.Cdf(ThinkStats2_Hist.firsts.totalwgt_lb, label='first')
other_cdf = ThinkStats2_CDF.Cdf(ThinkStats2_Hist.others.totalwgt_lb, label='other')
ThinkStats2_CDF_Plot.PrePlot(2)
ThinkStats2_CDF_Plot.Cdfs([first_cdf, other_cdf])
ThinkStats2_CDF_Plot.Show(xlabel='weight (pounds)', ylabel='CDF')

ThinkStats2_CDF的具体实现为:

import pandas
import numpy as npfrom collections import Counter
import copy
import loggingclass _DictWrapper(object):#此处实现请参考上文ThinkStats2_PMF的对应代码import ThinkStats2_Hist
#计算累积分布函数
class Cdf(object):def __init__(self, obj=None, ps=None, label=None):self.label = label if label is not None else '_nolegend_'if isinstance(obj, (_DictWrapper, Cdf)):if not label:self.label = label if label is not None else obj.labelif obj is None:# 未提供对象,创建空CDFself.xs = np.asarray([])self.ps = np.asarray([])if ps is not None:logging.warning("Cdf: can't pass ps without also passing xs.")returnelse:#如果传入xs/ps,存储起来          if ps is not None:if isinstance(ps, str):logging.warning("Cdf: ps can't be a string")self.xs = np.asarray(obj)self.ps = np.asarray(ps)returnif isinstance(obj, Cdf):self.xs = copy.copy(obj.xs)self.ps = copy.copy(obj.ps)returnif isinstance(obj, _DictWrapper):dw = objelse:dw = ThinkStats2_Hist.HistO(obj)if len(dw) == 0:self.xs = np.asarray([])self.ps = np.asarray([])returnxs, freqs = zip(*sorted(dw.Items()))self.xs = np.asarray(xs)self.ps = np.cumsum(freqs, dtype=np.float)self.ps /= self.ps[-1]#返回拷贝的对象def Copy(self, label=None):if label is None:label = self.labelreturn Cdf(list(self.xs), list(self.ps), label=label)def MakePmf(self, label=None):if label is None:label = self.labelreturn Pmf(self, label=label)def Values(self):return self.xsdef Items(self):a = self.psb = np.roll(a, 1)b[0] = 0return zip(self.xs, a-b)#生成可绘制的一系列点def Render(self, **options):def interleave(a, b):c = np.empty(a.shape[0] + b.shape[0])c[::2] = ac[1::2] = breturn ca = np.array(self.xs)xs = interleave(a, a)shift_ps = np.roll(self.ps, 1)shift_ps[0] = 0ps = interleave(shift_ps, self.ps)return xs, ps

ThinkStats2_CDF_Plot的具体实现为:

import pandas
import matplotlib.pyplot as plt
import numpy as npimport warnings#此处实现请参考上文ThinkStats2_PMF_Plot的对应代码import math
#将CDF绘制成线
def Cdf(cdf, complement=False, transform=None, **options):xs, ps = cdf.Render()xs = np.asarray(xs)ps = np.asarray(ps)scale = dict(xscale='linear', yscale='linear')for s in ['xscale', 'yscale']: if s in options:scale[s] = options.pop(s)if transform == 'exponential':complement = Truescale['yscale'] = 'log'if transform == 'pareto':complement = Truescale['yscale'] = 'log'scale['xscale'] = 'log'if complement:ps = [1.0-p for p in ps]if transform == 'weibull':xs = np.delete(xs, -1)ps = np.delete(ps, -1)ps = [-math.log(1.0-p) for p in ps]scale['xscale'] = 'log'scale['yscale'] = 'log'if transform == 'gumbel':xs = np.delete(xs, 0)ps = np.delete(ps, 0)ps = [-math.log(p) for p in ps]scale['yscale'] = 'log'options = _Underride(options, label=cdf.label)Plot(xs, ps, **options)return scaledef Cdfs(cdfs, complement=False, transform=None, **options):for cdf in cdfs:Cdf(cdf, complement, transform, **options)

下图更清晰地展示了分布的形状以及分布之间的差异。从图中可以看出,第一胎新生儿普遍体重较轻,而且大于均值时差异更为明显。

参考文献:

统计思维. Allen B.Downey. 金迎 译

统计思维(实例2)——概率质量函数与累积分布函数相关推荐

  1. 【机器学习】【ICA-1】概率统计/代数知识详解:高斯分布、概率密度函数、累积分布函数、联合分布函数、复合函数的概率密度函数、行列式求导等

    要容易理解ICA,就需要先好好理解透彻下面这些概率统计和线性代数的知识点:高斯分布.概率密度函数.累积分布函数.复合函数的概率密度函数.行列式.代数余子式.矩阵微积分等.下面一一简单记录和复习下这些概 ...

  2. 标准正态分布的概率密度函数和累积分布函数

    标准正态分布概率密度函数: 累积分布函数: 图像:

  3. 概率质量函数,概率密度函数,累积分布函数的区别

    概率质量函数( probability mass function,PMF)是离散随机变量在各特定取值上的概率. 概率密度函数( probability density function,PDF)是对 ...

  4. MATLAB概率密度函数和累积分布函数指令

    概率密度函数 函数名 对应分布的概率密度函数 betapdf 贝塔分布的概率密度函数 binopdf 二项分布的概率密度函数 chi2pdf 卡方分布的概率密度函数 exppdf 指数分布的概率密度函 ...

  5. 概率质量函数(PMF)、概率密度函数(PDF)、累积分布函数(CDF)

    1.概率分布函数(Probability Distribution Functions) 笔记来源:Probability Distribution Functions (PMF, PDF, CDF) ...

  6. python实现概率论与数理统计_《统计思维:程序员数学之概率统计》读书笔记

    更多 1.书籍信息 书名:Think Stats: Probability and Statistics for Programmers 译名:<统计思维:程序员数学之概率统计> 作者:A ...

  7. 《统计思维:程序员数学之概率统计》学习笔记 Chap.1-2

    最近在阅读Allen B. Downey所著的<统计思维:程序员数学之概率统计>,由于文章中大部分的函数操作都是基于作者自己写的模块thinkstats2,为了能够使用常用python库来 ...

  8. 概率质量函数(PMF)、概率密度函数(PDF)和累积分布函数(CDF)定义

    定义 概率质量函数(probability mass function,PMF) 概率密度函数(probability density function,PDF) 累积分布函数(Cumulative ...

  9. 叶丙成-概率-chapter4-随机变量-累积分布函数CDF-概率质量函数PMF-伯努利分布-二项分布-均匀分布

    国立台湾大学叶丙成<机率>课程学习-chapter4-随机变量-累积分布函数CDF-概率质量函数PMF-伯努利分布-二项分布-均匀分布 4.1 随机变量 4.1.1 随机变量(random ...

最新文章

  1. 20个纯css3写的logo
  2. JVM中的Stack和Heap1
  3. 【转】ora-00031:session marked for kill处理oracle中杀不掉的锁
  4. 【Latext】上标下标 ( 右侧上标下标 | 任意字符的正上标记 | 任意字符的正下标记 | 常用数学符号的上标和下标 | 加和 | 乘积 | 交集 | 并集 | 上积 | 极限 | 上弧 )
  5. 字符串大小写互换方法
  6. RabbitMQ延时队列原理讲解
  7. WCF入门的了解准备工作
  8. 玩转mini2440开发板之【tekkamanninja版的u-boot的编译和烧录】
  9. 服务器虚拟化svc,SVC的虚拟化变革
  10. Minio 报错bucket name does not follow Amazon S3 standards
  11. 微信开发经常会用到的一些方法
  12. Debian GNU/kFreeBSD是什么
  13. jquery easyui datagrid 获取Checked选择行(勾选行)数据
  14. 网上招生报名系统V1.0发布
  15. 数据采集之登录那些事
  16. c语言代码 txt下载,贪吃蛇C语言代码.txt
  17. 《汉魏风云》2、孙吴兵法第一传人——辛苦的天才曹操
  18. 基于Java语言的51单片机串口通讯PC机程序
  19. 乔巴机器人 番外篇_超神学院之暮光之眼
  20. 非聚集索引中的临界点(Tipping Point)

热门文章

  1. 粗糙集的上、下近似与定积分之间的关系
  2. 洗礼灵魂,修炼python(9)--灵性的字符串
  3. 高小青:Impala在神策实时分析引擎中的落地与优化
  4. 装箱问题(20 分)
  5. 【React工作记录三十七】react常见的http网络请求
  6. 重温微积分1|散度定理的证明
  7. (智力题)有7克、2克砝码各一个,天平一只,如何只用这些物品三次将140克的盐分成50、90克各一份?
  8. 2018年终总结之一:你的公司是否需要自建一套基于H5活动的SAAS系统
  9. 传统集卡变成无人驾驶,需要做出哪些改变
  10. 基础TypeScript(一)