本文介绍了如何用Python实现几种常见的概率分布模型,包括伯努利分布,二项分布,几何分布,泊松分布,正态分布和幂律分布。
注:想直接看代码的请直接下滑跳过下面这段。
涉及到的统计学知识在这里不做介绍,想了解相关知识的朋友推荐下面的链接进行学习。
这个是网易可汗学院的统计学公开课,涉及的知识包括:随机变量、均值方差标准差、统计图表、概率密度、二项分布、泊松分布、正态分布、大数定律、中心极限定理、样本和抽样分布、参数估计、置信区间、伯努利分布、假设检验和p值、方差分析、回归分析等内容。如果觉得课程太多,可以只看中心极限定理和假设检验,很重要!
伯努利分布(Bernoulli Distribution)
#导入相应的包
import warnings
warnings.filterwarnings
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
'''
arange用于生成一个等差数组,arange(start, stop, step,)
第1步,定义随机变量:明天是否下雨
下雨记录为1,不下雨记录为0
'''
x = np.arange(0,2,1)
x
array([0, 1])
'''
第2步,求对应分布的概率:概率质量函数 (PMF)
它返回一个列表,列表中每个元素表示随机变量中对应值的概率
'''
P = 0.6 #明天下雨的概率
plist = stats.bernoulli.pmf(x,P)
plist
array([0.4, 0.6])
plt.plot(x, plist, marker='o',linestyle='None')
'''
vlines用于绘制竖直线(vertical lines),
参数说明:vline(x坐标值, y坐标最小值, y坐标值最大值)
我们传入的X是一个数组,是给数组中的每个x坐标值绘制竖直线,
竖直线y坐标最小值是0,y坐标值最大值是对应pList中的值
官网文档:https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.vlines
'''
plt.vlines(x, 0, plist)
#x轴文本
plt.xlabel('随机变量:明天是否下雨')
#y轴文本
plt.ylabel('概率')
#标题
plt.title('伯努利分布:p=%.2f'%P)
#显示图形
plt.show()
二项分布(Binomial Distribution)
'''
arange用于生成一个等差数组
第1步,定义随机变量:5次抛硬币,正面朝上的次数
'''
n = 10 # 做某件事情的次数
p2 = 0.5 # 做某件事情成功的概率
x2 = np.arange(0, n+1,1)
x2
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
'''
二项分布官方使用文档:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binom.html#scipy.stats.binom
第2步,求对应分布的概率:概率质量函数 (PMF)
它返回一个列表,列表中每个元素表示随机变量中对应值的概率
'''
plist2 = stats.binom.pmf(x2,n,p2)
plist2
array([0.00097656, 0.00976563, 0.04394531, 0.1171875 , 0.20507813,
0.24609375, 0.20507813, 0.1171875 , 0.04394531, 0.00976563,
0.00097656])
plt.plot(x2, plist2, marker='o',linestyle='None')
'''
vlines用于绘制竖直线(vertical lines),
参数说明:vline(x坐标值, y坐标最小值, y坐标值最大值)
我们传入的X是一个数组,是给数组中的每个x坐标值绘制竖直线,
竖直线y坐标最小值是0,y坐标值最大值是对应pList中的值
官网文档:https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.vlines
'''
plt.vlines(x2, 0, plist2)
#x轴文本
plt.xlabel('随机变量:硬币正面朝上的次数')
#y轴文本
plt.ylabel('概率')
#标题
plt.title('二项分布:n=%i,p=%.2f'%(n,p2))
#显示图形
plt.show()
几何分布(Geometric Distribution)
'''
arange用于生成一个等差数组
第1步,定义随机变量:
首次表白成功的次数,可能是1次,2次,3次等
'''
#第k次做某件事情,才取到第1次成功
#这里我们想知道10次表白成功的概率
k = 10
# 做某件事情成功的概率,这里假设每次表白成功概率都是60%
p3 = 0.6
x3 = np.arange(1, k+1,1)
x3
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
'''
几何分布官方使用文档:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.geom.html#scipy.stats.geom
第2步,求对应分布的概率:概率质量函数 (PMF)
它返回一个列表,列表中每个元素表示随机变量中对应值的概率
分别表示表白第1次才成功的概率,表白第2次才成功的概率····表白第10次才成功的概率
'''
plist3 = stats.geom.pmf(x3,p3)
plist3
array([6.000000e-01, 2.400000e-01, 9.600000e-02, 3.840000e-02,
1.536000e-02, 6.144000e-03, 2.457600e-03, 9.830400e-04,
3.932160e-04, 1.572864e-04])
plt.plot(x3, plist3, marker='o',linestyle='None')
'''
vlines用于绘制竖直线(vertical lines),
参数说明:vline(x坐标值, y坐标最小值, y坐标值最大值)
我们传入的X是一个数组,是给数组中的每个x坐标值绘制竖直线,
竖直线y坐标最小值是0,y坐标值最大值是对应pList中的值
官网文档:https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.vlines
'''
plt.vlines(x3, 0, plist3)
#x轴文本
plt.xlabel('随机变量:表白第k次才首次成功')
#y轴文本
plt.ylabel('概率')
#标题
plt.title('几何分布:p=%.2f'%p3)
#显示图形
plt.show()
泊松分布(Poisson Distribution)
#某十字路口发生事故的概率是每月μ次,一个月发生k次事故的概率是多少
μ = 5 #平均5次
k2 = 6 #发生6次
x4 = np.arange(0,k2+1,1)
x4
array([0, 1, 2, 3, 4, 5, 6])
#求对应分布的概率:概率质量函数 (PMF)
plist4 = stats.poisson.pmf(x4,μ)
plist4
array([0.00673795, 0.03368973, 0.08422434, 0.1403739 , 0.17546737,
0.17546737, 0.14622281])
#概率分布
plt.plot(x4, plist4, marker='o', linestyle='none')
plt.vlines(x4, 0, plist4)
#x轴标题
plt.xlabel('随机变量:某路口发生k次事故')
#y轴标题
plt.ylabel('概率')
#标题
plt.title('泊松分布: 平均值=%.2f' % μ)
#显示图形
plt.show()
正态分布(Normal Distribution)
'''
第1步,定义随机变量:
'''
mu=0 #平均值
sigma= 1 #标准差
x5 = np.arange(-5,5,0.1)
x5
array([-5.00000000e+00, -4.90000000e+00, -4.80000000e+00, -4.70000000e+00,
-4.60000000e+00, -4.50000000e+00, -4.40000000e+00, -4.30000000e+00,
-4.20000000e+00, -4.10000000e+00, -4.00000000e+00, -3.90000000e+00,
-3.80000000e+00, -3.70000000e+00, -3.60000000e+00, -3.50000000e+00,
-3.40000000e+00, -3.30000000e+00, -3.20000000e+00, -3.10000000e+00,
-3.00000000e+00, -2.90000000e+00, -2.80000000e+00, -2.70000000e+00,
-2.60000000e+00, -2.50000000e+00, -2.40000000e+00, -2.30000000e+00,
-2.20000000e+00, -2.10000000e+00, -2.00000000e+00, -1.90000000e+00,
-1.80000000e+00, -1.70000000e+00, -1.60000000e+00, -1.50000000e+00,
-1.40000000e+00, -1.30000000e+00, -1.20000000e+00, -1.10000000e+00,
-1.00000000e+00, -9.00000000e-01, -8.00000000e-01, -7.00000000e-01,
-6.00000000e-01, -5.00000000e-01, -4.00000000e-01, -3.00000000e-01,
-2.00000000e-01, -1.00000000e-01, -1.77635684e-14, 1.00000000e-01,
2.00000000e-01, 3.00000000e-01, 4.00000000e-01, 5.00000000e-01,
6.00000000e-01, 7.00000000e-01, 8.00000000e-01, 9.00000000e-01,
1.00000000e+00, 1.10000000e+00, 1.20000000e+00, 1.30000000e+00,
1.40000000e+00, 1.50000000e+00, 1.60000000e+00, 1.70000000e+00,
1.80000000e+00, 1.90000000e+00, 2.00000000e+00, 2.10000000e+00,
2.20000000e+00, 2.30000000e+00, 2.40000000e+00, 2.50000000e+00,
2.60000000e+00, 2.70000000e+00, 2.80000000e+00, 2.90000000e+00,
3.00000000e+00, 3.10000000e+00, 3.20000000e+00, 3.30000000e+00,
3.40000000e+00, 3.50000000e+00, 3.60000000e+00, 3.70000000e+00,
3.80000000e+00, 3.90000000e+00, 4.00000000e+00, 4.10000000e+00,
4.20000000e+00, 4.30000000e+00, 4.40000000e+00, 4.50000000e+00,
4.60000000e+00, 4.70000000e+00, 4.80000000e+00, 4.90000000e+00])
#第2步,概率密度函数(PDF)
y=stats.norm.pdf(x5,mu,sigma)
#第3步,绘图
plt.plot(x5, y)
#x轴文本
plt.xlabel('随机变量:x')
#y轴文本
plt.ylabel('概率:y')
#标题
plt.title('正态分布:$mu$=%.1f,$sigma^2$=%.1f' % (mu,sigma))
#网格
plt.grid()
#显示图形
plt.show()
幂律分布 Power-Law
'''
第1步,定义随机变量:
'''
a=6
x6 = np.arange(0,1,0.01)
x6
array([0. , 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1 ,
0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2 , 0.21,
0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3 , 0.31, 0.32,
0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4 , 0.41, 0.42, 0.43,
0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5 , 0.51, 0.52, 0.53, 0.54,
0.55, 0.56, 0.57, 0.58, 0.59, 0.6 , 0.61, 0.62, 0.63, 0.64, 0.65,
0.66, 0.67, 0.68, 0.69, 0.7 , 0.71, 0.72, 0.73, 0.74, 0.75, 0.76,
0.77, 0.78, 0.79, 0.8 , 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87,
0.88, 0.89, 0.9 , 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98,
0.99])
y2 = stats.powerlaw.pdf(x6,a)
plt.plot(x6,y2)
plt.xlabel('随机变量:x')
plt.ylabel('概率')
plt.title('幂律分布:指数a=%i'%a)
plt.grid()
plt.show()
随机抽样 numpy实现
'''
抽奖:生成多个随机数
应用案例:从400个用户中随机抽取10个人作为中奖者
'''
for i in range(1,11):
userId=np.random.randint(1,401)
#用%s格式化字符串
print('第 %s 位获奖用户id是 %s' % (i,userId) )
第 1 位获奖用户id是 156
第 2 位获奖用户id是 225
第 3 位获奖用户id是 157
第 4 位获奖用户id是 3
第 5 位获奖用户id是 334
第 6 位获奖用户id是 277
第 7 位获奖用户id是 60
第 8 位获奖用户id是 216
第 9 位获奖用户id是 152
第 10 位获奖用户id是 174
随机抽样 pandas实现
import pandas as pd
'''
arange产生一个含有30个元素的一维数组
reshape:将数组转换成5行6列的二维数组
'''
df = pd.DataFrame(np.arange(30).reshape((5, 6)))
df
#随机选择一个n行的子集
sample1=df.sample(n=2)
sample1