顯示具有 R 標籤的文章。 顯示所有文章
顯示具有 R 標籤的文章。 顯示所有文章

2017年9月17日 星期日

[R] Tidyquant 的練習-利用200天平均線的測試

最初大約是3-4月,當時參加了一個 R User group的 Machine Learning Beginner 的課堂,接觸到 "tidyverse" library。Tidyverse" 中的 "dplyr" 在數據整理上十分方便,不過課堂中處理的都是一些非時間序列的數據,好奇在時間序列的股票方面有什麼好工具可以使用呢?那時候開始留意到有一個叫 "tidyquant" 的 R Library,就一直想找時候來學習一下。例如,好不好把之前的股價研究換成用 Tidyquant再試一次?終於,上星期在 Feedly 看到一篇評論信報某專欄的blog post,就正好用這研究來作為練習,有興趣的話建議先看以下兩篇原文:

分析數據還是以數據「作」分析呢?
https://htmichael.blogspot.hk/2017/08/blog-post.html

【EJFQ信析】港股未脫超買 不離三種下場
http://www2.hkej.com/instantnews/market/article/1636469


2017年4月28日 星期五

[R] ML4B 課堂重溫 - 淺談 KNN (K-th Nearest Neighbors) 算法

將今個星期二的 R Machine Learning 堂記錯成星期三,錯過最重要的最後一堂(哭)。 原本想打得太慢的記錄可以等埋最後一堂。算了吧.... 當上一堂講了Regression model,第3堂開始講分類Classification的問題。從使用 KNN (K-th Nearest Neighbors) 算法,在Class套件中的knn() 開始,一路講了 Logistics regression 的 glm()、分類樹的rpart()、支持向量機(Support Vector Machine)的svm(),最後在垃圾郵件的分類時,提到為中文句子斷詞的JiebaR套件。

這種分類問題的簡單例子,例如你找來了100個男生的資料,包括資產、收入、樣貌、才華、談吐等評分。再找女生們去評定他是否「荀盤」。有了這組Training Set的數據,可以用來訓練你的電腦中的一個「荀盤分類器」。讓它透過學習這群女生的判斷結果,從而當有新一筆資料(男生)時,可以從他的「Package」判別他是否女生心目中的荀盤。又或者,找出要成為荀盤的條件,看看你....在哪方面可以改進改進。

How a Math Genius Hacked OkCupid to Find True Love

拿KNN 算法來解釋,這算法是利用特徵空間中"距離"最近的K個鄰居去預測目標(或者是你)的分類。例如,當相近的5個近鄰中有3個是+,2個是-,就預測自己也是+ 。就是一種物以類聚,人以群分的想法。當然這鄰居不是指在你生活圈子中身邊附近的人(但大概你們也有某些相似之處),而是考慮上面所收集的一組多維度的「Package」中各個因素的接近程度。
https://commons.wikimedia.org/wiki/File:KnnClassification.svg#/media/File:KnnClassification.svg
k=3:預測= ▲
k=5:預測= ■

2017年4月4日 星期二

R User Group 的 Machine Learning for Beginners (三月)

三月另一個開始的活動,是R User Group 辦的Machine Learning for Beginners。共四堂,暫時上了一半,雖然不幸收工前總有意外,兩次都錯過了開頭的部份,還好有source code 看著理解,和對基本的統計總算仍有概念,

第一堂主是R 的數據處理。主要用"tidyverse"套件包,"tidyverse"是打包了一組有著共同資料形態和'API'設計,方便一齊使用的套件。透過"tidyverse"處理這些套件的 install (core + select) 和 load (core)的工序。當晚用到的主要指令包括來自 "magritti" 的 piping operator %>%,可以將一個output當做另一個指令的1st input,這個比起要括號配對括號的寫法的確方便很多。另外,還有來自 "dplyr" 的6個指令,包括'select', 'filter', 'arrange', 'mutate', 'group_by', 'summarise' 。在dataframe的數據處理上算十分方便。還有n, top_n, tally等一起使用。之後我把這用在處理問卷資料上已比去年方便得多了。
  • select: 根據給定的變數名稱選擇column
  • filter: 根據設定的條件做篩選row
  • arrange: 根據選定的變數內容做排列
  • mutate: 根據給定的值賦予新變數,或是變更舊變數
  • group_by: 根據給定變數做group,以銜接summarise
  • summarise: 資料整併

這些專門處理dataframe的數據,tidyverse有一個叫lubridate的套件處理日期時間,但另一方面自己所仍要找尋xts, zoo 等財務上時間序列的處理方法。見到有另一個"tidyquant"的套件,大概之後可以一試。

"tidyverse"的介紹和教學可以到:
  1. https://blog.rstudio.org/2016/09/15/tidyverse-1-0-0/
  2. http://r4ds.had.co.nz/model-basics.html

2017年1月13日 星期五

[R] Show Me The Code - Machine Learning的簡易入門

上星期去了一個程式員的講座交流活動,6個講者就著不同題目介紹和展示相關的coding。怎樣擔起一場有魅力的演說,這種能力很多時候都需要。大約10分鐘的演講,不用Powerpoint的投影片,即場示範效果和做法。同一個活動,今個星期就見到別人已經好好地寫出一篇『親睹Machine Learning辨別靚仔靚女』

收工到場時已經錯過第一位講者講的WebVR。第二位分享用elm這個前端應用開發的經驗,只有少量Javascript認識的我只記得它是讓開發者可以寫完後compile成HTML+CSS+JS,因為先編譯,就不會等到執行時才出現運行時期的錯誤。第三位的標題很吸引,如何用十分鐘開發Facebook Bot』。原來前排見過的應用程式是透過這種工具開發。這技術可以充當你專頁的回覆的機械人,也可以是當FB Messager成為你應用程式的用戶介面。講者用的應該是PHP,網上也有其他用Node.JS,Python 的示範。

「[程式開發] Facebook Messenger 聊天機器人 API 環境建置 教學 (Node.JS)」

「用 Python 開發 Facebook Bot」


第二節開始的一個講者介紹API.AI,雖然示範的只是特定句子的對答,但API.AI這家被Google收購了機械人對話開發公司,還做到更多型式的文字/語音辨析。然後見到R、Python這些比較有親切感的語言。 R有電鋸陳分享他在Network Analysis的過程中,用Rcpp套件以C寫looping 的經驗,這樣編譯和運行的時間可以比用apply function的即譯式更快。之後嘗試rJava時可以留意這個用法吧。不過他的分享中其實有很多時間是放在解釋研究的方法:怎樣的數據形式、什麼是Network analysis 的Triad Census。他做過的分析和文章可以參考明報的報道,報道版當時也讓我深感佩服,原來香港還是有做數據分析的人。

「通識導賞﹕佔領時代的facebook專頁版塊巴爾幹化社會網絡分析」

「數據新聞:香港網絡生態系列之三 沒有最撕裂 只有更撕裂——後佔領時代的Facebook專頁板塊」

用Python 的Andy展示的是所謂Machine Learning、Deep Learning 今天已經可以如何容易地做到。示範用 Keras套件 以神經網絡Neural Network 的方式分辨男或女的面孔照片。有男女各大約1300+ 張相片,32*32 pixel的黑白大頭照。轉換成共約2800行1024列的數據集。2/3 Training, 1/3 Testing。想想這件事應該可以用R 做吧?如果先準備好代表這些相片的矩陣,就可以讓R做緊接的神經網絡分析。數據仍需要準備,但Coding的例子呢? 有,Google 一下就找到 R-Bloggers 上的Coding 例子:

2016年12月29日 星期四

[R] RJDBC的例子,透過顧客行為的相似度建立推薦系統

自從之前安裝好R上的 rJava 和 RJDBC 套件(這篇:R 上安裝 RJDBC 和 rJava 的除錯),就應該可以借回那本書繼續學習R上連結用MySQL的例子。加上最近又想繼續股票短線的技術分析模型,希望將計算後的指標輸出到 Excel可以接手做試驗的形式,於是這幾天都在對著RStudio。股票方面思考過匯出怎樣的資料和格式才方便Excel處理,整理過之前的幾段Scirpt, 但想要的結果仍在做回溯測試中。而SQL的例子就可以告一段落了。
這個例子中的"Sakila"數據是MySQL 提供的樣本,假設一間DVD租售店的營運,數據庫的結構參考: https://dev.mysql.com/doc/sakila/en/sakila-structure.html。這個教學例子是利用顧客的租借記錄,以及電影的類別、分級等資料,製做一個推薦系統,為顧客推薦他可能有興趣的電影。一個方法是計算利用顧客的借閱記錄計算顧客間的相似性,這個就是下面的例子。書中也提及另一個方法是利用被電影被借閱的記錄計算電影間的相似性。實際上,更好的算法應該還要考慮在新的顧客或電影時如何更新推薦。

2016年11月21日 星期一

[R] R 上安裝 RJDBC 和 rJava 的除錯



話說早前有關R找到本不錯的教學書,試過模仿它測試股票投資策略的那一章後,正要嘗試 R與MySQL的連接,但想從書中的RODBC Library改為用RJDBC Library。當時已經安裝好MySQL,MySQL Workbench,下載了JDBC Connector 的 jar 檔,在 R 上安裝了 RJDBC Library,但要使用時卻一直在報錯而用不到。在印度的最後幾天,想起再繼續 R 的項目,跟 rJava 的設定糾纏了幾小時,在最氣餒的時候終於有了突破,一步步順利的通關。

原本報錯的情況,是在載入 library(RJDBC) 的時候,回報說在調用 library(rJava) 的 .jinit() 時出錯,找不到要用的JVM。
R> .jinit()
JavaVM: requested Java version ((null)) not available. Using Java at "" instead.
JavaVM: Failed to load JVM: /bundle/Libraries/libserver.dylib
JavaVM FATAL: Failed to load the jvm library.
Error in .jinit() : JNI_GetCreatedJavaVMs returned -1

之後己經事前準備好的:
1. R 和 Java 是本身己經在用的,本身分別搭配著 R Studio 和 Eclipse 使用

2. 安裝好MySQL 和 MySQL Workbench。記住連接用的user和pwd
下載:http://dev.mysql.com/downloads/mysql/http://dev.mysql.com/downloads/workbench/

3. 下載JDBC Connector 的jar檔:
下載:http://dev.mysql.com/downloads/connector/j/

2016年10月2日 星期日

[R] 閱後測試-R語言與股票市場的預測

原來上水圖書館的電腦類書有不少我想要的題目,打算去找點數學的書,結果卻捧了一堆電腦程序的書回來。
《巨量資料的第一步-R語言與商業應用》
《實戰Java-9個別具特色的實作經驗》
《Arduino錦囊妙計》
《Raspberry Pi 機器人自造專案》

這本學習R的書,算是我看過的R中文書當中很好的一本,特別是案例的部份的學習價值就很高。基本內容都有提及一些我不熟悉的。例如時間和時間序列的類型、資料連接SQL資料庫、處理遺留數據等。

上月初,周末加班時就帶著電腦和書,在坐車時跟著書去嘗試。誰知把書放在椅背休息一下,落車時就忘了帶走。好在一星期後發現有人已經代為把書還了圖書館,感謝這個好心人。

首先跟著這本書試的是這一章「股票市場的預測」。 它是用quandmod套件中的getSymbols()功能獲得xts時間序列類型的股價資訊。建立一個自行定義的回報觀察值去衡量價格變動,再用常見的技術分析指標作變數,建立決策樹Decision Tree的模型。最後評價模型的預測誤準確度。

2016年6月12日 星期日

[R] 複製-市盈率與後市關係之統計

最近好像少了Coding上的主題。上星期看到這篇文章:《以市盈率和股息率看後市統計》,正好想把這個作為R的練習。它統計在不同市盈率(P/E)之下,恆指在1個月以至1年之後是升還是跌。結論是:雖然恆指無論在高或低市盈率的短期(一個月)後,表現未見有特別;但當看一年或兩年後的話,則明顯升多跌少。而且市盈率越低,一年後及二年後上升的機會越大。

過程

想重複這個統計,需要的兩項資料分別是恆指收市價和恆指市盈率。在練習R時,收市價當然是用它的Library: "quantmod" 。背後的數據來源是Yahoo財經;因為今次需要的是月度資料(之後提到的恆指PE,要方便的話也是拿按月的資料),所以用compression="m";再用"zoo"格式的as.yearmon(index( )) 紀錄這類月度的時間序列。
Prices = get.hist.quote(instrument="^hsi", start="1986-01-01",end="2016-05-31", 
  quote=c("Close","AdjClose"),provider="yahoo", 
  origin="1970-01-01",compression="m", retclass="zoo")

另一方面的市盈率資料,之前為了自己弄的Excel模型就有找過。可以用恆指公司網頁上的.xls檔案。因為在MacOS上沒有再找處理excel格式的套件,所以下載回來後,我先刪去了合併儲存格的大標題、改了日期格式、和另存成我熟悉的csv檔案。

這兩項數據有不同的日期表示方式,Yahoo用的是每月首個交易日,恆指公司用的卻是每月最後一日。所以先將兩項資料都用"zoo"格式的as.yearmon(index( )) 去轉換成配合這類月度資料的時間序列。將兩個數據合併,然後在所有數據中,再抽出所想要的時間片段。而與他的例子不同的是,我選擇了1987年1月至2016年5月的資料。

一開始只是計算某一個市盈率範圍在某個時間後的表現,這個可以比較簡單可以做到。然後就想要引伸到不同情況(5種市盈率範圍、5種觀察時期),還有要把每個結果整合到一個表格中來呈現,就只想到用nested-loop的方式去計算每一個數值,然後逐步組合成用於表達的Matrix。不過,其實這方法在R的世界中好像因為執行效率的考慮而儘量避免的,會比較推崇的是Vectorization,把數據一開始便弄成更多維度的矩陣去運算。

整個結果如下圖。

2016年5月1日 星期日

賭波的初哥方式-Elo Rating System 的理解

之前在未了解背後數學之前先嘗試個應用。今個周未有空就來了解一下Elo Rating System背後是什麼理論,和如何得出那樣的公式了。

Part A)機率
先來看看「邏輯函数」Logistic Function。在很多地方都會看到它的身影,例如物種的人口增長,統計學上的對True/False這類二元結果的回歸分析。
「邏輯函数」 有這樣的一般型式:$$y = \frac{L}{ 1 + e^{-k(x-x_0)} }$$
$e$  :自然對數
$x_0$:x 的中間值
$L$  :y 的最大值
$k$  :斜度

例子一:Standard Logistic Function:$y = \frac{1}{1 + e^{-x}}$
例子二:國際象棋界 USCF 的 Elo rating system 的勝率期望值:$y = \frac{1}{1 + 10^{-\frac{1}{400}(r_A-r_B)}}$

我們考慮代入的是「分數差」(甲的分數-乙的分數), 即是$x=(r_A-r_B)$,$x_0=0$。一個函數可以作為「分數」 與「勝負機率」的轉換,大概很多$\mathbb{R} \to (0,1)$ 的函數都可以做到。而這「邏輯函数」還有以下特質::
  • 這函數可以輸入實數的「分數差」,而輸出0到1之間的機率值;而且數值是不斷上升的,所以差異愈大,贏(輸)機率就愈大。(這兩個特質就適合用來作"分數差" 和"輸贏機率"之間的轉換)
  • 零作為中間點是反向對稱的 $Pr(x)=1-Pr(-x)$,高分方的勝率等於低分方的負率。當雙方實力相等,也就是"分數差"在等於零的時候,輸贏的機率是0.5。
  • 而差異愈接近零的時候機率的變化的速度較大;但差異愈大的時候,這個機率的變化速度就愈不明顯。(這個有點像經濟學上「邊際效益遞減」的概念,現實上有點猶豫)


「邏輯函数」 在統計模型的重要性在於與「邏輯迴歸」Logistic Regression 的關係。

Logistic Regression Model與一般的「簡單線性迴歸」 Ordinary Linear Regression都是屬於GLM的其中一員,分別在於對「應變數」Dependent Variable的分佈,和所謂的「連結函數」Link Function有不同假設。Logistic Regression Model中,Y 的分佈是要配合"勝/負"這類二元結果, 連結函數的不同就得出機會率可以寫成Logistic Function的形式。Logistic Regression :
$$logit( E [Y | X] ) = ln(\frac{p}{1-p}) = \beta X$$
對觀察值Y的分佈假設為 $Y \sim Binomial (1 , p) $。上式經過移項後會得到:$p = \frac{1}{1 + e^{-\beta X}}$,也就是開始時所見的Logistic Function的形式。



終於,我們回來看看Elo Ratings中的機率公式:
$$S_{expect} = \frac{1}{1 + 10^{-\frac{1}{400}(r_A-r_B)}}$$
  1. 從 $e$ 變成 10的次方:因為  $10^x   =  {e^{ln(10)}}^x  =e^{ln(10)x} $,這只是在$k$值的影響。
  2. $k$:1/400,這個斜度是雙方選手的分數差如何轉換到 0-1的比例上。例如當同樣估計為A勝B,但估計的機率是60%還是70%就是這k值影響到。在線性回歸中我們會用OLS的方法去求取參數,在 Logistic Regression中參數是用「最大似然估計」Maximum Likelihood Estimation (MLE)找出來。
  3. $r_A, r_B$:選手的分數,這裡並不是一個可以直接觀察到的自變數,如何得出這分數就是Elo Rating 的另一重要部份。
**所以,簡單而言Elo Ratings 就是一套Logistic Regression model,(還有加上選手的評分方式,和如何不斷更新分數)**


Part B)分數
每名棋手會有一個初始分數$r_0$,然隨著實際對賽的結果,用以下公式更新棋手成積:

$$r_{post} = r_{pre} + K (S_{actual} - S_{expect})$$
$r_{post}$:對賽後棋手經調整後的分數。
$r_{pre}$:對賽前棋手原來的分數。
$S_{actual}$:實際結果,簡單可以設定:贏=1分,輸=0分,和=0.5分。
$S_{expect}$:預期結果,就是PartA計算甲會贏的機率公式。
$K$:這一般稱作attenuation factor,是調整新結果的影響和原有分數之間的比重。
一般會有這些考慮:假設比賽結果對新手影響較大,假設重要比賽的影響較大。

因為兩個等級的選手對賽,可以預期分數高的有較大贏面。棋手的分數要值得調整,他應該要表現得超越自己原有等級所預期的水準。Elo Rating更新分數的公式的設計就是為了達到這個效果。

另外,例如有 1200分的棋手A 和 1000分的棋手B 比賽:A,B的預期贏面分別算出是76%, 24%。 A勝出只會增加$0.24K$的分數,B勝出卻會增加$0.74K$的分數。所以:贏(輸)了該贏(輸)的比賽,分數不會有大幅調整;但如果出現戲劇性的結果,分數的調整就會較大。

Part C)應用
這套Elo Rating System在以下幾方面都有被應用:
遊戲:
    League Of Legends
http://leagueoflegends.wikia.com/wiki/Elo_rating_system

國際象棋界:
    World Chess Federation (FIDE)
https://www.fide.com/fide/handbook.html?id=172&view=article

足球:
    World Football Elo Ratings
http://www.eloratings.net/system.html

    FIFA Women's World Rankings
http://www.fifa.com/worldranking/procedureandschedule/womenprocedure/index.html
http://resources.fifa.com/mm/document/fifafacts/r%26a-wwr/52/00/99/fs-590_06e_wwr-new.pdf

     Footballdatabase.com (雖然無提供背後的模型,但如果沒有數據作自行測試的話也可以一看)
http://footballdatabase.com/ranking/europe/1

因為各方面的比賽有不同特質,所以模型參數略有不同。用以上的 FIFA Women’s World Ranking (WWR) 的模型去看足球方面的實際運作(這裡修改了官方符號方便表示)
$$S_{expect} = 1 / (1 + 10^{x/2})$$
$$ r_{new}  = r_{old}  +  K ( S_{actual} - S_{expect} )$$

文件中稱當中 $x = [r_A - r_B] / (\text{scaling factor})$。scaling factor是為了令新隊伍從1000分開始;對賽中每100分的差距做成64%的的機會勝出。用Excel模擬一下會得到它的scaling factor = -200,所以一樣是這條式:$S_{expect} = 1 / (1 + 10^{-\frac{1}{400}(r_A-r_B)})$


  • 它們對模型的修改上考慮到入球數目的不同:

  • 主場的優勢:主隊加100分
"A glance at the historical results shows that teams perform better at home than away; the home teams keep 66% of the points, while the opponents return home with 34%. To neutralise this effect, a correction is made by enhancing the rating of the home team by a value of 100 points (corresponding to 64%)."
  • 對於賽事重要性:

  • 參考的時間歷史:45年的比賽紀錄,在評分的角度上還可以接受,但我覺得對勝負機會率的目的來說就太多。現在的球隊隊員跟好幾年前的早就不同了吧。
"Solid foundation: some 6500 games since 1971"

  • 開始評分所需的數據:其實我覺得這套方式比較適合LOL遊戲平台上的計分,那時每次分數更新反映的是一個學習過程。但在象棋/足球這類大量練習,然後參加一場聯賽的情況中,每次分數更新就像是尋求反映真正實力的過程,這就要有足夠對實往績能達到效果。事實上,也因為Logistic Regression 的參數是用到MLE的方法,一般需要的樣本數也要較大。
"The ranking of a team is deemed official when:They have played at least 5 matches against teams with an official ranking. etc..."


------------
最後一部份,我是懷疑是否有關的,是這套評分和Exponential Distribution的關係。
因為:$A, B \sim Exp(1)  \Rightarrow   x_0 - \beta ln(A/B) \sim Logistic(x_0, \beta)$

設$R_A, R_B \sim Exp(\dot)$   A,B 是某種實力的量度。Exponential distribution 的圖明顯與Normal Distribution 不同的,它假設選手的$R_A, R_B$ 大多是在低實力區,高手則愈來愈少。它還有一個特點,是分佈上的「無記憶性質」(Memoryless):$Pr(X>m+n|X>m) = Pr(X>n)$ 。對給定的任意一個參考分數而言,比你高同樣n級的比例是一樣的。用一個效果比喻:無論是在哪一級的角色,在下一個等級之前,總是有面前的人當中最弱的3%等著你去超越。
( 以$Exp(1/30)$為例。平均等級是30級。R:pexp(1, rate=1/30) )

設$R_a=ln(R_A), R_b=ln(R_B)$ 。用$ln()$將實力的比例尺轉變成方便比較的分數,$log()$這個運算的起源,是當年在未有計算機的發明之前,有一樣叫對數表的工具,為了方便計算大數的乘法。
$a-b = ln(exp(Ra-Rb)) = ln(exp(Ra)/exp(Rb)) = ln(A/B) \sim Logistic(0,1)$
這就得出分數差會符合Logistic Distribution.

但這是否有什麼意義呢?未想清楚。。。
------------

2016年3月31日 星期四

賭波的初哥方式-Least Square Estimation & Elo Rating System

星期三放假在家,空閒的時間再嘗試一下去年的足球博彩模型。當時因為自己讀過點數學和統計,一直想有點實際的應用;朋友V想用模型預測球賽結果和博彩,而我工作時又會弄點程式來方便日常工作,所以去年就和我嘗試提高預測球賽結果的賺錢機會,以及做點自動化的工具。

去年,加入的是一個為每隊評分的方法。假設每隊有一個代表綜合實力的分數-Rating,而得失球的差-Score只是兩隊分數的差。用過往每隊的對賽結果,放入一個方程組(System of Linear Equations) $\underline{HA \times teamRank=Score}$ 去求最小方差(Least square estimation)的解,就可以反求出這些分數。
$$
\begin{bmatrix}
1 & 0 & 0 & -1 \\
0 & 1 & -1 & 0 \\
-1 & 0 & 1 & 0 \\
0 & -1 & 0 & 1 \\
0 & 0 & -1 & 1 \\
-1 & 1 & 0 & 0 \\
0 & 0 & 1 & -1 \\
1 & -1 & 0 & 0 \\
1 & 0 & 0 & -1 \\
-1 & 0 & 0 & 1 \\
0 & -1 & 1 & 0 \\
0 & 1 & 0 & -1 \\
0 & 1 & 0 & -1 \end{bmatrix}
\times
\begin{bmatrix}
1.375 \\
2 \\
-2.5 \\
-0.875 \end{bmatrix}
=
\begin{bmatrix}
2 \\
8 \\
-5 \\
-1 \\
4 \\
1 \\
1 \\
0 \\
-3 \\
-2 \\
2 \\
4 \end{bmatrix}$$
當然,我們想做的是把這些運算交給電腦。當只要做好數據的準備,在R上除了數據的輸入和顯示外,重要的運算就只是一行Coding:
teamRank = ginv(HA) %*% score;
以2013-2014年度英超對賽的紀錄作計算,最好幾隊分別是:
  1. 曼城=1.625
  2. 利物浦=1.275
  3. 車路士=1.1
  4. 阿仙奴=0.675
  5. 愛華頓=0.55
假如曼城和愛華頓對賽,期望值為曼城勝愛華頓1.125球。但只用一個期望值還未能反映這些隨機變數的離散程度,所以要看見多大的期望值才有信心下注?在求出得失球差的分佈之前,這還是要靠主觀觀察/回溯測試來判斷。

2016年2月20日 星期六

[Math] Office Work - 從編排更表到Hungarian Algorithm

因為會處理歐美收市和亞洲收市,所以我這組人的繁忙時間是清早和晚上兩端,需要有輪班制,工作分早晚兩更,據英文堂所學這種工作時間有個形容詞是antisocial hour, 人手足夠時就可以讓同事返九點左右的正常時間。編更上如何令大家滿意,這問題幾似數學Operational Research / Graph Theory中的 Matching problem。大概最近FB見到恆隆同伯賴段片,數學應用的頭腦靈活過來,想到還是可以用典型的Hungarian Algorithm。這演算法所處理的情況是:假設有n個任務需要分派給n個人,每人要完成各個任務都有某個成本,問如何編配任務才能讓總成本最少。

例如成員 i 要處理任務 j 的成本是cij,這些成本可以寫成矩陣C表示。例如第一個人p1處理任務一task1要成本1, p1 處理 task2 要成本5, p1 處理 task3 要成本3;分派方法可以寫成矩陣A,這簡單例子的最佳分配可以直觀得知如下, 總成本為6。而Hungarian Algorithm 的步驟是這樣,大致有以下程序:(一)將所有數值減去該行最小的數,然後再將所有數值減去該列最小的數,今每行、列都有零存在。(二)[Trial and Error] 找出一個"Independent zero"的組合,用最少條線穿過所有零。(三)如果剛好存在於n條線上,該"Independent zero"組合就可以得出答案;如果只需少過n條線,修改矩陣重覆步驟二。

$$
C=\begin{bmatrix}
1 & 5 & 3 \\
4 & 2 & 8 \\
7 & 9 & 3 \end{bmatrix},
A=\begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1 \end{bmatrix}
$$