10/25/2006

吳子青: 民意調查真的公正嗎

前言:
最近又到了選舉期了 在電視媒體或報章雜誌常常可以看到
“ 某某參選人支持率多少”…
民意支持率各家都宣稱客觀公正,但其實是可以操作的
在這裡舉出一個以前碰過的問題讓大家思考一下 

問題:

若台北市某候選人的真實 “民意支持率”為15%,找出使調查樣本的
民意支持率超過0.18 的出現機率不大於 10% 的最小樣本數 N。

----------------------------------------------------------------------
答案:

題旨與分析
這問題的思考流程是這樣的
將全部台北市民當成一個族群,而調查的對象代表抽樣的樣本
“某候選人的真實民意支持率為15%” 這句話的意思就是代表族群的支持率
而調查樣本的民意支持率就是樣本的支持 率

將這問題視為一個二項式分佈的問題,也就是支持和不支持兩種情況
支持的機率 P=0.15 不支持的機率 Q=0.85
舉例說明
如果某一次的抽樣從台北市民隨機抽10個人 (Sample Size m=10)
10個人中支持候選的人有2個人,不支持的有8個人
這個事件出現的機率為

http://photos1.blogger.com/blogger2/2907/859880749988154/1600/formula1.jpg

所以如果問題是 ”找出使調查樣本的民意支持率超過0.18”
如果抽樣人數維持10人,支持人數大於1.8的都符合條件
也就是支持人數 2 到10人分別算出的機率加總。

題目所求是 “出現機率不大於 10% 的最小樣本數 N。”所以從n=1
開始算到符合出現機率不大於10%為止。

程式流程
Step 1 : 宣告function p1(m,n) 為抽樣m個人,有n個人支持的機率

Step 2 : 計算A為抽樣m個人,支持率超過0.18的機率總和

Step 3 : 從m=1 開始增加用For 跑迴圈,決定停止條件為A < >程式內容


/ p1.m / (* 這行代表m-files p1.n 開始 *)

function output=p1(m,n)

if n>0.5*m
a=m-n;
output=prod((m-a+1):m)/prod(1:a)*(0.15)^n*(0.85)^(m-n);

else
output=prod((m-n+1):m)/prod(1:n)*(0.15)^n*(0.85)^(m-n);
end


/ pp1.m / (* 這行代表m-files pp1.n 開始 *)
clear;
max=400;
ppp1=zeros(max,2);

for m=1:max
k=ceil(m*0.18);
A=0;


if A<=0.1 fprintf('最小樣本數%d\t出現機率%d',m,A);

break
end
fprintf('最小樣本數%d\t出現機率%d\n',m,A);
clc;
end
plot (ppp1(1:max,2), 'DisplayName', 'ppp1(1:max,2)', 'YDataSource', 'ppp1(1:max,2)');
figure(gcf)
xlabel('樣本數目');
ylabel('出現機率');
/ Command windows / (* 這行代表command windows輸入 *)
pp1


執行結果
最小樣本數217 出現機率9.559103e-002
這是最後跑出來的結果
N=217為民意支持率超過0.18 的出現機率不大於 10% 的最小樣本數 N

這是程式結果




http://photos1.blogger.com/blogger2/2907/859880749988154/1600/hy2.jpg

這是圖

http://photos1.blogger.com/blogger2/2907/859880749988154/1600/hydro.jpg

討論
(1)因為老師上週的上課內容剛交到For 和If的用法,所以在這裡練習一下

(2) 程式中碰到最大的問題在於 prod () 連乘函數括號內的矩陣不能太大
從1*2*3……..*171 =prod(1:171) 這樣結果會爆掉 ,可是在算二項式分佈
的機率時就一定會用到。

所以在這裡用了一個小技巧,在p1裡當 n > 0.5 m 時 令n=m-n
因為在排列組合裡 C10取2=C10取8,10!/8!2! =10!/2!8!
在這裡可以避免連乘太多項,可以有效 避免算到M=171時,
結果一定會出現NaN。但是當m 算到300多時
仍然會出現同樣的問題。或許會有更有效率的寫法。

4 則留言:

MARTIN 提到...

這個問題好極了,程式方面可以使用下面兩個指令:
nchoosek(n,k):即n中選k的集合
factorial(n):計算n!階乘,但n好像要小於15.

Ching 吳子青 提到...

(1)
nchoosek(n,k): 我試過用這個指令
在n太大的情況會跳出這樣的訊息

nchoosek(200,100)
Warning: Result may not be exact. Coefficient is greater than 10^15,
and is only good to 15 digits.
> In nchoosek at 54

ans =

9.0549e+058

不過這樣比自己寫階乘要方便多了 :)

(2)factorial(n) 和 prod(1:n)指令類似
好像大於15也可以
我嘗試計算 factorial(170)

ans =

7.2574e+306

但是 factorial(171)

ans =

Inf

好像都有一樣的問題 謝謝老師

學到很多東西 也請老師加油 :)

Eric Wu(堉光) 提到...

  本人駑鈍,看了題目許久,請問此題得題意指的是說,一個候選人民調支持率為0.15,請問到了多少人之後,他的支持率在0.18時會小於的機率百分之十。

  我一開始以為這是一個統計的問題,要去推估樣本數目的大小。

  所以意思是說樣本數多少的時候,他都有一個機率會達成這樣的情況。
  試問由這樣一直推估下去,是否也能夠從這樣的方式計算回母群。因為統計好像都是以樣本去推估母群。

  老師加油看了老師的話有感而發寫了篇心得。感想

  

bai 提到...

我想請問各位MATLAB達人
不知道是否可以交我怎寫Erlang B的matlab程式
假設給你
Blocking probability (0.03)
channel 數目 (220)
要如何算出 total traffic