前回の続きです。
前回やった問題のコードを書き直して一般的なものにする。
■クッキーの問題
「クッキーの入った2つのボウルがある。
ボウル1 ? バニラクッキー 30枚 :チョコレートクッキー 10枚
ボウル2 ? バニラクッキー 20枚 :チョコレートクッキー 20枚
どちらかのボウルをランダムに選びクッキーを1つランダムに選んだ場合、
それがボウル1だという確率を求めよ。」
from thinkbayes import Pmf
class Cookie(Pmf):
def __init__(self, hypos):
Pmf.__init__(self)
for hypo in hypos:
self.Set(hypo, 1)
self.Normalize()
def Update(self, data):
for hypo in self.Values():
like = self.Likelihood(data, hypo)
self.Mult(hypo, like)
self.Normalize()
mixes = {
'Bowl 1':dict(vanilla=0.75, chocolate=0.25),
'Bowl 2':dict(vanilla=0.5, chocolate=0.5),
}
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
like = mix[data]
return like
def main():
hypos = ['Bowl 1', 'Bowl 2']
pmf = Cookie(hypos)
pmf.Update('vanilla')
for hypo, prob in pmf.Items():
print hypo, prob
if __name__ == '__main__':
main()
■20年前の早稲田大学の入試問題
「5回に1回の割合で帽子を忘れるくせのあるK君が、正月に A、B、C 3軒を順に年始回りをして家に帰ったとき、
帽子を忘れてきたことに気がついた。2軒目の家 B に忘れてきた確率を求めよ。」
from thinkbayes import Pmf
class Waseda(Pmf):
def __init__(self, hypos):
Pmf.__init__(self)
for hypo in hypos:
self.Set(hypo, 1)
self.Normalize()
def Update(self, data):
for hypo in self.Values():
like = self.Likelihood(data, hypo)
self.Mult(hypo, like)
self.Normalize()
def Likelihood(self, data, hypo):
if hypo == 'A':
return 1/5.0
elif hypo == 'B':
return 4/25.0
elif hypo == 'C'
return 16/125.0
def main():
hypos = ['A', 'B', 'C']
pmf = Waseda(hypos)
pmf.Update('B')
for hypo, prob in pmf.Items():
print hypo, prob
if __name__ == '__main__':
main()
■喫煙者の推定の問題
「男性10人、女性7人が一室でパーティーを開いた。男子の喫煙者は5人、女性は3人である。
部屋に入ったら煙草の吸殻が1本、灰皿の上にあった。このとき、吸った人が女性である確率を求めなさい(煙草の吸い回しはしていないと仮定する)」
from thinkbayes import Pmf
class Tabaco(Pmf):
def __init__(self, hypos):
Pmf.__init__(self)
for hypo in hypos:
self.Set(hypo, 1)
self.Normalize()
def Update(self, data):
for hypo in self.Values():
like = self.Likelihood(data, hypo)
self.Mult(hypo, like)
self.Normalize()
mixes = {
'Men':dict(Smoke=1/2.0, NoSmoke=1/2.0),
'Women':dict(Smoke=3/7.0, NoSmoke=4/7.0),
}
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
if hypo == 'Men':
like = 10/17.0 * mix[data]
return like
elif hypo == 'Women':
like = 7/17.0 * mix[data]
return like
def main():
hypos = ['Men', 'Women']
pmf = Tabaco(hypos)
pmf.Update('Smoke')
for hypo, prob in pmf.Items():
print hypo, prob
if __name__ == '__main__':
main()
=====フレームワークをカプセル化したとき=====
上のコードの共通化部分をカプセル化したとき。
■クッキーの問題
from thinkbayes import Suite
class Cookie(Suite):
mixes = {
'Bowl 1':dict(vanilla=0.75, chocolate=0.25),
'Bowl 2':dict(vanilla=0.5, chocolate=0.5),
}
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
like = mix[data]
return like
def main():
suite = Cookie(['Bowl 1', 'Bowl 2'])
suite.Update('vanilla')
suite.Print()
if __name__ == '__main__':
main()
■20年前の早稲田大学の入試問題
from thinkbayes import Suite
class Waseda(Suite):
def Likelihood(self, data, hypo):
if hypo == 'A':
return 1/5.0
elif hypo == 'B':
return 4/25.0
elif hypo == 'C':
return 16/125.0
def main():
suite = Waseda(['A', 'B', 'C'])
suite.Update('B')
suite.Print()
if __name__ == '__main__':
main()
■喫煙者の推定の問題
from thinkbayes import Suite
class Smoke(Suite):
mixes = {
'Men':dict(Smoke=1/2.0, NoSmoke=1/2.0),
'Women':dict(Smoke=3/7.0, NoSmoke=4/7.0),
}
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
if hypo == 'Men':
like = 10/17.0 * mix[data]
return like
elif hypo == 'Women':
like = 7/17.0 * mix[data]
return like
def main():
suite = Smoke(['Men', 'Women'])
suite.Update('Smoke')
suite.Print()
if __name__ == '__main__':
main()
喫煙者の推定の問題はもっとうまい方法があるかも。
今回は完全にメモ。
*7/24追記
喫煙者の問題で、事前確率を尤度の計算にもってきていたのを
事前確率のところに変更しました。
from thinkbayes import Suite
class Smoke(Suite):
def __init__(self, hypos):
Pmf.__init__(self)
self.Set('Men', 10/17.0)
self.Set('Women', 7/17.0)
self.Normalize()
def Update(self, data):
for hypo in self.Values():
like = self.Likelihood(data, hypo)
self.Mult(hypo, like)
self.Normalize()
mixes = {
'Men':dict(Smoke=1/2.0, NoSmoke=1/2.0),
'Women':dict(Smoke=3/7.0, NoSmoke=4/7.0),
}
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
if hypo == 'Men':
like = mix[data]
return like
elif hypo == 'Women':
like = mix[data]
return like
def main():
suite = Smoke(['Men', 'Women'])
suite.Update('Smoke')
suite.Print()
if __name__ == '__main__':
main()
以上