以面向过程的方式给出《贝叶斯思维:统计建模的Python学习法》——第五章:决策分析代码

背景

《艾伯特贝叶斯思维:统计建模的Python学习法.pdf》以面向对象的方式给出代码,作为了一本介绍统计思想的书,我们只需要了解其逻辑即可(PS:其实是懒得去看书中代码的组织过程),因此,给出读这本书的时候自己写的代码。

简单复述

总结第五章决策分析的处理过程的简单逻辑:

1、基于历史数据得到各选手商品价格的分布,以及选手出价差的分布
2、选手见到商品,猜测一个价格,据下面的过程得到商品真实价格的后验
先验分布:商品历史分布,似然度:由第一步的价差分布给出
后验分布:商品真实价格分布
3、基于游戏规则计算己方出不同价格时的预期收益。
4、出预期收益最大的价格

导入常见模块

# %load "E:\桌面space\临时数据\python\个人自定义模块\ImportFile.py"
# Standard Scientific Import
import numpy as np
import scipy as sp
import pandas as pd
import matplotlib as mpl
from matplotlib import pyplot as plt
from matplotlib.pyplot import plot as plot
import sklearn
import seaborn as sns
import sys
import patsy

# 个人代码测试路径
sys.path.append(r"C:\Users\Administrator\PycharmProjects\QY_TS_Quant")
from QY_plot import *

plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文字体设置-黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
sns.set(font='SimHei',font_scale=1.25,style="ticks",rc={"xtick.major.size": 3, "ytick.major.size": 3})# 解决Seaborn中文显示问题

# Jupyter 默认设置
%matplotlib inline
%config InlineBackend.figure_format="retina"
%config InlineBackend.rc = {"figure.figsize": (7.5,4.5)}
# 多列输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

导入数据

# 本地数据地址
#url_2011 = "./data/showcases.2011.csv"
#url_2012 = "./data/showcases.2012.csv"
# 网络数据地址
url_2011 = "http://thinkbayes.com/showcases.2011.csv"
url_2012 = "http://thinkbayes.com/showcases.2012.csv"
df_2011 = pd.read_csv(url_2011, index_col=0, skiprows=[1,2,5,8]).T.assign(year=2011).reset_index(drop=True)
df_2012 = pd.read_csv(url_2012, index_col=0, skiprows=[1,4,7]).T.assign(year=2012).reset_index(drop=True)
df = df_2011.append(df_2012, ignore_index=True)
df_2011.head()
Showcase 1Showcase 2Bid 1Bid 2Difference 1Difference 2year
0509694542942000340008969114292011
1219013406114000599007901-258392011
23281553186320004500081581862011
34443231428270003800017432-65722011
4242732232018750230005523-6802011
df_2012.head()
Showcase 1Showcase 2Bid 1Bid 2Difference 1Difference 2year
04081162485220004050018811219852012
13125932972100002100021259119722012
241943247553950022500244322552012
324946346652151332000343326652012
4262574863523420350002837136352012

展品价格分布

df.groupby("year").describe().T.assign(minus=lambda x:x.diff(axis=1).iloc[:, -1]).filter(like="Show", axis=0)
year20112012minus
Showcase 1count191.000000122.000000-69.000000
mean29482.73822031578.1721312095.433911
std6713.2056637628.472048915.266384
min19563.00000020869.0000001306.000000
25%24470.50000025684.5000001214.000000
50%28762.00000029402.500000640.500000
75%32740.50000036599.5000003859.000000
max54579.00000058342.0000003763.000000
Showcase 2count191.000000122.000000-69.000000
mean30668.14659731641.868852973.722256
std8003.1037478728.088463724.984716
min18349.00000019290.000000941.000000
25%25310.50000024900.250000-410.250000
50%29460.00000029530.50000070.500000
75%34191.00000035764.0000001573.000000
max71628.00000066996.000000-4632.000000
df.filter(like="Show").describe()
Showcase 1Showcase 2
count313.000000313.000000
mean30299.48881831047.680511
std7145.7054058293.059002
min19563.00000018349.000000
25%24866.00000025264.000000
50%28958.00000029488.000000
75%34428.00000034665.000000
max58342.00000071628.000000
list(filter(lambda x:x.startswith("Show"), df.columns))
['Showcase 1', 'Showcase 2']
fig, axes = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(18, 6))
for i, col in enumerate(filter(lambda x:x.startswith("Show"), df.columns)):
    sns.distplot(df[col], ax=axes[i]);
    axes[i].axvline(30000, c="r");
fig.suptitle("$2011-2012$正确商品价格分布", fontsize=15);
fig.subplots_adjust(wspace=0.05);

在这里插入图片描述

价差分析

# 出价差 = 商品正确价格 - 选手出价
# 猜测差 = 商品正确价格 - 选手猜测价格
# 由于猜测差不可得,以出价差估计,或者认为两者相等
fig, axes = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(18, 6))
for i, col in enumerate(filter(lambda x:x.startswith("Diff"), df.columns)):
#     sns.distplot(df[col], ax=axes[i]);
    axes[i].hist(df[col], cumulative=True)
    axes[i].axvline(0., c="r");
fig.suptitle("$2011-2012$价差分析", fontsize=15);
fig.subplots_adjust(wspace=0.05);

在这里插入图片描述

# 选手一二出价过高过低概率分布 
# diff = 商品正确价格 - 选手出价
# 可以看出diff大于0的概率更高,即选手更倾向于往小了猜
# 这也是规则导致的,如果你的价格高于商品正确价格,你就输了
(df.filter(like="Diff")<0).apply(lambda x:x.value_counts(normalize=True))
Difference 1Difference 2
False0.7539940.709265
True0.2460060.290735

选手一对商品真实价格分析

选手一根据商品信息,预测商品为20000元,再结合历史信息,对商品真实价格的预测过程。

# 以选手一为对象,分析历史数据,可以得到商品最可能价格分布
# PS 这里是概率密度,未归一化
kde = sp.stats.gaussian_kde(df["Showcase 1"])
h = np.linspace(0, 75000, 101)
plt.plot(h, kde.evaluate(h))
[<matplotlib.lines.Line2D at 0x1e2396cb7b8>]

在这里插入图片描述

# 先验商品最可能的价格
# 概率密度,最大的点——PS:这里步长不是1
h[kde.evaluate(h).argmax()]
27750.0
# 先验概率
p_h = kde.evaluate(h)
# 在猜测商品为20000时,似然度,
# 以猜测差分布计算(假设猜测差等于出价差)
p_dh = sp.stats.norm.pdf(h-20000, loc=0, scale=df["Difference 1"].std())
def normlize(z):
    return z/np.sum(z)
# 此计算的商品价格的后验概率分布
p_hd = normlize(p_dh*p_h)
# 展示商品价格的概率分布
plt.plot(h, p_hd, h, normlize(kde.evaluate(h)))
plt.legend(["后验分布","先验分布"])
plt.title("选手一预测价格为20000时,结合历史展品信息与误差分布的后验分布");

在这里插入图片描述

# 选手一预测商品为20000时,商品最有可能的价格
h[p_hd.argmax()]
24000.0
# 后验分布均值
np.sum(p_hd * h)
25103.012921487145

最优报价分析

# 重申游戏规则:
# diff = 商品真实价格 - 出价价格
# 出价比真实价格高,一无所获(diff<0)
# 出价差比对手少,赢得奖品
# 而且,出价价差小于250元赢得对手的奖品(diff<=250)
plt.plot(h, p_hd)
[<matplotlib.lines.Line2D at 0x1e2399a3048>]

在这里插入图片描述

# 计算选手二的出价差分布函数
def cdf(x):
    return np.sum(df["Difference 2"]<x)/len(df)
# 在选手一猜测商品价格为20000时,根据前述以得到已方展品真实价格的分布
# 下面计算,选手一出不同价格时,可能获得的期望收益
return_s = []
for bid in h: #猜价格
    Er = 0.
    for price,prob in zip(h, p_hd): # 真实商品价格 及 概率
        diff = price - bid # 出价差 = 实际价格-猜测价格
        if diff<0: # 猜价过高,失败
            Er += 0
        else:
            probwin_1 = cdf(-1) # 选手二出价小于0 的概率
            probwin_2 = 1 - cdf(diff) # 选手二出价大于diff的概率
            probwin = probwin_1 + probwin_2 # 选手一赢的概率
            if diff<=250:
                 Er += 2*price*prob*probwin
            else:
                 Er += price*prob*probwin
    return_s.append(Er)
# 在选手一猜测商品价格为20000时,根据前述以得到已方展品真实价格的分布
# 下面展示,选手一出不同价格时,可能获得的期望收益
plt.plot(h, return_s)
[<matplotlib.lines.Line2D at 0x1e239e44dd8>]

在这里插入图片描述

# 最大预期收益,及最优出价
max(zip(return_s,h))
(16666.56998160178, 21000.0)
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 贝叶斯定理 1 1.1 条件概率 1 1.2 联合概率 2 1.3 曲奇饼问题 2 1.4 贝叶斯定理 3 1.5 历时诠释 4 1.6 M&M豆问题 5 1.7 Monty Hall难题 6 1.8 讨论 8 第2章 统计计算 9 2.1 分布 9 2.2 曲奇饼问题 10 2.3 贝叶斯框架 11 2.4 Monty Hall难题 12 2.5 封装框架 13 2.6 M&M豆问题 14 2.7 讨论 15 2.8 练习 16 第3章 估计 17 3.1 骰子问题 17 3.2 火车头问题 18 3.3 怎样看待先验概率? 20 3.4 其他先验概率 21 3.5 置信区间 23 3.6 累积分布函数 23 3.7 德军坦克问题 24 3.8 讨论 24 3.9 练习 25 第4章 估计进阶 27 4.1 欧元问题 27 4.2 后验概率的概述 28 4.3 先验概率的湮没 29 4.4 优化 31 4.5 Beta分布 32 4.6 讨论 34 4.7 练习 34 第5章 胜率和加数 37 5.1 胜率 37 5.2 贝叶斯定理的胜率形式 38 5.3 奥利弗的血迹 39 5.4 加数 40 5.5 最大化 42 5.6 混合分布 45 5.7 讨论 47 第6章 决策分析 49 6.1 “正确的价格”问题 49 6.2 先验概率 50 6.3 概率密度函数 50 6.4 PDF的表示 51 6.5 选手建模 53 6.6 似然度 55 6.7 更新 55 6.8 最优出价 57 6.9 讨论 59 第7章 预测 61 7.1 波士顿棕熊队问题 61 7.2 泊松过程 62 7.3 后验 63 7.4 进球分布 64 7.5 获胜的概率 66 7.6 突然死亡则 66 7.7 讨论 68 7.8 练习 69 第8章 观察者的偏差 71 8.1 红线问题 71 8.2 模型 71 8.3 等待时间 73 8.4 预测等待时间 75 8.5 估计到达率 78 8.6 消除不确定性 80 8.7 决策分析 81 8.8 讨论 83 8.9 练习 84 第9章 二维问题 85 9.1 彩弹 85 9.2 Suite对象 85 9.3 三角学 87 9.4 似然度 88 9.5 联合分布 89 9.6 条件分布 90 9.7 置信区间 91 9.8 讨论 93 9.9 练习 94 第10章 贝叶斯近似计算 95 10.1 变异性假说 95 10.2 均值和标准差 96 10.3 更新 98 10.4 CV的后验分布 98 10.5 数据下溢 99 10.6 对数似然 100 10.7 一个小的优化 101 10.8 ABC(近似贝叶斯计算) 102 10.9 估计的可靠性 104 10.10 谁的变异性更大? 105 10.11 讨论 107 10.12 练习 108 第11章 假设检验 109 11.1 回到欧元问题 109 11.2 来一个公平的对比 110 11.3 三角前验 111 11.4 讨论 112 11.5 练习 113 第12章 证据 115 12.1 解读SAT成绩 115 12.2 比例得分SAT 115 12.3 先验 116 12.4 后验 117 12.5 一个更好的模型 119 12.6 校准 121 12.7 效率的后验分布 122 12.8 预测分布 123 12.9 讨论 124 第13章 模拟 127 13.1 肾肿瘤的问题 127 13.2 一个简化模型 128 13.3 更普遍的模型 130 13.4 实现 131 13.5 缓存联合分布 132 13.6 条件分布 133 13.7 序列相关性 135 13.8 讨论 138 第14章 层次化模型 139 14.1 盖革计数器问题 139 14.2 从简单的开始 140 14.3 分层模型 141 14.4 一个小优化 142 14.5 抽取后验 142 14.6 讨论 144 14.7 练习 144 第15章 处理多维问题 145 15.1 脐部细菌 145 15.2 狮子,老虎和熊 145 15.3 分层版本 148 15.4 随机抽样 149 15.5 优化 150 15.6 堆叠的层次结构 151 15.7 另一个问题 153 15.8 还有工作要做 154 15.9 肚脐数据 156 15.10 预测分布 158 15.11 联合后验 161 15.12 覆盖 162 15.13 讨论 164
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值