数学への挑戦 第二弾〜集合を使う:数理モデルxプログラミング〜

前回は「傘を持って行くか行かないか?」をテーマに数理モデルを考えました。

今回は、数理モデルでの喫煙率を求める方法を考えます。
参考にする本は下のものです。

前提

この本に登場する「青葉」が担当することになった大学内の喫煙率調査を行う場合の内容で考えていきます。前提としては

  1. 大学内は禁煙
  2. 生徒数は1000人
  3. 下のような質問(アンケート)をしても適切な答えは返ってこない
    あなたは学内でタバコを吸ったことがありますか?
    <はい> <いいえ>
    どちらかに丸をつけてください

このアンケートを見てもう一人の登場人物「花京院」がダメ出しをして以下のような手順で「喫煙率」を求めようと言うことになった。
こんな内容で書かれていました。

行ったことの一覧

  1. 回答のランダム化
  2. 集合で考える
  3. 期待値と分散
  4. 結論を見る

数理モデルを作る

1.回答のランダム化

学内で「違反行為」に当たる喫煙を行なったのか?と言う質問に対して全員が正直に「YES」と答えるとは考えにくいので「回答のランダム化」を行います。
早い話が、「大数の弱法則」を使用して「確率によってバラツキの出る値を0に近づける」=「確率(パーセンテージを含む)を無視できるレベルまで下げる」と言うことを行いアンケートの結果をまとめると言うことです。

具体的に①

コインを投げてもらい、裏が出たら必ず<はい>を選択してもらう

この方法で、正直に答える人とそうでない人の割合(確率)を求めることで「正直に答えない人=喫煙者」の割合を求めると言うことです。

2.集合で考える

まずはグループわけを行います。下のように分けます。

  1. Aグループ = コインで表が出た人
  2. Bグループ = コインで裏が出た人
  3. Cグループ = Aの中でタバコを吸った人
  4. Dグループ = Bグループでタバコを吸った人

<図1>

喫煙率の推定

アンケートの結果で<はい>と答えた人が600人いたと仮定すると下のようになる。

Cグループ = コインの表が出て、正直に<はい>と回答
Bグループ = コインの裏が出て<はい>と回答

<はい>と回答した人の中には上のような人が含まれますので|B U C| = 600と表現できます。
BまたはCの要素数 = 600と言う意味です。

そして「生徒数=1000」でコインの裏が出る確率は「1/2」なので|A|=500, |B|=500と推測することができる。確定ではないので注意です。

上記の情報をまとめると以下のようになる。
|B U C|=600, |A|=500, |B|=500
そして、コインの表裏はランダムに決まるので「確率的に」以下のようになる
|C|/|A| = |D|/|B|
これは「AグループとBグループに喫煙者がX人ずついるであろう」と言う考えを基にしている

具体的に②

実際に行ってはいないけれど「仮に」喫煙者が400人いたとするのであれば、喫煙率は「400 / 1000 = 40%」になるので「コイントスでA, Bグループ(500人ずつ)にいる喫煙者社の割合(確率)も40%で200人ずついることになる。

求めるべき値の喫煙者数=400は下のようにして求めることができる。

|B U C| = |B| + |C|
|B U C| - |B|=  |C| 両辺から|B|を引く

下の値を使用して計算すると。。。
|B U C|=600, |A|=500, |B|=500
次のような計算式で求めることができる
|B U C| - |B| = |C| = 100
|C| / |A| = 100 / 500 = 0.2 = 40%
となる。。。つまり喫煙者の割合は「40%」になり「仮定」で示した「400」と言う数値も正しいものであると言える。

この結果は、喫煙率でなくても良い。

と言うことらしいです。

ここまでをプログラムに落とすなら。。。

Javaで上のものを表現する

まずは、主要な変数を明確にします。

  1. A〜Dまでのグループの人数
  2. ここで求めたい数値(喫煙率)

「上の数式そのまんま?」と思うかもしれませんが、その通りになります。
プログラムに落とし込むときに重要なのは、各パラメータの意味が重要になります。

早い話が

「数理モデルのインプットとアウトプットがなんなのか?」がわかれば良いと言うことです。
実装するメソッドも下のようになります。

/** 
 * 恋んトスによるランダム化の、割合を求める、数理モデル
 * 目的は引数に依存する
 * @param all 対象になる(分母の)数
 * @param resultValue アンケートの結果<はい>の数
 */
public double daisunoHosoku(int all, int resultValue) {
   // |B U C| 上のケースでは600だった
   double BorC = resultValue;
   // |A|
   double A = all / 2;
   // |B|
   double B = all / 2;
   // |C| / |A| = |D| / |B|で求めるのは|C|
   double C = BorC - B;
   // 割合(確率)を返却する
   return C / A;
}

と上のようになります。
ちなみに、今後このコードをカスタムしていきます。
でわでわ。。。

<!— BODY広告-->