什麼是熵(Entropy)
簡單來講,熵是表示物質系統狀態的一種度量,用它老表徵系統的無序程度。熵越大,系統越無序,意味着系統結構和運動的不肯定和無規則;反之,,熵越小,系統越有序,意味着具備肯定和有規則的運動狀態。熵的中文意思是熱量被溫度除的商。負熵是物質系統有序化,組織化,複雜化狀態的一種度量。git
熵最先來原於物理學. 德國物理學家魯道夫·克勞修斯首次提出熵的概念,用來表示任何一種能量在空間中分佈的均勻程度,能量分佈得越均勻,熵就越大。github
- 一滴墨水滴在清水中,部成了一杯淡藍色溶液
- 熱水晾在空氣中,熱量會傳到空氣中,最後使得溫度一致
更多的一些生活中的例子:web
- 熵力的一個例子是耳機線,咱們將耳機線整理好放進口袋,下次再拿出來已經亂了。讓耳機線亂掉的看不見的「力」就是熵力,耳機線喜歡變成更混亂。
- 熵力另外一個具體的例子是彈性力。一根彈簧的力,就是熵力。 胡克定律其實也是一種熵力的表現。
- 萬有引力也是熵力的一種(熱烈討論的話題)。
- 渾水澄清[1]
因而從微觀看,熵就表現了這個系統所處狀態的不肯定性程度。香農,描述一個信息系統的時候就借用了熵的概念,這裏熵表示的是這個信息系統的平均信息量(平均不肯定程度)。算法
最大熵模型
咱們在投資時經常講不要把全部的雞蛋放在一個籃子裏,這樣能夠下降風險。在信息處理中,這個原理一樣適用。在數學上,這個原理稱爲最大熵原理(the maximum entropy principle)。網絡
讓咱們看一個拼音轉漢字的簡單的例子。假如輸入的拼音是"wang-xiao-bo",利用語言模型,根據有限的上下文(好比前兩個詞),咱們能給出兩個最多見的名字「王小波」和「王曉波 」。至於要惟一肯定是哪一個名字就難了,即便利用較長的上下文也作不到。固然,咱們知道若是通篇文章是介紹文學的,做家王小波的可能性就較大;而在討論兩岸關係時,臺灣學者王曉波的可能性會較大。在上面的例子中,咱們只須要綜合兩類不一樣的信息,即主題信息和上下文信息。雖然有很多湊合的辦法,好比:分紅成千上萬種的不一樣的主題單獨處理,或者對每種信息的做用加權平均等等,但都不能準確而圓滿地解決問題,這樣比如之前咱們談到的行星運動模型中的小圓套大圓打補丁的方法。在不少應用中,咱們須要綜合幾十甚至上百種不一樣的信息,這種小圓套大圓的方法顯然行不通。函數
數學上最漂亮的辦法是最大熵(maximum entropy)模型,它至關於行星運動的橢圓模型。「最大熵」這個名詞聽起來很深奧,可是它的原理很簡單,咱們天天都在用。說白了,就是要保留所有的不肯定性,將風險降到最小。工具
回到咱們剛纔談到的拼音轉漢字的例子,咱們已知兩種信息,第一,根據語言模型,wangxiao-bo能夠被轉換成王曉波和王小波;第二,根據主題,王小波是做家,《黃金時代》的做者等等,而王曉波是臺灣研究兩岸關係的學者。所以,咱們就能夠創建一個最大熵模型,同時知足這兩種信息。如今的問題是,這樣一個模型是否存在。匈牙利著名數學家、信息論最高獎香農獎得主希薩(Csiszar)證實,對任何一組不自相矛盾的信息,這個最大熵模型不只存在,並且是惟一的。並且它們都有同一個很是簡單的形式 -- 指數函數。下面公式是根據上下文(前兩個詞)和主題預測下一個詞的最大熵模型,其中 w3 是要預測的詞(王曉波或者王小波)w1 和 w2 是它的前兩個字(好比說它們分別是「出版」,和「」),也就是其上下文的一個大體估計,subject 表示主題。spa
咱們看到,在上面的公式中,有幾個參數 lambda 和 Z ,他們須要經過觀測數據訓練出來。最大熵模型在形式上是最漂亮的統計模型,而在實現上是最複雜的模型之一。.net
咱們上次談到用最大熵模型能夠將各類信息綜合在一塊兒。咱們留下一個問題沒有回答,就是如何構造最大熵模型。咱們已經全部的最大熵模型都是指數函數的形式,如今只須要肯定指數函數的參數就能夠了,這個過程稱爲模型的訓練。翻譯
最原始的最大熵模型的訓練方法是一種稱爲通用迭代算法 GIS(generalized iterative scaling) 的迭代 算法。GIS 的原理並不複雜,大體能夠歸納爲如下幾個步驟:
1. 假定第零次迭代的初始模型爲等機率的均勻分佈。
2. 用第 N 次迭代的模型來估算每種信息特徵在訓練數據中的分佈,若是超過了實際的,就把相應的模型參數變小;不然,將它們便大。
3. 重複步驟 2 直到收斂。
GIS 最先是由 Darroch 和 Ratcliff 在七十年代提出的。可是,這兩人沒有能對這種算法的物理含義進行很好地解釋。後來是由數學家希薩(Csiszar)解釋清楚的,所以,人們在談到這個算法時,老是同時引用 Darroch 和Ratcliff 以及希薩的兩篇論文。GIS 算法每次迭代的時間都很長,須要迭代不少次才能收斂,並且不太穩定,即便在 64 位計算機上都會出現溢出。所以,在實際應用中不多有人真正使用 GIS。你們只是經過它來了解最大熵模型的算法。
八十年代,頗有天才的孿生兄弟的達拉皮垂(Della Pietra)在 IBM 對 GIS 算法進行了兩方面的改進,提出了改進迭代算法 IIS(improved iterative scaling)。這使得最大熵模型的訓練時間縮短了一到兩個數量級。這樣最大熵模型纔有可能變得實用。即便如此,在當時也只有 IBM 有條件是用最大熵模型。
因爲最大熵模型在數學上十分完美,對科學家們有很大的誘惑力,所以很多研究者試圖把本身的問題用一個相似最大熵的近似模型去套。誰知這一近似,最大熵模型就變得不完美了,結果可想而知,比打補丁的湊合的方法也好不了多少。因而,很多熱心人又放棄了這種方法。第一個在實際信息處理應用中驗證了最大熵模型的優點的,是賓夕法尼亞大學馬庫斯的另外一個高徒原 IBM 現微軟的研究員拉納帕提(Adwait Ratnaparkhi)。拉納帕提的聰明之處在於他沒有對最大熵模型進行近似,而是找到了幾個最適合用最大熵模型、而計算量相對不太大的天然語言處理問題,好比詞性標註和句法分析。拉納帕提成功地將上下文信息、詞性(名詞、動詞和形容詞等)、句子成分(主謂賓)經過最大熵模型結合起來,作出了當時世界上最好的詞性標識系統和句法分析器。拉納帕提的論文發表後讓人們耳目一新。拉納帕提的詞性標註系統,至今仍然是使用單一方法最好的系統。科學家們從拉納帕提的成就中,又看到了用最大熵模型解決複雜的文字信息處理的但願。
可是,最大熵模型的計算量仍然是個攔路虎。我在學校時花了很長時間考慮如何簡化最大熵模型的計算量。終於有一天,我對個人導師說,我發現一種數學變換,能夠將大部分最大熵模型的訓練時間在 IIS 的基礎上減小兩個數量級。我在黑板上推導了一個多小時,他沒有找出個人推導中的任何破綻,接着他又回去想了兩天,而後告訴我個人算法是對的。今後,咱們就建造了一些很大的最大熵模型。這些模型比修修補補的湊合的方法好很多。即便在我找到了快速訓練算法之後,爲了訓練一個包含上下文信息,主題信息和語法信息的文法模型(language model),我並行使用了20 臺當時最快的 SUN 工做站,仍然計算了三個月。因而可知最大熵模型的複雜的一面。
最大熵模型,能夠說是集簡與繁於一體,形式簡單,實現複雜。值得一提的是,在Google的不少產品中,好比機器翻譯,都直接或間接地用到了最大熵模型。
講到這裏,讀者也許會問,當年最先改進最大熵模型算法的達拉皮垂兄弟這些年難道沒有作任何事嗎?他們在九十年代初賈里尼克離開 IBM 後,也退出了學術界,而到在金融界大顯身手。他們兩人和不少 IBM 語音識別的同事一同到了一家當時還不大,但如今是世界上最成功對衝基金(hedge fund)公司----文藝復興技術公司 (Renaissance Technologies)。咱們知道,決定股票漲落的因素可能有幾十甚至上百種,而最大熵方法偏偏能找到一個同時知足成千上萬種不一樣條件的模型。達拉皮垂兄弟等科學家在那裏,用於最大熵模型和其餘一些先進的數學工具對股票預測,得到了巨大的成功。從該基金 1988 年創立至今,它的淨回報率高達平均每一年 34%。也就是說,若是 1988 年你在該基金投入一塊錢,今天你能獲得 200 塊錢。這個業績,遠遠超過股神巴菲特的旗艦公司伯克夏哈撒韋(Berkshire Hathaway)。同期,伯克夏哈撒韋的總回報是 16 倍。
值得一提的是,信息處理的不少數學手段,包括隱含馬爾可夫模型、子波變換、貝葉斯網絡等等,在華爾街多有直接的應用。因而可知,數學模型的做用。
HMM(隱馬爾可夫模型)
隱馬爾可夫模型(Hidden Markov Model,HMM)是統計模型,它用來描述一個含有隱含未知參數的馬爾可夫過程。其難點是從可觀察的參數中肯定該過程的隱含參數。而後利用這些參數來做進一步的分析,例如模式識別。
是在被建模的系統被認爲是一個馬爾可夫過程與未觀測到的(隱藏的)的狀態的統計馬爾可夫模型。
下面用一個簡單的例子來闡述:
假設我手裏有三個不一樣的骰子。第一個骰子是咱們日常見的骰子(稱這個骰子爲D6),6個面,每一個面(1,2,3,4,5,6)出現的機率是1/6。第二個骰子是個四面體(稱這個骰子爲D4),每一個面(1,2,3,4)出現的機率是1/4。第三個骰子有八個面(稱這個骰子爲D8),每一個面(1,2,3,4,5,6,7,8)出現的機率是1/8。
假設咱們開始擲骰子,咱們先從三個骰子裏挑一個,挑到每個骰子的機率都是1/3。而後咱們擲骰子,獲得一個數字,1,2,3,4,5,6,7,8中的一個。不停的重複上述過程,咱們會獲得一串數字,每一個數字都是1,2,3,4,5,6,7,8中的一個。例如咱們可能獲得這麼一串數字(擲骰子10次):1 6 3 5 2 7 3 5 2 4
這串數字叫作可見狀態鏈。可是在隱馬爾可夫模型中,咱們不只僅有這麼一串可見狀態鏈,還有一串隱含狀態鏈。在這個例子裏,這串隱含狀態鏈就是你用的骰子的序列。好比,隱含狀態鏈有多是:D6 D8 D8 D6 D4 D8 D6 D6 D4 D8
通常來講,HMM中說到的馬爾可夫鏈實際上是指隱含狀態鏈,由於隱含狀態(骰子)之間存在轉換機率(transition probability)。在咱們這個例子裏,D6的下一個狀態是D4,D6,D8的機率都是1/3。D4,D8的下一個狀態是D4,D6,D8的轉換機率也都同樣是1/3。這樣設定是爲了最開始容易說清楚,可是咱們實際上是能夠隨意設定轉換機率的。好比,咱們能夠這樣定義,D6後面不能接D4,D6後面是D6的機率是0.9,是D8的機率是0.1。這樣就是一個新的HMM。
一樣的,儘管可見狀態之間沒有轉換機率,可是隱含狀態和可見狀態之間有一個機率叫作輸出機率(emission probability)。就咱們的例子來講,六面骰(D6)產生1的輸出機率是1/6。產生2,3,4,5,6的機率也都是1/6。咱們一樣能夠對輸出機率進行其餘定義。好比,我有一個被賭場動過手腳的六面骰子,擲出來是1的機率更大,是1/2,擲出來是2,3,4,5,6的機率是1/10。
其實對於HMM來講,若是提早知道全部隱含狀態之間的轉換機率和全部隱含狀態到全部可見狀態之間的輸出機率,作模擬是至關容易的。可是應用HMM模型時候呢,每每是缺失了一部分信息的,有時候你知道骰子有幾種,每種骰子是什麼,可是不知道擲出來的骰子序列;有時候你只是看到了不少次擲骰子的結果,剩下的什麼都不知道。若是應用算法去估計這些缺失的信息,就成了一個很重要的問題。這些算法我會在下面詳細講。
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
若是你只想看一個簡單易懂的例子,就不須要往下看了。
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
說兩句廢話,答主認爲呢,要了解一個算法,要作到如下兩點:會其意,知其形。答主回答的,其實主要是第一點。可是這一點呢,偏偏是最重要,並且不少書上不會講的。正如你在追一個姑娘,姑娘對你說「你什麼都沒作錯!」你要是隻看姑娘的表達形式呢,認爲本身什麼都沒作錯,顯然就理解錯了。你要理會姑娘的意思,「你趕忙給我道歉!」這樣當你看到對應的表達形式呢,趕忙認錯,跪地求饒就對了。數學也是同樣,你要是不理解意思,光看公式,每每一頭霧水。不過呢,數學的表達頂多也就是晦澀了點,姑娘的表達呢,有的時候就徹底和本意相反。因此答主一直認爲理解姑娘比理解數學難多了。
回到正題,和HMM模型相關的算法主要分爲三類,分別解決三種問題:
1)知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換機率),根據擲骰子擲出的結果(可見狀態鏈),我想知道每次擲出來的都是哪一種骰子(隱含狀態鏈)。
這個問題呢,在語音識別領域呢,叫作解碼問題。這個問題其實有兩種解法,會給出兩個不一樣的答案。每一個答案都對,只不過這些答案的意義不同。第一種解法求最大似然狀態路徑,說通俗點呢,就是我求一串骰子序列,這串骰子序列產生觀測結果的機率最大。第二種解法呢,就不是求一組骰子序列了,而是求每次擲出的骰子分別是某種骰子的機率。好比說我看到結果後,我能夠求得第一次擲骰子是D4的機率是0.5,D6的機率是0.3,D8的機率是0.2.第一種解法我會在下面說到,可是第二種解法我就不寫在這裏了,若是你們有興趣,咱們另開一個問題繼續寫吧。
2)仍是知道骰子有幾種(隱含狀態數量),每種骰子是什麼(轉換機率),根據擲骰子擲出的結果(可見狀態鏈),我想知道擲出這個結果的機率。
看似這個問題意義不大,由於你擲出來的結果不少時候都對應了一個比較大的機率。問這個問題的目的呢,實際上是檢測觀察到的結果和已知的模型是否吻合。若是不少次結果都對應了比較小的機率,那麼就說明咱們已知的模型頗有多是錯的,有人偷偷把咱們的骰子給換了。
3)知道骰子有幾種(隱含狀態數量),不知道每種骰子是什麼(轉換機率),觀測到不少次擲骰子的結果(可見狀態鏈),我想反推出每種骰子是什麼(轉換機率)。
這個問題很重要,由於這是最多見的狀況。不少時候咱們只有可見結果,不知道HMM模型裏的參數,咱們須要從可見結果估計出這些參數,這是建模的一個必要步驟。
問題闡述完了,下面就開始說解法。(0號問題在上面沒有提,只是做爲解決上述問題的一個輔助)
0.一個簡單問題
其實這個問題實用價值不高。因爲對下面較難的問題有幫助,因此先在這裏提一下。
知道骰子有幾種,每種骰子是什麼,每次擲的都是什麼骰子,根據擲骰子擲出的結果,求產生這個結果的機率。
解法無非就是機率相乘:
1.看見不可見的,破解骰子序列
這裏我說的是第一種解法,解最大似然路徑問題。
舉例來講,我知道我有三個骰子,六面骰,四面骰,八面骰。我也知道我擲了十次的結果(1 6 3 5 2 7 3 5 2 4),我不知道每次用了那種骰子,我想知道最有可能的骰子序列。
其實最簡單而暴力的方法就是窮舉全部可能的骰子序列,而後依照第零個問題的解法把每一個序列對應的機率算出來。而後咱們從裏面把對應最大機率的序列挑出來就好了。若是馬爾可夫鏈不長,固然可行。若是長的話,窮舉的數量太大,就很難完成了。
另一種頗有名的算法叫作Viterbi algorithm. 要理解這個算法,咱們先看幾個簡單的列子。
首先,若是咱們只擲一次骰子:
看到結果爲1.對應的最大機率骰子序列就是D4,由於D4產生1的機率是1/4,高於1/6和1/8.
把這個狀況拓展,咱們擲兩次骰子:
結果爲1,6.這時問題變得複雜起來,咱們要計算三個值,分別是第二個骰子是D6,D4,D8的最大機率。顯然,要取到最大機率,第一個骰子必須爲D4。這時,第二個骰子取到D6的最大機率是
一樣的,咱們能夠計算第二個骰子是D4或D8時的最大機率。咱們發現,第二個骰子取到D6的機率最大。而使這個機率最大時,第一個骰子爲D4。因此最大機率骰子序列就是D4 D6。
繼續拓展,咱們擲三次骰子:
一樣,咱們計算第三個骰子分別是D6,D4,D8的最大機率。咱們再次發現,要取到最大機率,第二個骰子必須爲D6。這時,第三個骰子取到D4的最大機率是
同上,咱們能夠計算第三個骰子是D6或D8時的最大機率。咱們發現,第三個骰子取到D4的機率最大。而使這個機率最大時,第二個骰子爲D6,第一個骰子爲D4。因此最大機率骰子序列就是D4 D6 D4。
寫到這裏,你們應該看出點規律了。既然擲骰子一二三次能夠算,擲多少次均可以以此類推。咱們發現,咱們要求最大機率骰子序列時要作這麼幾件事情。首先,無論序列多長,要從序列長度爲1算起,算序列長度爲1時取到每一個骰子的最大機率。而後,逐漸增長長度,每增長一次長度,從新算一遍在這個長度下最後一個位置取到每一個骰子的最大機率。由於上一個長度下的取到每一個骰子的最大機率都算過了,從新計算的話其實不難。當咱們算到最後一位時,就知道最後一位是哪一個骰子的機率最大了。而後,咱們要把對應這個最大機率的序列從後往前推出來。
2.誰動了個人骰子?
好比說你懷疑本身的六面骰被賭場動過手腳了,有可能被換成另外一種六面骰,這種六面骰擲出來是1的機率更大,是1/2,擲出來是2,3,4,5,6的機率是1/10。你怎麼辦麼?答案很簡單,算一算正常的三個骰子擲出一段序列的機率,再算一算不正常的六面骰和另外兩個正常骰子擲出這段序列的機率。若是前者比後者小,你就要當心了。
好比說擲骰子的結果是:
要算用正常的三個骰子擲出這個結果的機率,其實就是將全部可能狀況的機率進行加和計算。一樣,簡單而暴力的方法就是把窮舉全部的骰子序列,仍是計算每一個骰子序列對應的機率,可是這回,咱們不挑最大值了,而是把全部算出來的機率相加,獲得的總機率就是咱們要求的結果。這個方法依然不能應用於太長的骰子序列(馬爾可夫鏈)。
咱們會應用一個和前一個問題相似的解法,只不過前一個問題關心的是機率最大值,這個問題關心的是機率之和。解決這個問題的算法叫作前向算法(forward algorithm)。
首先,若是咱們只擲一次骰子:
看到結果爲1.產生這個結果的總機率能夠按照以下計算,總機率爲0.18:
把這個狀況拓展,咱們擲兩次骰子:
看到結果爲1,6.產生這個結果的總機率能夠按照以下計算,總機率爲0.05:
繼續拓展,咱們擲三次骰子:
看到結果爲1,6,3.產生這個結果的總機率能夠按照以下計算,總機率爲0.03:
一樣的,咱們一步一步的算,有多長算多長,再長的馬爾可夫鏈總能算出來的。用一樣的方法,也能夠算出不正常的六面骰和另外兩個正常骰子擲出這段序列的機率,而後咱們比較一下這兩個機率大小,就能知道你的骰子是否是被人換了。
Viterbi algorithm
HMM(隱馬爾可夫模型)是用來描述隱含未知參數的統計模型,舉一個經典的例子:一個東京的朋友天天根據天氣{下雨,天晴}決定當天的活動{公園散步,購物,清理房間}中的一種,我天天只能在twitter上看到她發的推「啊,我前天公園散步、昨天購物、今天清理房間了!」,那麼我能夠根據她發的推特推斷東京這三天的天氣。在這個例子裏,顯狀態是活動,隱狀態是天氣。
任何一個HMM均可以經過下列五元組來描述:
:param obs:觀測序列 :param states:隱狀態 :param start_p:初始機率(隱狀態) :param trans_p:轉移機率(隱狀態) :param emit_p: 發射機率 (隱狀態表現爲顯狀態的機率)
僞碼以下:
states = ('Rainy', 'Sunny') observations = ('walk', 'shop', 'clean') start_probability = {'Rainy': 0.6, 'Sunny': 0.4} transition_probability = { 'Rainy' : {'Rainy': 0.7, 'Sunny': 0.3}, 'Sunny' : {'Rainy': 0.4, 'Sunny': 0.6}, } emission_probability = { 'Rainy' : {'walk': 0.1, 'shop': 0.4, 'clean': 0.5}, 'Sunny' : {'walk': 0.6, 'shop': 0.3, 'clean': 0.1}, }
求解最可能的天氣
求解最可能的隱狀態序列是HMM的三個典型問題之一,一般用維特比算法解決。維特比算法就是求解HMM上的最短路徑(-log(prob),也便是最大機率)的算法。
稍微用中文講講思路,很明顯,第一每天晴仍是下雨能夠算出來:
-
定義V[時間][今每天氣] = 機率,注意今每天氣指的是,前幾天的天氣都肯定下來了(機率最大)今每天氣是X的機率,這裏的機率就是一個累乘的機率了。
-
由於第一天個人朋友去散步了,因此第一天下雨的機率V[第一天][下雨] = 初始機率[下雨] * 發射機率[下雨][散步] = 0.6 * 0.1 = 0.06,同理可得V[第一天][天晴] = 0.24 。從直覺上來看,由於第一天朋友出門了,她通常喜歡在天晴的時候散步,因此第一每天晴的機率比較大,數字與直覺統一了。
-
從次日開始,對於每種天氣Y,都有前一每天氣是X的機率 * X轉移到Y的機率 * Y天氣下朋友進行這天這種活動的機率。由於前一每天氣X有兩種可能,因此Y的機率有兩個,選取其中較大一個做爲V[次日][天氣Y]的機率,同時將今天的天氣加入到結果序列中
-
比較V[最後一天][下雨]和[最後一天][天晴]的機率,找出較大的哪個對應的序列,就是最終結果。
算法的代碼能夠在github上看到,地址爲:
https://github.com/hankcs/Viterbi
運行完成後根據Viterbi獲得結果:
Sunny Rainy Rainy
Viterbi被普遍應用到分詞,詞性標註等應用場景。