统计分析是可以帮助人们认清、刻画不确定性的方法。总体是某一特定事物可能发生结果的集合,
随机变量(Random Variable) 则是一个不确定事件结果是数值函数(Function)。也就是说,把不确定事件的结果用数值来表述,即得到随机变量。随机变量又分为
离散型随机变量(Discrete Random Variable) 和
连续型随机变量(Continuous Radom Variable)。
1. 概率与概率分布
概率(Probability)是用于刻画事物不确定性的一种测度(Measure),根据概率的大小,我们可以判断不确定性的高低。
1.1离散型随机变量
1.1.1概率质量函数(PMF)
假设X是一个离散型随机变量,其所有可能取值为集合{ak},k=1,2,…,我们定义X的概率质量函数(Probability Mass Function) 为:
概率质量函数可以量化地表达随机变量X取每个数值可能性的大小
1.1.2 累计分布密度函数(CDF)
对于离散型随机变量,累计分布函数可以用概率质量函数累加来获得:
1.1.3 Python的实现
在Python中我们可以通过Numpy包的random模块中的choice()函数来生成服从待定的概率质量函数的随机数。
choice()函数:
- choice(a, size=None, replace=True, p=None)
参数a: 随机变量可能的取值序列。
参数size: 我们要生成随机数数组的大小。
参数replace: 决定了生成随机数时是否是有放回的。
参数p:为一个与x等长的向量,指定了每种结果出现的可能性。
计算频数分布使用value_counts()函数
# 以数组形式
import numpy as np
import pandas as pd
RandomNumber=np.random.choice([1,2,3,4,5],\
size=100, replace=True,\
p=[0.1,0.1,0.3,0.3,0.2])
pd.Series(RandomNumber).value_counts() # 计算频数分布value_counts()函数
pd.Series(RandomNumber).value_counts()/100 #计算概率分布
结果呈现:
- 增大size参数,即生成随机数的数目,得到的结果则会更接近设定的概率。
1.2 连续型随机变量
若随机变量X是连续的,我们则不再能通过概率质量函数来刻画随机变量只随机性,对任意ak都有
P{X=ak}=0。
连续型随机变量没有PMF。对于连续型随机变量,累积分布函数
(Probability Density Function)(PDF),X的取值落在某个区间的概
率可以用概率密度函数在这个区间上的积分来求得。
算法逻辑:
- 使用stats模块kde包中的gaussian_kde()可以估计数据的概率密度,在其中传入我们要统计的Series类型的变量名即可,得到的是一个“scipy.stats.kde.gaussian_kde”类型的对象,我们暂先给其命名为density。
- 然后设定好分割区间,设为数组格式,暂将该对象命名为bins。
- 注意,这次与以往绘图不同,这次是以研究的对象数据为行进行绘图。
- 使用上边得到的数据类型density,以 density(bins)格式的语法可以得到一个以设定的分割区间为界限的概率密度数组,让将density(bins)这个对象作为行传入plot即可。
- 如果要绘制累计分布函数图,则只需在上边的density(bins)对象后再调用一下cumsum()函数,对数组数据进行累加后在传入即可。
以2020年沪深300指数(399300.SZ)的收益率(日涨跌幅)数据为例:
# 调取数据
import numpy as np
import tushare as ts
import pandas as pd
token = 'Your Token' # 输入你的接口密匙,获取方式及相关权限见Tushare官网。
pro = ts.pro_api(token)
df = pro.index_daily(ts_code='399300.SZ')
df['trade_date'] = pd.to_datetime(df['trade_date'])
df.set_index(['trade_date'], inplace=True) # 将日期列作为行索引
df = df.sort_index()
# 实现概率分布
import matplotlib.pyplot as plt
from scipy import stats
density = stats.kde.gaussian_kde(df.pct_chg['2020']) #研究数据格式化
bins=np.arange(-5,5,0.02) # 设定分割区间
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(211)
plt.plot(bins,density(bins))
plt.title('沪深300指数2020年收益率序列概率密度曲线图')
plt.subplot(212)
plt.plot(bins,density(bins).cumsum())
plt.title('沪深300指数2020年收益率序列累积分布函数图')
plt.show()
结果展示如下:
2. 期望值与方差
可以用样本数据的平均值来刻画样本的中心位置,期望(Expectation)是随机变量所有可能取的结果的均值,用来呈现总体的中心位置。对于离散型随机变量,期望是该随机变量所有可能结果的取值与其概率的乘积之和:
方差(Variance)则是:
对于一类特殊的离散型随机变量:伯努利(Bernoulli Random Variable)随机变量,伯努利随机变量X只能取到两个值,0或者1,对应的概率质量函数为:
随机变量可能的取值有很多(比如连续型随机变量的取值为无穷),但其观测值(实际值)个数有限,因此现实中随机变量的概率分布、期望、方差等特征值通常是不可知的,推断统计就是透过其观测值的集合——样本数据来刻画这些特征的。
3. 二项分布
3.1二项分布概述及其与伯努利分布的差别
研究伯努利分布时,我们关注的期望是进行一次试验结果的期望值,这样的结果有两种情况,所以伯努利分布也称“两点分布”。
而研究二项分布时,我们关注的是n次试验的结果,这样的结果有多种组合。
为直观说明,假设二点分布结果0的概率为0.4,结果为1的概率为0.6;
二项分布结果为0的概率为0.4,结果为1的概率为0.6,且进行十次。
则:
n = 10
p1 = 0.6
p2 = 0.6
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(221)
plt.bar(['0','1'], [1-p1,p1], width=0.5)
plt.title("二点分布PMF")
plt.subplot(222)
plt.plot(['0','0','1','1',' '], [0, 0.4, 0.4, 1.0,1.0])
plt.title("二点分布CDF")
plt.subplot(223)
b = [stats.binom.pmf(i,10,0.6) for i in range(0,11)]
plt.bar([str(i) for i in range(0,n+1)],b)
plt.title('二项分布PMF')
plt.subplot(224)
plt.title("二项分布CDF")
c = [str(i//2) for i in range(0,2*(n+1))]
c.append('')
d = [stats.binom.cdf(i//2,10,0.6) for i in range(0,22)]
d.insert(0,0)
plt.plot(c,d)
plt.show()
展示结果:
当np≥10,n(1-p)≥10都满足时,二项分布可以近似为正态分布。
3.2 Numpy生成二项分布随机数
在Numpy库中可以使用binomial()函数来生成二项分布随机数。
形式为:binomial(n, p, size=None)
参数n是进行伯努利试验的次数,参数p是伯努利变量取值为1的概率,size是生成随机数的数量。
np.random.binomial(100, 0.5, 20)
3.3 二项分布的PMF与CDF
3.3.1 PMF及其图像绘制
# 求100次试验,20次成功的概率,p=0.5
stats.binom.pmf(20,100,0.5)
# 求100次试验,50次成功的概率,p=0.5
stats.binom.pmf(50,100,0.5)
图像绘制
#传入时n+1是因为10次实验有十一种可能的结果组合。
n=10 # 十次试验
p=0.5
plt.rcParams['font.sans-serif'] = ['SimHei']
b = [stats.binom.pmf(i, n, p) for i in range(0,n+1)]
plt.bar([str(i) for i in range(0,len(b))],b)
plt.title('X~B({},{})二项分布PMF'.format(n,p))
plt.show()
3.3.2 CDF及其图像绘制
可以直接用pmf()函数解决这个问题。
#stats.binom.pmf函数很神奇,传入的第一个参数是数字(指定伯努利试验成功的次数),生成结果就也是一个数字。如果传入的第一个参数是数组,则会将会以该数组的shape输出其中每个数字成功次数的条件下,对应的概率。
dd = stats.binom.pmf(np.arange(0, 21, 1), 100, 0.5)
dd
# 然后对数组求和即求出小于等于20次发生这一事件的概率
dd.sum()
此外,也可以用binom中的cdf()函数来直接解决这个问题
# 依然100次试验成功20次,每次p=0.5
stats.binom.cdf(20,100,0.5)
图像绘制
n=10 # 十次试验
p=0.5
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('X~B({},{})二项分布CDF'.format(n,p))
c = [str(i//2) for i in range(0, 2*(n+1))]
c.append('')
d = [stats.binom.cdf(i//2, n, p) for i in range(0, 22)]
d.insert(0,0)
plt.plot(c,d)
plt.show()
3.3.3 二项分布在金融市场的应用
二项分布常常用于描述金融市场中只有两个结果的重复事件。
如研究平安银行股票2020年数据:
# 导入相关模块
import numpy as np
import tushare as ts
import pandas as pd
from scipy import stats
# 设定好接口 注意这句不能照抄,需要输入自己的接口密匙
token = 'Your token' # 输入你的接口密匙,获取方式及相关权限见Tushare官网。
pro = ts.pro_api(token)
# 获取数据
df = pro.daily(ts_code='000001.SZ') # daily为tushare的股票日线数据接口。
df['trade_date'] = pd.to_datetime(df['trade_date'])
df.set_index(['trade_date'], inplace=True) # 将日期列作为行索引
df = df.sort_index()
ret = df.pct_chg['2020']
# 估算平安银行股价上涨的概率
p = len(ret[ret > 0]) / len(ret)
print(p)
# 估计十个交易日中,平安银行有六个交易日上涨的概率
prob = stats.binom.pmf(6,10,p)
print(prob)