2010年3月10日星期三

一個英語好屎者的自白

我雖然大學畢業,但以生活上的英語來說,恐怕連鬼仔初中生的水平都未到。始終,以前在大學混所需的學術用英語與日常英語是大有分別的。

英文應該怎麼教,是一個一向都爭論不休的問題。有些人主張教文法,背生字,有些則主張盡量學習日常對話。身為老餅,少時所學的當然是前一套。

由於自己的日用英語不靈光,所以我一向都以為自己所學的那一套是垃圾,不過這套垃圾偶然都有一點「長處」:
  1. 我們可能會認識一些一般西人也未必識的生字。例如日前我寫了封函件,我的澳洲老闆批改時,就驚訝地問 parsimonious 一字是甚麼意思。我沒想過他會不懂,所以比他還驚訝。另外,某次一位在香港出生但於英國長大的高學歷朋友問起 genocide 一字怎解,也令我懷疑她是否在跟我開玩笑。
  2. 我們串字往往比鬼仔準確,原因是我們不靠拼音。因此,我們很少搞錯 you're 跟 your,it's 跟 its 等等,更不會連 potato 都串錯。
  3. 故此,儘管我們的英語發音往往謬誤百出,但若以「錯別字」來比喻的話,我們的謬誤多是「別音」(例如將 challenge 讀作 ── 以通勝拼音來比喻 ── 近似「叉輪廚」而非近似「車輪廚」),而不是「錯音」(例如將 nuclear 讀成 nucular)。
  4. 還有一個比較特殊的情形,是西人似乎很容易將以 -neous 或 -nious 作結的生字(例如上述的 parsimonious,還有 homogeneous 等等)當成 -nous 來讀,就算是對著正確地串出的文本唸時,也不例外。這種情況我見過許多次。我們因為先背生字,所以較少漏掉 -neous 或 -nious當中的 e 或 i。
不過兩害相權取其輕嘛 …… 我還是寧願自己懂得用日常英語與鬼佬(或 preferably 鬼妹,if that matters)溝通。

伸延閱讀:順帶一提,challenge 的音標 ˈtʃæl.ɪndʒ 當中的 æ,原來大有政治學問。咁都得?

2010年3月5日星期五

難怪北極企鵝多

(Inspired by Target population; 1-555-CONFIDE blog)

在民建聯的奇幻世界,有南極企鵝和北極企鵝。這是一個奇妙的世界。

現在,請閱以下問題。毋須計算答案,瞭解問題就夠了:
奇幻世界有 7,000,000 隻動物,包括 1,736,623 隻企鵝,其中隨機地抽了一批,放在某個有 700 間房的園區之中。若 4.7% 的房間有北極企鵝,在以下每種情況之下,試估計奇幻世界的北極企鵝總數。

(A) 每間房只得一隻動物。
(B) 每間房兩隻動物,但最多只得一隻是北極企鵝。
(C) 每間房的動物數目不明。
依照民建聯的奇幻邏輯,以上三種情況的答案,都是 1,736,623 × 4.7% = 81,621。

這真是一個奇妙的世界。

xxxxxxxxxx

話說民建聯搞了個民意調查,訪問了 700 人,其中問到:
3. 據你所知,你既朋友或親人有冇試過吸毒後駕駛呢?
根據調查結果,民建聯得出如下推論:
另外,在是次調查中, 4.7% 受訪者表示,曾有朋友或親人試過吸毒後駕駛的情況,若以本港現時 1,736,623 名領有正式駕駛執照的總人數來推算,我們估計約有 81,621 名駕駛人士曾試過吸毒後駕駛,有關情況令人憂慮(見問題3)。
若將「房間」換成「受訪者」,「房中動物」換成「受訪者認識的親友」,「企鵝」換成「駕駛者」,「北極企鵝」換成「吸毒駕駛者」,那麼以上的 (C) 情形就最接近民建聯的問題 3 了。(不過也只是接近而已,原因請見電鋸的統計學剖析。)

調查報告「估計約有 81,621 名駕駛人士曾試過吸毒後駕駛」,這是怎樣算出來的?

答案就是 81,621 = 1,736,623 × 4.7%。

真是奇妙的推論。其實,莫講含有不明參數的 (C) 情形,就算是 (A) 或 (B),這個 81,621 的推論,都仍然是錯的。就連這樣簡單的算術都計錯,咁樣「猜 my best」,也難怪民建聯的人會以為「北極,人少企鵝多」了。

2010年3月2日星期二

Random shuffling

Doing the Microsoft Shuffle: Algorithm Fail in Browser Ballot; Rob Weir: An Antic Disposition

這是我近日看過的一篇有趣文章。話說歐盟控告微軟的 IE 造成壟斷,雙方後來和解,同意於新版本的 Windows 之中加入選單畫面,讓用家選擇安裝喜歡的瀏覽器(見下圖)。選單中五種瀏覽器的位置,是隨機決定的,不過上述網誌的作者卻發現,五種瀏覽器的位置,實在稱不上是均勻分佈 (uniformly distributed)。後來他深入研究微軟「兜亂」(shuffle) 五個位置所用的程式碼,發現結果相當不平均。

要兜亂一個序列,或者用數學化一點的語言來說,要生成一個隨機置換(這裏「隨機」的意思當然不是照字面解,而是照一般人的用法去解,也就是不止隨機,還要均勻分佈),最方便穩妥的辦法當然是 Fisher-Yates shuffle。用一行 pseudocode去講,就是

p = {1, 2, 3, 4, 5}; for (i=n; i>1; --i) swap(p[i], p[rand(i)])

微軟捨此不用,反而做類似以下的事情:

p = {1, 2, 3, 4, 5}; sort(p, RandomSort)

當然,p 並非隨機序列,按其內容排序,並不會得出隨機結果,所以微軟排序時,用了以下的隨機「比較函數」(comparator):

function RandomSort (a,b) {return (0.5 - Math.random());}

換句話題,當你為兩個數目 a 與 b 排大小時,程式所看的並非 a 的數值是否真的小於 b,而是隨機產生一個介乎 -0.5 與 +0.5 之間的數字 x = 0.5 - Math.random(),若 x 是負數,便扮作 a<b;若是正數,則扮作a>b;若 x=0,則當 a=b。

利用這樣的隨機比較函數,當然也會得出隨機置換,只不過置換的分佈既不夠平均,亦因排序方法而異。其實腦筋清楚並對中學的統計學稍為有點認識的人,根本都不會犯上這種錯誤,所以前述文章令我喜歡的地方,並不是它有甚麼令人意外的發現或結論,而是作者竟然肯花那麼多時間去找出實際錯誤的來源。這種探究精神,才真的令我佩服。

該網誌的留言亦非常值得一看。例如 #27 的 Tom 問,若將 Fisher-Yates shuffle 改動成 for (i=1; i<=n; ++i) swap(p[i], p[rand(n)]),為甚麼不算均勻置換?#31 的 Dave 就回答得相當精闢。Tom 另外提及 for (i=1; i<=n; ++i) swap(p[rand(n)], p[rand(n)]),其問題所在也是有趣的思考材料甚至面試題目。(有無讀者可以用簡單的方法指出問題所在?)留言 #52 及 #53 則反映原來人們對統計學的認識,可以相當出人意表。留言 #92 則指出原來微軟所用的蠢方法,一個有名的 Javascript 教學網站亦有教!至於留言 #95 的 Issac 君,與文章作者同樣具探索精神。他發現用微軟所用的隨機比較法,五個位置的置換結果於不同的排序方法之下,差異可以頗為巨大。詳見:

Randomizing by Random-Comparison Sorting (Revisited); 2718.us blog