データ分析の初歩から学んでいく連載(確率分布編)の第12回。ベータ分布は「確率の確率」とも呼ばれる分布です。ある事象の成功数と失敗数が分かっているときに、成功率が一定の範囲に入っている確率を求めるのに使われます。今回も具体例を基に、ベータ分布の利用例や、確率密度関数と累積分布関数の形を見ていきます。
この連載は、データをさまざまな角度から分析し、その背後にある有益な情報を取り出す方法を学ぶ『社会人1年生から学ぶ、やさしいデータ分析』連載(記述統計と回帰分析編)の続編で、確率分布に焦点を当てています。
この確率分布編では、推測統計の基礎となるさまざまな確率分布の特徴や応用例を説明します。身近に使える表計算ソフト(Microsoft ExcelやGoogleスプレッドシート)を使いながら具体的に事例を見ていきます。
必要に応じて、Pythonのプログラムや統計ソフト「R」などでの作成例にも触れることにします。
数学などの前提知識は特に問いません。中学・高校の教科書レベルの数式が登場するかもしれませんが、必要に応じて説明を付け加えるのでご心配なく。肩の力を抜いてぜひとも気楽に読み進めてください。
筆者紹介: IT系ライターの傍ら、非常勤講師として東大で情報・プログラミング関連の授業を、一橋大でAI関連の授業を担当。趣味の献血は心拍数が基準を超えてしまい99回で中断。心肺機能を高めるために水泳を始めるも、一向に上達せず。また、リターンライダーとして何十年ぶりかに大型バイクにまたがるも、やはり体力不足を痛感。足腰を鍛えるために最近は四股を踏む日々。超安全運転なので、原付やチャリに抜かされることもしばしば(すり抜けキケン、制限速度守ってね!)。
データ分析の初歩から応用まで少しずつステップアップしながら学んでいく連載の確率分布編、第12回です。前回は、待ち行列の分析などに使われるガンマ分布を取り上げました。今回はどちらの方法が優れているかを知るためのA/Bテストや、ベイズ統計での事前分布としてよく使われるベータ分布について、その特徴や意味を基本から解き明かし、確率密度関数/累積分布関数の求め方、利用例などを見ていきます。
最近は、人気のアニメや、日本国内でのBリーグの流行、オリンピックや米国のNBA(National Basketball Association)での日本人選手の活躍などでバスケットボール(以下、バスケ)がニュースに取り上げられることも多くなってきたので、バスケをよく知らない方でも「3ポイントシュート」という言葉を耳にしたことのある人は多いと思います。バスケのフィールドゴールは通常2点ですが、3ポイントラインの外側から放った場合には点数が3点入るというものです。遠くからシュートしないといけないので、失敗するリスクも高いですが、成功すると効果は抜群です。
筆者はバスケの素人ですが、3ポイントシュートにチャレンジして、いきなり成功したとします。1回シュートして1回成功したので成功率は100%です。筆者としては鼻高々ですが、この100%という数字には信ぴょう性があるでしょうか。そんなのはたまたまだ、と軽くあしらわれるのがオチです。
では、プロの選手が何試合かで25回中11回、3ポイントシュートを決めたとしましょう。成功率は11/25=44%となりますが、その数字にはどれぐらいの信ぴょう性があるでしょうか(図1)。
ただし、ここで言う「信ぴょう性」とは、「ちょうど44%であることが、どれだけ信じられるか」という意味ではなく、「成功率がどのように分布していて、その分布の中で“真の成功率”が特定の範囲に入っている確率はどのくらいか」という意味です。例えば、観測されたデータ(44%)を基に、“真の成功率”が40〜50%という特定の範囲に入っている確率はどの程度なのか、と評価することです。
もう少しくだけた言い方をすれば、何試合かの3ポイントシュート成功率は44%だったけれど、その選手の実力を表す“真の成功率”はどの範囲に(高い確率で)入っているか、ということです。
この問題に対するアプローチは、頻度主義と呼ばれる古典的な統計学の考え方とベイズ主義と呼ばれる考え方では異なります。今回はベイズ主義の考え方にそって話を進めます。頻度主義とベイズ主義の違いについては後ほど簡単に説明することとして、取りあえず、基本的な考え方と計算の方法を続けて見ていくことにします。
プロの選手で何回かシュートを打った結果だから、真の成功率は44%前後の狭い範囲に(高い確率で)入っているんじゃないの、と思われますね。でも、実力はもっと上で、たまたま調子が良くなかっただけかもしれません。あるいは、実力はそれほどでもないのにたまたま調子が良かっただけかもしれません。
そこで、さらに数試合を戦ったとして、以下のようなシナリオを考えてみましょう。
ちょっと先走りになりますが、真の成功率がどのように分布するかを上の例に合わせて可視化すると図2のようになります。上側のグラフがシナリオ1に、下側のグラフがシナリオ2に対応しています。ここではあくまでイメージを捉えるだけで構いません。グラフの作り方は後で解説します。
各シナリオにおいて、0試合目(青の直線)、25試合目(オレンジの曲線)、……、125試合目(緑色の曲線)のようにして定期的に試行(図2の可視化)を繰り返し、それまでの成功率の分布(事前分布)を、「○試合目」時点のデータが得られた後の成功率の分布(事後分布)に更新します。この更新をさらに繰り返せば、真の成功率がどのあたりの範囲に入るかが徐々に明確になってくるはずです。
さて、ここでようやくベータ分布の登場です。バスケの例のようなベルヌーイ試行(成功するかしないか)の場合、事前分布をベータ分布であるとすれば、事後分布もベータ分布となることが分かっています。
ベータ分布の確率密度関数では、ある成功率(例えば44%)に対する確率密度が求められます。ただし、確率密度は確率そのものではありません。つまり、成功率が44%である確率が求められるわけではありません。確率密度とは、累積確率がどの程度増えるか、といった「傾向」を表すものです。このことについては、第6回で解説した通りです。
一方、ベータ分布の累積分布関数では成功率が何らかの値までである確率が求められます。例えば、成功率が50%までである確率が求められます。従って、成功率が40〜50%である確率も求められます。成功率が50%までの確率から成功率が40%までの確率を引けばいいですね。これは図2での、グラフとx軸の0.4〜0.5までで囲まれた範囲の面積に当たります。
では、成功率の分布を求めてみましょう。具体的には、BETA.DIST関数を使って、3ポイントシュートの成功率が40〜50%である確率を求めてみます。BETA.DIST関数の書き方を見てから操作に進みます。
成功率がベータ分布の確率変数xに当たります。台(確率変数xが取り得る値の範囲)は0〜1です。
ベータ分布の母数は成功数を表すαと失敗数を表すβですが、図2ではαとβを実際の値+1としました。その理由は、最初の試行以前の状態が分からない場合、取りあえず成功率が0〜1である確率が全て等しいものとするためです。ベータ分布はα=1,β=1の場合は連続型一様分布になるので、そのような場合の事前分布として使われます。成功数1、失敗数1の状態から、11回の成功、14回の失敗という情報が得られた、と考えるわけです。このように事前の情報が得られない場合に使われる分布のことを無情報事前分布と呼びます。
ただし、それ以前の成績が分かっている場合やどの程度であるかが想定される場合には、無情報事前分布ではなく、妥当だと思われる分布を使った方が適切です。
例えば、昨シーズンの成績が200回中60回の成功、140回の失敗(=成功率30%)だったとします。シーズンオフに大幅な成長が見られたとするなら、昨シーズンの成績をベースとしつつも控えめに考慮するのがいいでしょう。そこで、成功数と失敗数の割合を保ったまま、値そのものを小さくし、成功数に+6、失敗数に+14して計算するといったことも考えられます。
なお、αとβにそのまま成功数と失敗数を指定すると、成功数あるいは失敗数の値が0の場合にベータ分布の値が求められないというやや消極的な理由もあります(BETA.DIST関数も#NUMエラーを返します)。試行の回数が増えると1を足した影響はほとんどなくなります。
では、図4で利用例を確認してみましょう。50%までの累積確率から40%までの累積確率を引いて、40〜50%の範囲に入る確率を求めます。
サンプルファイルをこちらからダウンロードし、[ベータ分布の利用]ワークシートを開いて試してみてください。Googleスプレッドシートのサンプルはこちらから開くことができます。メニューから[ファイル]−[コピーを作成]を選択し、Googleドライブにコピーしてお使いください。具体的な操作方法については、図中の説明や図の後の説明を参照してください。
◆ Excelでの操作方法
◆ Googleスプレッドシートでの操作方法
セルD9の値は0.395(=39.5%)となりました(図2の例で説明するなら25試合目時点での確率)。
ここで、セルB3に22、セルB4に28と入力してみてください(50試合目時点)。データから得られた成功率は44%のままですが、セルD9の、40〜50%の範囲に入る確率は0.527(=52.7%)となります。確率が39.5%から52.7%に高まっているので、成功率が40〜50%の範囲内にあることがより確からしくなりました。
また、セルB3に70、セルB4に55と入力してみてください(125試合目時点)。データから得られた成功率は56%となります。このとき、40〜50%の範囲に入る確率(セルD9の値)はぐっと下がって0.090(=9.0%)となります。真の成功率がある範囲は56%あたりだと考えられるので当然ですね。そこで、セルB7に0.5、セルB8に0.6と入力してみましょう。すると、0.733(=73.3%)という値が得られます。
このことは、図2のグラフと照らし合わせてみるとよく分かります。というわけで、そろそろ、ベータ分布の確率密度関数と累積分布関数を可視化する方法を見ておきたいですね。その前に、ベータ分布の確率密度関数と累積分布関数の定義だけを掲載しておきます。例によって、定義を覚える必要は全くありません。さらっとスルーして、ベータ分布の可視化に進んでいただいて結構です。
以下に示した式がベータ分布の確率密度関数と累積分布関数の定義です。これらの式を覚える必要は全くありません。ExcelのBETA.DIST関数を使えば、簡単に答えが求められます。
◆ ベータ分布の確率密度関数
◆ ベータ分布の累積分布関数
ただし、Bはベータ関数、Iは正則化ベータ関数です。これらの関数の定義は、第8回のコラムで紹介しました。
BETA.DIST関数の引数として母数α,βに幾つかの値を指定し、xの値を変化させていったグラフを描けば、ベータ分布の確率密度関数や累積分布関数を可視化できます。今回は、図1の例で使った値を指定して、成功率がどの範囲にあるのかを可視化したいと思います。なお、x=0やx=1の場合、α,βの値によってはBETA.DIST関数がエラーになることがあるので、x=0.01〜0.99のグラフとします(図5)。
確率密度関数の値を求めるための手順は以下の通りです。可視化については単に折れ線グラフを描くだけなので、関数の入力にのみ焦点を当てることにします。グラフ作成の手順についてはサンプルファイル内に掲載しておきます。[ベータ分布]ワークシートを開いて、図の後の手順で試してみてください。
◆ Excelでの操作方法
◆ Googleスプレッドシートでの操作方法
● グラフの作成方法
図5のグラフを見ると、α=1,β=1の場合は、連続型一様分布になっていることが分かります。また、α=12,β=15の場合は、山が0.25〜0.65ぐらいの広い範囲にあり、α=56,β=71の場合は、0.35〜0.55ぐらいの狭い範囲にあることも分かります。後者の方が、観測された値(0.44)にぐっと近くなりますね。ただし、山の高さが確率を表しているわけではないということに注意してください。グラフとx軸で囲まれた範囲の面積が確率(累積確率)を表します。
続いて、累積分布関数です。x,α,βの値は図5と同様とします(図6)。[ベータ分布累積]ワークシートを開いて、図の後の手順で試してみてください。
操作の手順は図4とほぼ同じです。違いは、BETA.DIST関数の[関数形式]に累積分布関数を表すTRUEを指定することだけです。グラフ作成の手順についてはサンプルファイル内に掲載しておきます。
◆ Excelでの操作方法
◆ Googleスプレッドシートでの操作方法
● グラフの作成方法
図5のグラフから、α=56,β=71の場合は、0.35あたりまでは累積確率がほぼ0で、それ以降急激に高くなることが分かります。また、0.55あたりでほぼ1に近づいていることも分かります。このことからも、成功率が35〜55%の範囲にあることがかなり「確からしい」と言えそうです。
BETA.DIST関数で関数の形式にTRUEを指定すると、成功率に対するベータ分布の累積分布関数の値、つまり累積確率が求められました。例えば、成功率に50%(=0.5)を指定すると、成功率が50%までである確率が求められました。
ここでは、その逆の計算を行います。つまり、ある累積確率になるのは成功率が何%までの場合かということを求めます。そのためには、BETA.INV関数を使って、累積確率から確率変数の値(成功率)を求めます。まず、BETA.INV関数の書き方を見ておきましょう。
BETA.INV関数を使えば、例えば、全体の95%を占める成功率がどの範囲であるかを求めることもできます。2.5%までの位置から97.5%までの位置ですね。[ベータ分布の逆関数]ワークシートを開いて、図の中に記された手順で試してみてください。
結果は、2.5%点が0.2659、97.5%点が0.6308となりました。全体の95%(=97.5%−2.5%)を占める成功率の範囲が0.2659〜0.6308であるということですね。
ここで、シナリオ1を試してみましょう。セルB3に55、セルB4に70と入力してみてください。2.5%点が0.3560、97.5%点が0.5277という結果になります。0.3560〜0.5277ということなので、かなり範囲が狭くなりました。
また、シナリオ2も試してみてください。セルB3に70、セルB4に55と入力すれば、全体の95%を占める成功率の範囲が0.4723〜0.6440となることが分かります。
これらの数字をどう解釈するかは、頻度主義とベイズ主義とでは異なります。頻度主義では、このような95%に含まれる範囲のことを95%信頼区間と呼びます。ただし、信頼区間は「真の値(真の成功率)」が、95%の確率でその範囲の中に入っているという意味ではありません。サンプルを取り出して信頼区間を求めることを何度も繰り返すと、それらの信頼区間のうちの95%が真の値を含んだものになっている、ということです。
一方のベイズ主義ではこの範囲を確信区間または信用区間と呼びます。ベイズ統計では、その範囲の中に真の成功率が95%の確率で含まれている、と素直に解釈できます。なお、今回の例では、簡単な計算で事後分布が求められましたが、分布によっては計算が複雑になり、簡単に求められない場合もあります。そのような場合には乱数を使ったシミュレーションにより事後分布を求めます。詳細については、この連載の続編である推測統計編でお話しする予定です。
ここでは、分布の累積確率が小さい部分を左右から2.5%ずつ切り取って95%の範囲を求めました。このような方法で求めた確信区間を等裾事後確信区間(ETI:Equal-Tailed posterior credible Interval)と呼びます。
一方、山の高いところから95%を求めることもあります。そのような確信区間を最大事後密度確信区間(HDIまたはHPDI:Highest posterior Dencity Interval)と呼びます。
最後に、実用的な例として、A/Bテストの例も紹介しておきましょう。Webサイトの広告をユーザーがクリックした後、資料請求や購買などの行動を取ったことをコンバージョン(CV)といいます。
ここで、広告を2種類を用意し、ランダムに表示して、どちらの効果が高いかを見極めることとしましょう。一定期間の実験を行ったところ、以下のような結果になったとします。CV数は成功数に当たるものです、クリック数は文字通り広告をクリックした回数です。こちらは、失敗数ではなく、試行数に当たることに注意してください。
広告A | 広告B | |
---|---|---|
CV数 | 11 | 24 |
クリック数 | 250 | 275 |
CV率 | 0.044 | 0.0872 |
表1 Webサイトの広告に対するCV率(=CV数÷ユーザークリック数) |
一見して、広告BのCV率の方が良さそうです。そこで、CV率の分布をそれぞれ可視化してみましょう。確率密度関数とグラフの作成方法は図5の例とほぼ同じです。CV率の値が小さいので、確率変数xの範囲を0.01〜0.2に限定して作成してみます。[A-Bテスト]ワークシートを開いて図9の後の手順で試してみてください。
◆ Excelでの操作方法
◆ Googleスプレッドシートでの操作方法
● グラフの作成方法
図9を見ると、広告Bの方が優れていることが分かります。ただし、グラフには重なっている部分があるので、絶対的に広告Bが優位であるというわけではありません。例えば、広告AのCV率が0.08で、広告BのCV率が0.06になることもあり得ます。
そこで、広告Bがどの程度優れているかを簡単なシミュレーションで求めてみましょう。それぞれのベータ分布に従う乱数を作成して、AのCV率よりBのCV率の方が大きい割合を求めればいいですね。Excelでももちろんできますが、乱数を1000個作るとすれば少なくとも1000×2個のセルが必要になります。Excelでの例も[A-Bテスト (完成例)]ワークシートに含めてありますが、Pythonであれば数行で済むので、ここでは簡単なコードを紹介しておきます。
サンプルプログラムはこちらから参照できます。リンクをクリックすれば、ブラウザが起動し、Google Colaboratoryの画面が表示されます(Googleアカウントでのログインが必要です)。最初のコードセルをクリックし、[Shift]+[Enter]キーを押してコードを実行してみてください。コードの詳細については解説しませんが、コメントとリスト1の説明を見れば何をやっているかが大体分かると思います。
from scipy.stats import beta
import numpy as np
cv_a = 11 # AのCV数
click_a = 250 # Aのクリック数
cv_b = 24 # BのCV数
click_b = 275 # Bのクリック数
a = beta.rvs(cv_a+1, click_a-cv_a+1, size=1000) # ベータ分布の乱数を1000個
b = beta.rvs(cv_b+1, click_b-cv_b+1, size=1000) # ベータ分布の乱数を1000個
np.mean(a < b) # bの方が大きくなる割合を求める
# 出力例(乱数を使っているので実行のたびに結果が少し変わります): 0.971
結果を見ると、97.1%の確率で広告BのCV率が高くなっていることが分かります。なお、サンプルプログラムの中には図9と同様のグラフを描画するコードも含めてあります。
今回はベータ分布について、簡単な利用例を紹介した後、確率密度関数と累積分布関数の求め方についてお話しし、さらにA/Bテストへの応用例を見ました。その中で、ベイズ統計における事前分布と事後分布についても簡単に触れました。確信区間などについてやや深入りしたかもしれませんが、詳細については推測統計編でお話しします。
次回は、機械の寿命や故障率の分析などに使われるワイブル分布のお話をします。次回もお楽しみに!
関数の利用例については、この記事の中で紹介している通りです。ここでは、今回取り上げた関数の基本的な機能と引数の指定方法だけを示しておきます。
BETA.DIST(x, α, β, 関数形式)
BETA.INV(x, α, β)
「やさしい確率分布」
Copyright© Digital Advantage Corp. All Rights Reserved.