前回の続きです。
前回やった問題のコードを書き直して一般的なものにする。
■クッキーの問題
「クッキーの入った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()
以上