PrefixSpan算法原理總結

  前面咱們講到頻繁項集挖掘的關聯算法Apriori和FP Tree。這兩個算法都是挖掘頻繁項集的。而今天咱們要介紹的PrefixSpan算法也是關聯算法,可是它是挖掘頻繁序列模式的,所以要解決的問題目標稍有不一樣。算法

1. 項集數據和序列數據

    首先咱們看看項集數據和序列數據有什麼不一樣,以下圖所示。數據庫

    左邊的數據集就是項集數據,在Apriori和FP Tree算法中咱們也已經看到過了,每一個項集數據由若干項組成,這些項沒有時間上的前後關係。而右邊的序列數據則不同,它是由若干數據項集組成的序列。好比第一個序列<a(abc)(ac)d(cf)>,它由a,abc,ac,d,cf共5個項集數據組成,而且這些項有時間上的前後關係。對於多於一個項的項集咱們要加上括號,以便和其餘的項集分開。同時因爲項集內部是不區分前後順序的,爲了方便數據處理,咱們通常將序列數據內全部的項集內部按字母順序排序。分佈式

2. 子序列與頻繁序列

    瞭解了序列數據的概念,咱們再來看看上面是子序列。子序列和咱們數學上的子集的概念很相似,也就是說,若是某個序列A全部的項集在序列B中的項集均可以找到,則A就是B的子序列。固然,若是用嚴格的數學描述,子序列是這樣的:大數據

    對於序列A={a1,a2,...ana1,a2,...an}和序列B={b1,b2,...bmb1,b2,...bm},nmn≤m,若是存在數字序列1j1j2...jnm1≤j1≤j2≤...≤jn≤m, 知足a1bj1,a2bj2...anbjna1⊆bj1,a2⊆bj2...an⊆bjn,則稱A是B的子序列。固然反過來講, B就是A的超序列。優化

    而頻繁序列則和咱們的頻繁項集很相似,也就是頻繁出現的子序列。好比對於下圖,支持度閾值定義爲50%,也就是須要出現兩次的子序列纔是頻繁序列。而子序列<(ab)c>是頻繁序列,由於它是圖中的第一條數據和第三條序列數據的子序列,對應的位置用藍色標示。atom

3. PrefixSpan算法的一些概念

     PrefixSpan算法的全稱是Prefix-Projected Pattern Growth,即前綴投影的模式挖掘。裏面有前綴和投影兩個詞。那麼咱們首先看看什麼是PrefixSpan算法中的前綴prefix。spa

    在PrefixSpan算法中的前綴prefix通俗意義講就是序列數據前面部分的子序列。若是用嚴格的數學描述,前綴是這樣的:對於序列A={a1,a2,...ana1,a2,...an}和序列B={b1,b2,...bmb1,b2,...bm},nmn≤m,知足a1=b1,a2=b2...an1=bn1a1=b1,a2=b2...an−1=bn−1,而anbnan⊆bn,則稱A是B的前綴。好比對於序列數據B=<a(abc)(ac)d(cf)>,而A=<a(abc)a>,則A是B的前綴。固然B的前綴不止一個,好比<a>, <aa>, <a(ab)> 也都是B的前綴。xml

    看了前綴,咱們再來看前綴投影,其實前綴投影這兒就是咱們的後綴,有前綴就有後綴嘛。前綴加上後綴就能夠構成一個咱們的序列。下面給出前綴和後綴的例子。對於某一個前綴,序列裏前綴後面剩下的子序列即爲咱們的後綴。若是前綴最後的項是項集的一部分,則用一個「_」來佔位表示。blog

    下面這個例子展現了序列<a(abc)(ac)d(cf)>的一些前綴和後綴,仍是比較直觀的。要注意的是,若是前綴的末尾不是一個徹底的項集,則須要加一個佔位符。排序

    在PrefixSpan算法中,相同前綴對應的全部後綴的結合咱們稱爲前綴對應的投影數據庫。

4. PrefixSpan算法思想

    如今咱們來看看PrefixSpan算法的思想,PrefixSpan算法的目標是挖掘出知足最小支持度的頻繁序列。那麼怎麼去挖掘出全部知足要求的頻繁序列呢。回憶Aprior算法,它是從頻繁1項集出發,一步步的挖掘2項集,直到最大的K項集。PrefixSpan算法也相似,它從長度爲1的前綴開始挖掘序列模式,搜索對應的投影數據庫獲得長度爲1的前綴對應的頻繁序列,而後遞歸的挖掘長度爲2的前綴所對應的頻繁序列,。。。以此類推,一直遞歸到不能挖掘到更長的前綴挖掘爲止。

    好比對應於咱們第二節的例子,支持度閾值爲50%。裏面長度爲1的前綴包括<a>, <b>, <c>, <d>, <e>, <f>,<g>咱們須要對這6個前綴分別遞歸搜索找各個前綴對應的頻繁序列。以下圖所示,每一個前綴對應的後綴也標出來了。因爲g只在序列4出現,支持度計數只有1,所以沒法繼續挖掘。咱們的長度爲1的頻繁序列爲<a>, <b>, <c>, <d>, <e>,<f>。去除全部序列中的g,即第4條記錄變成<e(af)cbc>

    
    如今咱們開始挖掘頻繁序列,分別從長度爲1的前綴開始。這裏咱們以d爲例子來遞歸挖掘,其餘的節點遞歸挖掘方法和D同樣。方法以下圖,首先咱們對d的後綴進行計數,獲得{a:1, b:2, c:3, d:0, e:1, f:1,_f:1}。注意f和_f是不同的,由於前者是在和前綴d不一樣的項集,然後者是和前綴d同項集。因爲此時a,d,e,f,_f都達不到支持度閾值,所以咱們遞歸獲得的前綴爲d的2項頻繁序列爲<db>和<dc>。接着咱們分別遞歸db和dc爲前綴所對應的投影序列。首先看db前綴,此時對應的投影后綴只有<_c(ae)>,此時_c,a,e支持度均達不到閾值,所以沒法找到以db爲前綴的頻繁序列。如今咱們來遞歸另一個前綴dc。以dc爲前綴的投影序列爲<_f>, <(bc)(ae)>, <b>,此時咱們進行支持度計數,結果爲{b:2, a:1, c:1, e:1, _f:1},只有b知足支持度閾值,所以咱們獲得前綴爲dc的三項頻繁序列爲<dcb>。咱們繼續遞歸以<dcb>爲前綴的頻繁序列。因爲前綴<dcb>對應的投影序列<(_c)ae>支持度所有不達標,所以不能產生4項頻繁序列。至此以d爲前綴的頻繁序列挖掘結束,產生的頻繁序列爲<d><db><dc><dcb>。

    一樣的方法能夠獲得其餘以<a>, <b>, <c>, <e>, <f>爲前綴的頻繁序列。

5. PrefixSpan算法流程

    下面咱們對PrefixSpan算法的流程作一個概括總結。

    輸入:序列數據集S和支持度閾值αα

    輸出:全部知足支持度要求的頻繁序列集

    1)找出全部長度爲1的前綴和對應的投影數據庫

    2)對長度爲1的前綴進行計數,將支持度低於閾值αα的前綴對應的項從數據集S刪除,同時獲得全部的頻繁1項序列,i=1.

    3)對於每一個長度爲i知足支持度要求的前綴進行遞歸挖掘:

      a) 找出前綴所對應的投影數據庫。若是投影數據庫爲空,則遞歸返回。

      b) 統計對應投影數據庫中各項的支持度計數。若是全部項的支持度計數都低於閾值αα,則遞歸返回。

      c) 將知足支持度計數的各個單項和當前的前綴進行合併,獲得若干新的前綴。

      d) 令i=i+1,前綴爲合併單項後的各個前綴,分別遞歸執行第3步。

6. PrefixSpan算法小結

    PrefixSpan算法因爲不用產生候選序列,且投影數據庫縮小的很快,內存消耗比較穩定,做頻繁序列模式挖掘的時候效果很高。比起其餘的序列挖掘算法好比GSP,FreeSpan有較大優點,所以是在生產環境經常使用的算法。

    PrefixSpan運行時最大的消耗在遞歸的構造投影數據庫。若是序列數據集較大,項數種類較多時,算法運行速度會有明顯降低。所以有一些PrefixSpan的改進版算法都是在優化構造投影數據庫這一塊。好比使用僞投影計數。

    固然使用大數據平臺的分佈式計算能力也是加快PrefixSpan運行速度一個好辦法。好比Spark的MLlib就內置了PrefixSpan算法。

    不過scikit-learn始終不過重視關聯算法,一直都不包括這一塊的算法集成,這就有點落伍了。

相關文章
相關標籤/搜索