http://www.asyura2.com/10/senkyo97/msg/645.html
Tweet |
確率を計算しよう!と思ってる方で、気になる方だけお読みください。
<補足:計算について>ー―――――――――――――――――――――――
大雑把に3通りの計算の仕方があります。
1.中心極限定理を用いる方法:簡単で応用範囲が広い。一定の誤差は出る。
2.シミュレーション:簡単で結構正確。プログラムを書くか統計ソフトが必要。
3.数学的に出す方法:最も正確。プログラムを書くか数式計算ソフトが必要。
―――――――――――――――――――――――――――――――――――
問題は次の通りです。
「東京都の区部・市部の20歳から69歳の人から、11人を無作為に選択し平均を
取った時、その年齢が34.27歳(四捨五入)以下になる確率を求めなさい。」
http://www.toukei.metro.tokyo.jp/juukiy/2010/jy10q10601.htm
平成22年の東京都の区部・市部の20歳から69歳までの人口は、↑の統計表から、
114764, 129829, 139317, 156213, 168990, 181678, 185709, 187437, 189819,
193936, 201216, 205167, 207597, 211507, 214705, 226978, 235054, 230807,
227315, 220988, 216615, 213950, 218324, 158336, 202569, 187105, 173772,
164315, 156465, 153510, 147778, 145646, 134967, 136167, 139211, 138967,
141882, 151812, 157961, 171561, 198236, 197308, 201501, 137814, 122194,
150353, 160989, 154820, 155493, 142255,
となっていることが解ります。
総数は、8760902人となります。平均は43.64, 分散192.8, 標準偏差13.89
<1.中心極限定理を用いる方法>
母集団がどういう分布であれ、その母集団からn人を無作為抽出して、
その平均をとったものの分布は、平均が「母集団の平均」、
標準偏差が「母集団の標準偏差/√n」の正規分布に、
n が大きくなるにつれ急速に近づく、というのが中心極限定理です。
よって、11人無作為抽出した時の平均年齢の分布は、
「平均値43.64, 標準偏差4.187 の正規分布」にかなり近いはずです。
ですから、例えば Excel や Google docs のスプレッドシートで、
「=NORMDIST(377/11,43.63758789,4.186598188,TRUE)」
等とすれば、求める確率「0.012647538」が出てきます。
<2.シミュレーション>
理屈は非常に簡単です。問題の通りの事をやってみればいいだけですから。
要するに、11回、乱数で1〜8760902までの整数を出してみて、それによって
11人が何歳かを決定し、平均年齢を出します。
この操作を何回も繰り返せば、頻度表が作れますので、それでどの程度
平均年齢が34.27歳以下になりやすいかをシミュレートできる、というわけです。
とりあえず、C# で書いたプログラムと、その結果を書いてみます。
Nを1億程度に変更すれば、かなり正確な値を出すことが可能です。
――――――――――――――――――――――――――――――――――
using System;
namespace ConsoleKensatuSinsakai
{
class Program
{
static void Main(string[] args)
{
KensatuSinsakai ks = new KensatuSinsakai();
ks.Run();
}
}
///
/// 東京都の区部・市部から m人無作為抽出することをシミュレートし、平均年齢の頻度を調べる。
///
class KensatuSinsakai
{
///
/// H22年の、東京都の区部・市部の20歳から69歳の人口 (79歳までの人口を使う方が真の値に近いはず)
///
int[] tokyo20_79 = new int[] {
114764, 129829, 139317, 156213, 168990, 181678, 185709, 187437, 189819, 193936,
201216, 205167, 207597, 211507, 214705, 226978, 235054, 230807, 227315, 220988,
216615, 213950, 218324, 158336, 202569, 187105, 173772, 164315, 156465, 153510,
147778, 145646, 134967, 136167, 139211, 138967, 141882, 151812, 157961, 171561,
198236, 197308, 201501, 137814, 122194, 150353, 160989, 154820, 155493, 142255, // 69歳まで
124149, 120043, 131504, 125775, 128213, 110765, 109801, 105012, 94894, 87319, // 79歳まで
};
int m = 11;
int offset = 20;
///
/// 無作為に m 回足した和の頻度表。数=totals[和](0 〜 offset*m-1 は使わないので本来削るべき)
///
int[] totals;
///
/// totals の比率で各人が選ばれるようにするための大富豪的配列。メモリ食う。
/// (普通はtokyoを単純化するか、「乱数を引数にとり該当する年齢を返す関数」を定義する。)
///
int[] b;
Random rand = new Random();
public KensatuSinsakai()
{
int totNum = 0;
for (int i = 0; i < tokyo20_79.Length; i++)
{
totNum += tokyo20_79[i];
}
b = new int[totNum];
int x = 0;
for (int i = 0; i < tokyo20_79.Length; i++)
{
for (int j = 0; j < tokyo20_79[i]; j++)
{
b[x++] = offset + i;
}
}
totals = new int[(tokyo20_79.Length + offset - 1) * m + 1];
}
public void Run()
{
int N = 1000000; // 試行回数。適宜変更してください。
Console.WriteLine("各々 {0} 回({1}万回)の試行結果", N, N / 10000);
WriteProbability(50, N, false, false, 33.91, 34.27);
WriteProbability(60, N, false, false, 33.91, 34.27);
Console.ReadLine();
}
///
/// 各種確率計算と頻度表を書きだす。
///
/// 20+index-1 歳までのデータを使う
/// 試行回数
/// 1歳毎の分布を書きだすかどうか
/// 年齢の和の分布を書きだすかどうか
/// 何歳以下の年齢の確率を調べるか
void WriteProbability(int index, int N, bool writeStatus1, bool writeStatus2, params double[] ages)
{
for (int i = 0; i < totals.Length; i++)
{
totals[i] = 0;
}
int totNum = 0;
for (int i = 0; i < index; i++)
{
totNum += tokyo20_79[i];
}
// 無作為(ランダム)に m 回、tokyoの人口から選んで和を取り、totals[和] の頻度表を作る。
for (int i = 0; i < N; i++)
{
int temp = 0;
for (int j = 0; j < m; j++)
{
temp += b[rand.Next(totNum)];
}
totals[temp]++;
}
Console.WriteLine("{0}歳〜{1}歳から11人無作為に選んだ場合", offset, offset + index - 1);
for (int i = 0; i < ages.Length; i++)
{
Console.WriteLine("平均年齢が{0}歳以下になる確率:{1}", ages[i],
LowerCount((int)Math.Round(ages[i] * 11.0d)) / (double)N);
}
if (writeStatus1) WriteStatus1(index);
if (writeStatus2) WriteStatus2(index);
}
///
/// 無作為に m 回足した和が sum 以下であるカウント数を返す
///
int LowerCount(int sum)
{
int result = 0;
for (int i = offset * m; i <= sum; i++)
{
result += totals[i];
}
return result;
}
///
/// offset歳〜(offset+index)歳まで、1 歳単位の頻度表を書きだす
///
void WriteStatus1(int index)
{
for (int i = offset; i < offset + index - 1; i++)
{
int t = 0;
for (int j = i * m; j < (i + 1) * m; j++)
{
t += totals[j];
}
Console.WriteLine("[{0,2}]\t{1}", i, t);
}
int k = (offset + index - 1);
Console.WriteLine("[{0,2}]\t{1}", k, totals[k * m]);
Console.WriteLine();
}
///
/// 平均年齢が offset+index 歳までの、和の頻度表を書きだす
/// (この結果をExcelに張り付けてグラフにすれば、正規分布に近いグラフが得られます)
///
void WriteStatus2(int index)
{
for (int i = offset * m; i < (offset + index - 1) * m + 1; i++)
{
Console.WriteLine("[{0,3}]\t{1}", i, totals[i]);
}
Console.WriteLine();
}
}
}
<出力例>
各々 1000000 回(100万回)の試行結果
20歳〜69歳から11人無作為に選んだ場合
平均年齢が33.91歳以下になる確率:0.008697
平均年齢が34.27歳以下になる確率:0.011267
20歳〜79歳から11人無作為に選んだ場合
平均年齢が33.91歳以下になる確率:0.002463
平均年齢が34.27歳以下になる確率:0.003201
――――――――――――――――――――――――――――――――――
<3.数学的に出す方法>
まず、計算法についてです。そんなに難しい話ではないのですが、あまり
詳しく話しても仕方ない事なので(詳しくは確率や統計の教科書参照して下さい)
ポイントと、Mathematica での算出法だけ書いておきます。
まず、確率分布X,Y があった時、その和というのは「畳み込み」という演算で計算されます。
http://ja.wikipedia.org/wiki/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF
それを利用すればいいのですが、「難しそう」という人もいらっしゃると思うので、
サイコロの目の和の例と結果をご覧になれば「なるほど」と思ってもらえるはずです。
「サイコロをm回振った時、サイコロの出る目の和がX になる確率」を考えます。
結果的には、(1/6+x/6+(x^2)/6+(x^3)/6+(x^4)/6+(x^5)/6)^m の係数が、その確率になります。
[1回だけの時]
(1+x+x^2+x^4+x^5)/6 の係数は、(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)ですので、
サイコロの目が、1,2,3,4,5,6 になる確率は、全部 1/6 です。
[2回振った時]
和の範囲は、2〜12 になりますよね。
(1+x+x^2+x^4+x^5)^2/6^2
=1/36+x/18+x^2/12+x^3/9+(5x^4)/36+x^5/6+(5x^6)/36+x^7/9+x^8/12+x^9/18+x^10/36
ですから、和が 2,3,4,...,12 になる確率は、それぞれ
{1/36, 1/18, 1/12, 1/9, 5/36, 1/6, 5/36, 1/9, 1/12, 1/18, 1/36}
となるわけです。
3回振った時も、(1+x+x^2+x^4+x^5)^3/6^3 を計算して、係数を見れば
和が 3,...,18 になる確率が解ります。
これと全く同じことを、東京都の人口比に合わせて計算すれば、厳密に確率が求まります。
以下、Mathematica での計算例と、結果です。
――――――――――――――――――――――――――――――――――
list = {
114764, 129829, 139317, 156213, 168990, 181678, 185709, 187437,
189819, 193936, 201216, 205167, 207597, 211507, 214705, 226978,
235054, 230807, 227315, 220988, 216615, 213950, 218324, 158336,
202569, 187105, 173772, 164315, 156465, 153510, 147778, 145646,
134967, 136167, 139211, 138967, 141882, 151812, 157961, 171561,
198236, 197308, 201501, 137814, 122194, 150353, 160989, 154820,
155493, 142255, 124149, 120043, 131504, 125775, 128213, 110765,
109801, 105012, 94894, 87319
};
tokyoFunc[x_, m_, n_] :=
Dot[list[[1 ;; n]]*x^Range[0, n - 1], Table[1, {i, n}]]^m
pFunc[d_, m_, n_] :=
Sum[CoefficientList[tokyoFunc[x, m, n], x][[i]], {i, d}]/
Sum[list[[i]], {i, n}]^m
pFunc[154, 11, 50] // N (*33.91歳以下*)
pFunc[158, 11, 50] // N (*34.27歳以下*)
pFunc[154, 11, 60] // N (*33.91歳以下*)
pFunc[158, 11, 60] // N (*34.27歳以下*)
<出力>
0.008619
0.0111554
0.00240519
0.00314545
――――――――――――――――――――――――――――――――――
この記事を読んだ人はこんな記事も読んでいます(表示まで20秒程度時間がかかります。)
▲このページのTOPへ ★阿修羅♪ > 政治・選挙・NHK97掲示板
スパムメールの中から見つけ出すためにメールのタイトルには必ず「阿修羅さんへ」と記述してください。
すべてのページの引用、転載、リンクを許可します。確認メールは不要です。引用元リンクを表示してください。