1个掷硬币问题,4个Python解法:读书笔记

首发于知乎,再发到阿里社区看看人气如何

关键词:统计,概率,机器学习,Pandas, Numpy, sympy scipy

预计阅读时间-10分钟

我在学习机器学习算法和玩Kaggle 比赛时候,不断地发现需要重新回顾概率、统计、矩阵、微积分等知识。如果按照机器学习的标准衡量自我水平,这些知识都需要重新梳理一遍。

网上或许有各种各样知识片断,却较难找到一本书将概率,统计、矩阵、微积分公式和Python结合起来。 要么是讲的比较浅显,要么跨度比较大。 最近看到一本书,恰好把上面的问题解决了。着重讲解Python for 概率,统计,机器学习. 相比较吴恩达教授的网上课程,各有千秋。

  • l 感觉吴教授的课程偏学术。 假设学生数学基础比较扎实(毕竟课堂受众是斯坦福大学学生,起点比较高),用矩阵推导公式,简洁明了。整个课程把绝大多数机器学习算法都教了一遍。
  • 这本书偏工程实践。 书中从多个层面来介绍经典算法。尤其是后期的泛化,正则化等章节。介绍的算法,但是每个算法都用2-5种python方法实现。例如: 

Python 循环或自带Itertools ((笛卡尔乘积,经典概率)
Python sympy(数学符号) (微积分公式推导和实现)
Python Pandas(分组计算) (程序员看得懂)

Python numpy (矩阵计算) (注:用矩阵计算,有速度飞起来的感觉)

Python scipy (科学计算库) (算法增强器)

个人感觉这本书比较适合我的学习目标。 也许也有人喜欢这样的书。书名和下载地址在文章最后面。

我先来翻译一段书中的一道期望计算题目,分享一下这种庖丁解牛和层次渐近的感觉。

题目:

三个硬币: 1角,2角,5角。 同时掷硬币,正面朝上的将面值加在一起求和。 只有两个硬币正面朝上的期望和是多少?  

  • Xi ∈ {0, 1} 注:硬币为Xi, (面值10,10,50,分别为X10,X20,X50,只有正面和反面,是服从二项分布(0,1)
  • ξ := 10X10 + 20X20+ 50X50 注: ξ 为正面朝上的硬币面值之和
  • η := X10X20(1 −X50) + (1 − X10)X20X50 + X10(1 − X20)X50 注: η 为只有两个硬币正面朝上的情况

这样此题就变成了计算 E(ξ |η) 在 η 条件为真时,ξ 的期望。我们首先需要找到一个函数 h(η)。 这个函数可以让残差最小化。


现在,计算两个硬币朝上的面值之和公式变成了如何定义h(η)函数。

注:η的结果是{0,1},所以h函数的只有两种输入值{0,1}。因此,正交内积条件为


因为我们只需要知道满足两个硬币朝上的情况,(即η =1 ),所以公式简化为:


两边积分计算求和



数学公式到此就结束了。本书中定义h(η) αη,并求α。这样公式就变成了如下形式。



注:



公式推导完了,下面就看看Python的四种解法吧。

解法1 :Sympy数学符号方法

上述推导公式,直接可以用数学符号语言,在Sympy中计算。

计算结果精准 alpha = 160/3

E(ξ |η) = (160/3)*η

# Do it by sympy
import sympy as S
X10,X20,X50 = S.symbols("X10,X20,X50",real=True)

xi = 10*X10+20*X20+50*X50
print("ξ = ",xi)
eta = X10*X20*(1-X50)+X10*(1-X20)*(X50)+(1-X10)*X20*(X50)
print("η = ",eta)

num=S.summation(xi*eta,(X10,0,1),(X20,0,1),(X50,0,1))

den=S.summation(eta*eta,(X10,0,1),(X20,0,1),(X50,0,1))

alpha=num/den

print(alpha)

ξ = 10*X10 + 20*X20 + 50*X50
η = X10*X20*(-X50 + 1) + X10*X50*(-X20 + 1) + X20*X50*(-X10 + 1)
160/3

解法2 :用Pandas,分组和计算(程序员的方式)

注:做1000次试验(蒙特卡罗仿真),然后计算试验的均值。计算结果近似于推导结果。

# Do it by pandas
import pandas as pd
d = pd.DataFrame(columns=['X10','X20','X50'])
ntest = 10**6
d.X10 = np.random.randint(0,2,ntest)
d.X10 = np.random.randint(0,2,ntest)
d.X20 = np.random.randint(0,2,ntest)
d.X50 = np.random.randint(0,2,ntest)

grp=d.groupby(d.eval('X10+X20+X50'))
grp.get_group(2).eval('10*X10+20*X20+50*X50').mean()

53.340141339548644

解法3:用Numpy,矩阵计算(速度快,有飞起来的感觉)

# Do it by numpy
import numpy as np
from numpy import array
ntest = 10**6
x=np.random.randint(0,2,(3,ntest)) 

expectation =np.dot(x[:,x.sum(axis=0)==2].T,array([10,20,50])).mean()

print(expectation)

53.3542987559

解法4: 用笛卡尔笛卡尔乘积,过滤只有两个硬币朝上事件,计算期望

#do it by pure python
import itertools as it
Xi = list(it.product((0,1),(0,1),(0,1)))               #笛卡尔乘积函数 初始化 - 所有掷硬币的事件 8种情况,三个硬币,每个硬币只有正面和反面

Xi_conditioned = list(it.filterfalse(lambda i:sum(i)!=2,Xi)) #过滤 只有两个硬币正面朝上的事件,只有三个事件

results = list((map(lambda k:10*k[0]+20*k[1]+50*k[2],Xi_conditioned)))
dem = len(results)
num = sum(results)

print(Xi)
print(Xi_conditioned)
print(results)
print(num/dem)

[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
[(0, 1, 1), (1, 0, 1), (1, 1, 0)]
[70, 60, 30]
53.333333333333336

这道概率期望题,书中演示了4种方法: Sympy,Numpy, Pandas 和Itertools. 在科学计算和机器学习中,采用不同的实现方法可以有助于问题解决和交叉检查。

最后分享一下这本书的名字:

. Python for Probability, Statistics, and Machine Learning

网上有下载。

如果觉得本文对你有帮助,请随手点赞!

分享是最好的投资!

个人文章链接

Kaggle HousePrice : LB 0.11666(前15%), 用搭积木的方式(2.实践-特征工程部分)

Kaggle HousePrice : LB 0.11666(排名前15%), 用搭积木的方式(1.原理)

用Python分析指数: 11月16日热门指数Z值表

用Python分析指数: 10月18日指数高低Z值表。

沪深300进入低估区了吗? 没有。好像中证环保现在低估了。

一个韭菜用Python采集,清洗和分析中证指数

时间: 2024-09-20 05:58:08

1个掷硬币问题,4个Python解法:读书笔记的相关文章

python函数学习笔记

#!/usr/bin/env python #个人学习笔记,无其他用途 def add(x=9,y=10): if x>y: a=x+y print "x+y" return a if x<y: a=y-x print "y-x" return a if x==y: a=x*y print "x*y" return a print add(2,3) print add(5,4) print add(6,6) 将一个数组的值传递给函数

python fabric使用笔记

  这篇文章主要介绍了python fabric使用笔记,fabric是一款实现远程操作和部署强大工具,本文就给出了它的多个使用实例,需要的朋友可以参考下 fabric title是开发,但是同时要干开发测试还有运维的活--为毛 task*3 不是 salary * 3 (o(╯□╰)o) 近期接手越来越多的东西,发布和运维的工作相当机械,加上频率还蛮高,导致时间浪费还是优点多. 修复bug什么的,测试,提交版本库(2分钟),ssh到测试环境pull部署(2分钟),rsync到线上机器A,B,C

python进阶学习笔记(一)

本节讲文件的操作 -------------------------------   打开文件   open函数用来打开文件,语法如下: open(name[, mode[,buffering]]) open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象.假设我要打开我硬盘(I:/python/test.txt) 文件,可以用下面方法: >>> f = open(r'i:\python\test.txt')   open函数中模式参数的常用值     基本文件方法   打开文

Python 3 学习笔记(二)python基本语法

许多 python 文件的头部都会写上: #!/usr/bin/python 或 #!/usr/bin/python2 或 #!/usr/bin/python3 这句活是必须的么? 如果你用 python xxoo.py 来运行,那么写不写都没关系,如果要用 ./xxoo.py 那么就必须加这行,这行被称为 shebang, 用来为脚本语言指定解释器. 1.编码 3.0之前Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在读取中文时会报错. 解决方法为只

python核心编程--笔记(不定时跟新)

的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   冗余输出(导入语句详细追踪) 1.5 –m mod 将一个模块以脚本形式运行 1.6 –Q opt 除法选项(参阅文档) 1.7 –c cmd 运行以命令行字符串心事提交的python脚本 1.8 file   以给定的文件运行python脚本 2 _在解释器中表示最后一个表达式的值. 3 prin

Python 3 学习笔记(一)python能干什么?

Python是一种什么语言? Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的Java语言等,Python是他们其中的一种. 比如,完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行. 所以Python是一种相当高级的语言. 学习Python难吗? 是不是越低级的程序越难学,越高级的程序越简单? 表面上来说,是的. 但是,在非常高的抽象

Python异常学习笔记_python

异常(exceptions)是Python中一种非常重要的类型,它和语法错误不同,是在程序运行期间引发的错误.Python中内置了很多异常,如IOError,NameError,KeyboardInterrupt等,更多的异常可以点击这里. 异常的意义在于提供一种更加优雅的运行方式,例如用Python编写一个计算器,如果用户输入不能计算的对象,则可以抛出异常,并进行处理, 如下: while True: try: x= int(input('Please In enter A number:')

&lt;深入 Python 3 &gt;学习笔记

可能学习的动力来源于对存在的好奇. 而所谓追求真善美,只是学习过程中的某一单维折射而已. 而学习的原理在于重复关注到使之成为思维惯性吧. PYTHON,我越来越记住它啦. 正如所有程序语言都涉及数据类型,数据结构,算法,标准库,扩展库,与系统API互动,,当然,它也不例外, <深入 Python 3 >电子版,URL:http://dipyzh.bitbucket.org/ 我也慢慢作笔记~: 在 Python 中, 每个值都属于某种数据类型,但却不用对声明变量的数据类型.它是怎么做到呢?Py

python基础学习笔记(十三)

re模块包含对 正则表达式.本章会对re模块主要特征和正则表达式进行介绍.   什么是正则表达式 正则表达式是可以匹配文本片段的模式.最简单的正则表达式就是普通字符串,可以匹配其自身.换包话说,正则表达式'python' 可以匹配字符串'python' .你可以用这种匹配行为搜索文本中的模式,并且用计算后有值并发特定模式,或都将文本进行分段.   ** 通配符 正则表达式可以匹配多于一个的字符串,你可以使用一些特殊字符创建这类模式.比如点号(.)可以匹配任何字符.在我们用window 搜索时用问