基于 MM 算法對 BT 模型的排序

一、前言

現實生活中個體間的差異與優劣往往是以兩兩比對的形式進行,但是兩個個體間的比對有時候會出現如下的困境:設想有下面這一種循環的情況, a 個體戰勝了 b 個體,而 b 個體又戰勝了 c 個體,且 c 個體戰勝了 a 個體,它們的實力應該如何評估呢?又設想一下我們的跆拳道比賽,足球比賽,勝負輸贏情況繁復,我們又以怎樣的標準來評估各個體的實力值呢?

簡單來說,我們完成的是一個基于 Mongo DB 和 Node.js 的后端框架,提供 API 用于實現這種兩兩比對之后的實力值評估。

二、問題定義

1、輸入

我們程序的輸入包含每場比賽的輸贏情況:比如記錄了三場賽事, a 戰勝了 b , a 戰勝了 c , b 戰勝了 c ,那么我們只需要提供一串包含這些比賽信息的字符串“0 a b|1 a c|2 b c”作為輸入即可,數字表示比賽的 ID 號,重復提交相同 ID 的比賽,后一個數據項會覆蓋前一個數據項。當然,我們也提供刪除比賽的 API ,如果想刪除比賽 0 , 1 和 4 ,那么我們只需要提供字符串“0|1|4”即可。輸入方式為將上述指定的字符串通過 POST 的方式發送到服務器對于 URL 即可。

具體來說,想要添加比賽的輸贏情況, POST 上述規定的字符串到“/add”;想要刪除比賽的輸贏情況, POST 上述規定的字符串到“/delete”。

2、輸出

我們程序的輸出包含了各個個體的實力值,格式為 JSON 。

也許這么解釋會過于的抽象,更多的信息請參考我們已經完成的一個前端的 Demo 源碼,里面使用了每一條 API 指令,并有詳細的注釋。

三、算法描述

我們設計的思想來自于圍棋 AI 的選子算法,所參考的論文是《Factorization Ranking Model for Move Prediction in the Game of Go》。在論文中,作者利用 MM 算法構建了一個排序算法來對復雜化的 BT 模型(也就是論文中的 FBT 模型)進行排序。

1、知識鋪墊

1.1 BT 模型

BT 模型是一種用來預測比較結果的概率模型,全稱是 Bradley-Terry 模型。下面我將舉出一個形象化的例子,假設有兩個個體 i 和 j , Pi 和 Pj 分別表示這兩個個體的實力值,那么在一次比賽中, i 戰勝 j 的概率就可以用下面這個式子來表示:

事實上, BT 模型可以有很多參數化的表示,比如我們可以用 e 的 n 次冪的形式來替代簡單的線性形式:

BT 模型之所以那么構建,有著嚴謹的數據論證[1],這里不再贅述。

1.2 MM 算法

MM 算法準確來說不是一種算法,它其實是對如何得出優秀算法的一種描述。 MM 是 majorize/minimize 或者 minorize/maximize 的縮寫,兩者的區別僅在于一個試圖求出最大值,一個試圖求出最小值,兩者所用到的方法是完全相同的,下面我將以 minorize/maximize 為例,簡單地介紹一下 MM 算法:

如果存在一個函數 M(θ|θ_m) 滿足:

對于所有的 θ ,有 M(θ│θ_m) ≤ f(θ)

且 M(θ_m│θ_m) = f(θ_m)

那么我們就稱它 minorize 了函數 。

此時,我們取出函數 M(θ|θm) 的最大值 θ(m+1) ,并在該點構建新的函數 M(θ|θ_(m+1)) 以此不斷地迭代, θ_m 將會趨于函數 f(θ) 的最大值,我們的目的也便達成。我們再來用一張圖來表示這個具體的過程:

[圖1 MM 算法的迭代]

但是讀者可能會問了,求函數的最值何必那么復雜呢,求出函數的導數畫出函數的圖像不就可以十分精確地求出極大值了么?誠然,對于一些簡單的函數比如初等函數或是初等函數的復函數我們確實可以通過求導的方式輕松地解決最值問題,但是如果一個函數是離散的,甚至說一個函數的自變量根本不是一個數,那么它的導數也便無從定義了。在我們的算法中, θ 便不是一個數字,你可以將其看做是一個高維的向量,或者是數的集合,這個時候我們需要用 MM 算法不斷迭代,以求出近似的最值。

1.3 超平面上的凸函數

超平面是 n 維歐氏空間中余維度等于一的線性子空間。這是平面中的直線、空間中的平面之推廣。

它有如下性質,如果 h(x) 是一個凸函數,那么有:

這里涉及到的是純數學,其論證仍不在這里贅述[2]。

2、對自己算法的描述

有了上面的鋪墊,我們就可以理解 MM 算法是如何對 BT 模型進行排序的了。我們假設有很多支足球隊,其中有兩支球隊被標記為 i 和 j ,我們先假定它們的實力值為 Pi 和 Pj (在程序之初所有隊伍的實力值被初始化為一個常數,經過我們的多次嘗試,為了達到一個最令人舒適的結果,我們將其初始化為 100 ),那么根據我們前面提到的對 BT 模型的線性定義, i 球隊戰勝 j 球隊的概率就可以被表示為:

現在我們將這個思路拓展到任意兩支球隊,設置計數器 bij 為 i 戰勝 j 的次數,那么一張任意的輸贏表(一個歷史戰局,比如一場世界杯結束后所有的輸贏情況,這里可能會比較難理解)就可以被表示為:

眾所周知,計算機的計算精度極其有限的,如果比賽場次眾多,假如有100場比賽,其中每支隊伍的實力值均相等,那么這個概率 L(θ) 就等于 0.5^100 ,這個數字普通的 PC 不通過特殊的算法已經很難表示,因此我們對這個概率值取對數。依賴于對數函數良好的單調性,我們只需要求出對數函數最值時的自變量即是使概率最大化的自變量。

讀者可能又會問了,這樣對 L(θ) 的表示不把一支球隊自己踢自己的情況計算進去了?的確如此,所以我們需要使用算法者格外小心地維護自己的數據:一個合法的數據是不存在自己戰勝自己的情況的,即 bij 為 0 ,任何數的 0 次冪均為 1 ,它并不影響求積結果。

正如上面所述,我們對 L(θ) 取對數,并定義為 f(θ) ,則:

根據前面對 MM 算法的描述,我們需要找到一個函數 M(θ|θ_m) 讓其和 f(θ) 滿足對 MM 算法的定義。我們考慮“放縮” -ln?(θ_i+ θ_j) ,不妨設為 h(x) = -ln?x 。那么根據超平面上凸函數的性質,有下面這個不等式成立:

令 y= θ_i^n +θ_j^n , x 仍滿足我們之前的定義 x= θ_i +θ_j ,帶入上面 f(θ) 的表達式,則有:

這里 n 表示第 n 次迭代,并不是指 n 次冪; θ_i^n 和 θ_j^n 是上一次的計算結果,在我們的程序中被初始化為了 100 ; θ 可以被看做是一個高維的向量,或者是數的集合,而等式右側的 θ_i 和 θ_j 為其中的一項。

我們對上面得到的這個 M(θ│θ_n ) 稍作檢查,便可以發現它滿足 MM 算法的要求,也就是說它 minorize 了函數 f(θ) 。根據一些巧妙的運算,我們就可以得到:

具體的計算過程仍為數學過程,這里也不多贅述。

照此不斷迭代,我們便可以得到“可能性”的最大值,這意味著什么呢?讓我們再次來梳理一下邏輯:我們首先假定每支球隊的實力均為 100 ,依此計算出了發生輸入的這張輸贏表發生的概率,然后我們通過 MM 算法不斷地迭代,修改每支球隊的實力值以使這張輸贏表發生的概率增大,可能性越大,便可說明我們對每支隊伍的實力評估越接近現實,當達到一定精度的時候,我們便可以根據實力值,得出排名。這就是利用 MM 算法對 BT 模型的排序。

四、實驗結果

1、用 C / C++ 完成的簡單測試

為了確保算法的有效性,我們沒有十分魯莽地直接用它來搭建服務器,而是先寫了一個 C / C++ 的小程序來進行測試。我們測試的思路是這樣的:

我們先用隨機數產生了 100 個個體,每個個體有 0 到 99 之間整數的實力值。我們根據這個實力值利用 BT 模型來模擬比賽,比賽的輸贏概率遵從 BT 模型線性形式的定義,兩兩個體之間比賽 100 場。

上述過程是我們程序的預處理階段,接下來我們便用這 100 場比賽的輸贏情況來評估每個個體的實力,如果我們評估出的實力與我們設定的相似,則說明我們算法是有效的。輸出結果如下:

[圖2 MM 算法對 BT 模型排序 C / C++ 實驗]

輸出分為四列,第一列為個體的序號,第二列為我們給它設定的實力值,第三列為我們給它的評分,第四列為個體被設定的實力值與我們給它評定的實力值的比值。我們可以看到,第四列的值穩定在 0.4 左右,說明我們對各個體實力評估是相當準確的。這里沒必要展示所有的 100 項結果,所以上圖僅展示其中的前 20 項。

2、后端框架

我們收集了最近 3 屆世界杯(不含預選賽)的所有比賽數據,依次為據給每支球隊打分并排序,數據總結如下:

[圖3 世界杯數據文件]

讀者可能會發現這個文件的格式并不符合論文第二部分里的定義,我們寫了一個簡單的程序來轉換格式,由于程序十分簡單,這里也不多說。

程序的具體啟動方法將在附錄中進行詳細的說明,這里只做展示。

[圖4 啟動數據庫 Mongo DB ]

[圖5 啟動服務器]

[圖6 進入“demo/”文件夾]

演示的樣例在項目的“demo/”文件夾中,確保服務器正確運行之后,雙擊其中的“index.html”文件即可運行網站,網站上則會顯示世界杯前 10 名的排名:

[圖7 世界杯前 10 及其實力值]

在這里只顯示了前 10 名,如果你想知道其他球隊的排名,在右上角的搜索框中搜索即可:

[圖8 搜索未參與近年世界杯的球隊]

[圖9 搜索參與過近年世界杯的球隊]

我們對比了世界足聯給出的官方數據,發現我們的評分是可靠的。

最后,我們再簡單的介紹一下源碼[3],以分析其實如何工作的。后端框架的代碼比較復雜,也是我們程序的核心,但是它不是展示的內容,有興趣的讀者可以下載之后自行研究,我們這里只講講前端代碼是如何工作的。

打開“demo/js/footballRank.js”,代碼如下:

[圖10 Demo 的 js 文件]

第 5 行我們將最近三屆所有世界杯輸贏信息 POST 到了服務器,第 8 行我們通過 GET 方法從服務器獲取每支隊伍的實力值,第 27 行開始為我們事先搜索框邏輯部分的代碼。

五、總結

在我們日常生活中,很多比較都是兩兩個體之間進行的:

<img src='http://upload-images.jianshu.io/upload_images/3433108-68afd58aaf25aa6a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240' width='24%'/>
<img src='http://upload-images.jianshu.io/upload_images/3433108-d0df0f4253b844a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240' width='24%'/>
<img src='http://upload-images.jianshu.io/upload_images/3433108-c6df6006fc1ae3ed.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240' width='24%'/>
<img src='http://upload-images.jianshu.io/upload_images/3433108-1776c095d3c87de3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240' width='24%'/>

[圖11 日常生活中兩兩比較的競爭]

比如游戲中的圍棋、爐石傳說,體育中的足球、跆拳道等,我們應該如何對玩家或選手進行排位?如何去評估他們的實力呢?比較簡單的方法有以下幾個,我將一一的指出它們的缺點,并闡述為什么說我們提供的算法是可靠的。

按照個體的勝率? 假設有這樣一種情況,一個個體僅參加過幾次比賽,而他恰巧遇到的對手都是實力很弱的,假設這個個體贏得了比賽,那么他的勝率會是100%,但事實上他的實力并不一定強。

按照個體獲勝的場數? 假設有這樣一種情況,圍棋高手李世石和 Alpha Go 過招, Alpha Go 屢次戰勝李世石,顯然它的實力高過李世石,但是如果以獲勝場數來評估,李世石會被錯誤地評估為比 Alpha Go 更強。

按照獲勝加分?輸場扣分? 上面李世石和 Alpha Go 的例子仍能駁倒這種評分方法。

那么我們憑什么說用 MM 算法對 BT 模型排序就是極優的呢?我們還是舉出一個例子來證明, Alpha Go 屢次戰勝李世石說明其水平更高,盡管其參加的比賽場次數很少,在我們的算法中, Alpha Go 初始實力為 100 ,假設李世石實力已有 500, 那么 Alpha Go 戰勝李世石的概率僅有 ,這并不能讓概率達到較大的值,所以在迭代時為了使 BT 模型概率最大化, MM 算法會不斷調高 Alpha Go 實力值以達到最優,我們的算法僅需2、3次就可以讓 Alpha Go 實力值超越李世石,這與事實的客觀實力估計是十分契合的。

六、附錄

1、實驗環境

我們沒有進行性能方面的比較,因此我們也不詳細說明電腦的配置了。我們的程序運行在一臺 Macbook Pro 以及一臺 Macbook Air 上,操作系統均為 OS X El Capitan 版本 10.11.5 ,使用的編輯器為 Sublime Text 3,瀏覽器為 Chrome。

2、如何運行程序

正如在第四部分中所講的那樣,我們的代碼分為兩個部分: C++ 的簡單測試程序以及我們的后端服務器框架。

對于前者,只需要簡單的編譯運行即可;對于后者,想要運行起來會比較困難,但是如果電腦上已經安裝過 Mongo DB 和 Node.js ,那么運行也就很簡單了。 Mongo DB 和 Node.js 是目前Web很通用的兩款工具,具體的安裝過程網上提供了很多的教程,在這里也不再贅述。

安裝好這兩款工具后,在命令行中打開工程目錄,運行“mongod -dbpath data/”,確保數據庫正常運行起來之后,新建命令行窗口,運行“node index.js”即可啟動服務器。

我們提供了一個 Demo 網站,在完成服務器的啟動之后直接運行 Demo 的 HTML 頁面即可,你可以通過瀏覽器的 Network 監視來進一步地了解這個網站工作的原理。

3、參考

  1. 對于 BT 模型的更多信息可以參考它的維基百科:https://en.wikipedia.org/wiki/Bradley%E2%80%93Terry_model
  2. 對于超平面的更多信息可以參考它的危機百科:https://en.wikipedia.org/wiki/Hyperplane
  3. 我們的項目代碼請從 Github 上下載,如果覺得有意思的話歡迎點贊:https://github.com/An0nym6/Bradley-TerryRankingTemplate

在我博客上面的鏈接:傳送門

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這篇文章的技術難度會低一些,主要是對推薦系統所涉及到的各部分內容進行介紹,以及給出一些推薦系統的常用算法,比起技術...
    我偏笑_NSNirvana閱讀 12,159評論 5 89
  • 轉載 http://blog.csdn.net/zouxy09 EM算法是一種迭代算法,用于含有隱含變量的概率模型...
    Jlan閱讀 2,183評論 1 13
  • AI人工智能時代,機器學習,深度學習作為其核心,本文主要介紹機器學習的基礎算法,以詳細線介紹 線性回歸算法 及其 ...
    erixhao閱讀 13,961評論 0 36
  • 前言 已經很久沒有寫博客了,我的博客一般都是對我工作中遇到的問題的一個總結已經自己學習中遇到的一些心得,剛剛迭代的...
    iOScoderZZJ閱讀 596評論 0 9
  • 和朋友約好一起去逛街,其實也不是有多少東西非要去買,只是長大了就連一起出去走走的時間好像都需要提前預約一般。 ...
    晨喵喵閱讀 175評論 0 0