Spark下的FP-Growth和Apriori



基本概念

  關聯分析是一種在大規模數據集中尋找有趣關系的非監督學習算法。這些關系可以有兩種形式:頻繁項集或者關聯規則。頻繁項集(frequent item sets)是經常出現在一塊的物品的集合,關聯規則(association rules)暗示兩種物品之間可能存在很強的關系。

  下圖是一個乒乓球店的交易記錄,〇表示顧客購買了商品。其中{底板,膠皮,澆水}就是一個頻繁項集;從中可以找到底板->膠皮這樣的關聯規則:

支持度

  怎樣有效定義頻繁和關聯?其中最重要的兩個概念是支持度和置信度。

  支持度(support)從字面上理解就是支持的程度,一個項集的支持度(support)被定義為數據集中包含該項集的記錄所占的比例。上圖中{底板}的支持度=(5/6) * 100%。

  這個概念其實經常在現實生活中出現,翻譯成支持率似乎更好理解,典型的例子就是投票,比如英國脫歐的支持率為51.89%。

  用數學去解釋就是,設W 中有s%的事務同時支持物品集A和B,s%稱為{A,B}的支持度,即:

  support({A,B}) = num(A∪B) / W = P(A∩B)

  num(A∪B)表示含有物品集{A,B}的事務集的個數,不是數學中的並集。

置信度

  置信度(confidence)揭示了A出現時B是否一定出現,如果出現,則出現的概率是多大。如果A->B的置信度是100%,則說明A出現時B一定會出現(返回來不一定)。上圖中底板共出現5次,其中4次同時購買了膠皮,底板->膠皮的置信度是80%。

  用公式表示是,物品A->B的置信度=物品{A,B}的支持度 / 物品{A}的支持度:

  Confidence(A->B) = support({A,B}) / support({A}) = P(B|A)

Apriori原理

   假設我們在經營一家商品種類並不多的雜貨店,我們對那些經常在一起被購買的商品非常感興趣。我們只有4種商品:商品0,商品1,商品2和商品3。那么所有可能被一起購買的商品組合都有哪些?這些商品組合可能只有一種商品,比如商品0,也可能包括兩種、三種或者所有四種商品。我們並不關心某人買了兩件商品0以及四件商品2的情況,我們只關心他購買了一種或多種商品。

  下圖顯示了物品之間所有可能的組合。為了讓該圖更容易懂,圖中使用物品的編號0來取代物品0本身。另外,圖中從上往下的第一個集合是Ф,表示空集或不包含任何物品的集合。物品集合之間的連線表明兩個或者更多集合可以組合形成一個更大的集合。

  前面說過,我們的目標是找到經常在一起購買的物品集合。我們使用集合的支持度來度量其出現的頻率。一個集合的支持度是指有多少比例的交易記錄包含該集合。如何對一個給定的集合,比如{0,3},來計算其支持度?我們遍歷毎條記錄並檢查該記錄包含0和3,如果記錄確實同時包含這兩項,那么就增加總計數值。在掃描完所有數據之后,使用統計得到的總數除以總的交易記錄數,就可以得到支持度。上述過程和結果只是針對單個集合{0,3}。要獲得每種可能集合的支持度就需要多次重復上述過程。我們可以數一下上圖中的集合數目,會發現即使對於僅有4種物品的集合,也需要遍歷數據15次。而隨着物品數目的增加遍歷次數會急劇增長。對於包含— 物品的數據集共有2N-1種項集組合。事實上,出售10000或更多種物品的商店並不少見。即使只出售100種商品的商店也會有1.26×1030種可能的項集組合。對於現代的計算機而言,需要很長的時間才能完成運算。

  為了降低所需的計算時間,研究人員發現一種所謂的Apriori原理。Apriori原理可以幫我們減少可能感興趣的項集。Apriori原理是說如果某個項集是頻繁的,那么它的所有子集也是頻繁的。上圖給出的例子,這意味着如果{0,1}是頻繁的,那么{0}、{1}也一定是頻繁的。這個原理直觀上並沒有什么幫助,但是如果反過來看就有用了,也就是說如果一個項集是非頻繁集,那么它的所有超集也是非頻繁的,如下所示:

  上圖中,已知陰影項集{2,3}是非頻繁的。利用這個知識,我們就知道項集{0,2,3} ,{1,2,3}以及{0,1,2,3}也是非頻繁的。這也就是說,一旦計算出了{2,3}的支持度,知道它是非頻繁的之后,就不需要再計算{0,2,3}、{1,2,3}和{0,1,2,3}的支持度,因為我們知道這些集合不會滿足我們的要求。使用該原理就可以避免項集數目的指數增長,從而在合理時間內計算出頻繁項集。

Apriori算法過程

  關聯分析的目標包括兩項:發現頻繁項集和發現關聯規則。首先需要找到頻繁項集,然后才能獲得關聯規則。

Apriori算法過程

  發現頻繁項集的過程如上圖所示:

  1. 由數據集生成候選項集C1(1表示每個候選項僅有一個數據項);再由C1通過支持度過濾,生成頻繁項集L1(1表示每個頻繁項僅有一個數據項)。
  2. 將L1的數據項兩兩拼接成C2。
  3. 從候選項集C2開始,通過支持度過濾生成L2。L2根據Apriori原理拼接成候選項集C3;C3通過支持度過濾生成L3……直到Lk中僅有一個或沒有數據項為止。

  下面是一個超市的交易記錄:

  Apriori算法發現頻繁項集的過程如下:

 

以上轉於:https://www.cnblogs.com/bigmonkey/p/7405555.html

FP-Grwoth 算法過程

Apriori算法雖然思路很簡單,但是該算法有以下缺點:

    (1)在每一步產生侯選項目集時循環產生的組合過多,沒有排除不應該參與組合的元素;

    (2)每次計算項集的支持度時,都對數據集中的全部記錄進行了一遍掃描比較,

在數據集較大時,這樣掃描下來會大大增加計算機的IO開銷。這種代價會讓計算機奔潰。
針對Apriori算法的性能瓶頸——需要產生大量候選集和需要重復掃描數據集,FP-growth算法應用而生。該算法只進行2次數據集掃描而且不使用候選集,直接壓縮數據集成一個頻繁模式樹(FP樹),最后通過這個FP樹生成頻繁項集。對於本題較大的數據集,FP-growth算法是個不錯的選擇。  

(1)按以下步驟構造FP-樹

(a) 掃描事務數據庫D一次。收集頻繁項的集合F和它們的支持度。對F按支持度降序排序,結果為頻繁項表L。
(b) 創建FP-樹的根結點,以“null”標記它。對於D 中每個事務Trans,執行:選擇 Trans 中的頻繁項,並按L中的次序排序。設排序后的頻繁項表為[p | P],其中,p 是第一個元素,而P 是剩余元素的表。調用insert_tree([p | P], T)。該過程執行情況如下。如果T有子女N使得N.item-name = p.item-name,則N 的計數增加1;否則創建一個新結點N將其計數設置為1,鏈接到它的父結點T,並且通過結點鏈結構將其鏈接到具有相同item-name的結點。如果P非空,遞歸地調用insert_tree(P, N)。
(2)FP-樹的挖掘
通過調用FP_growth(FP_tree, null)實現。該過程實現如下:
FP_growth(Tree, α)
(1) if Tree 含單個路徑P then
(2) for 路徑 P 中結點的每個組合(記作β)
(3) 產生模式β ∪ α,其支持度support = β中結點的最小支持度;
(4) else for each ai在Tree的頭部(按照支持度由低到高順序進行掃描) {
(5) 產生一個模式β = ai ∪ α,其支持度support = ai .support;
(6) 構造β的條件模式基,然后構造β的條件FP-樹Treeβ;
(7) if Treeβ ≠ ∅ then
(8) 調用 FP_growth (Treeβ, β);}
end
1.1.3 FP-Growth算法演示—構造FP-樹
(1)事務數據庫建立

原始事務數據庫如下:

Tid

Items

1

I1,I2,I5

2

I2,I4

3

I2,I3

4

I1,I2,I4

5

I1,I3

6

I2,I3

7

I1,I3

8

I1,I2,I3,I5

9

I1,I2,I3

 

 

掃描事務數據庫得到頻繁1-項目集F。

I1

I2

I3

I4

I5

6

7

6

2

2

 

定義minsup=20%,即最小支持度為2,重新排列F。

 

I2

I1

I3

I4

I5

7

6

6

2

2

 

重新調整事務數據庫。

 

Tid

Items

1

I2, I1,I5

2

I2,I4

3

I2,I3

4

I2, I1,I4

5

I1,I3

6

I2,I3

7

I1,I3

8

I2, I1,I3,I5

9

I2, I1,I3

 

(2)創建根結點和頻繁項目表

 

 

 

(3)加入第一個事務(I2,I1,I5)

 

 

(4)加入第二個事務(I2,I4)

 

 

(5)加入第三個事務(I2,I3)

 

 

以此類推加入第5、6、7、8、9個事務。

 

(6)加入第九個事務(I2,I1,I3)

 

1.1.4 FP-Growth算法演示—FP-樹挖掘

FP-樹建好后,就可以進行頻繁項集的挖掘,挖掘算法稱為FpGrowth(Frequent Pattern Growth)算法,挖掘從表頭header的最后一個項開始,以此類推。本文以I5、I3為例進行挖掘。

(1)挖掘I5:

對於I5,得到條件模式基:<(I2,I1:1)>、<I2,I1,I3:1>

構造條件FP-tree:

 

得到I5頻繁項集:{{I2,I5:2},{I1,I5:2},{I2,I1,I5:2}}

I4、I1的挖掘與I5類似,條件FP-樹都是單路徑。

(1)挖掘I3:

I5的情況是比較簡單的,因為I5對應的條件FP-樹是單路徑的,I3稍微復雜一點。I3的條件模式基是(I2 I1:2), (I2:2), (I1:2),生成的條件FP-樹如下圖:

 

I3的條件FP-樹仍然是一個多路徑樹,首先把模式后綴I3和條件FP-樹中的項頭表中的每一項取並集,得到一組模式{I2 I3:4, I1 I3:4},但是這一組模式不是后綴為I3的所有模式。還需要遞歸調用FP-growth,模式后綴為{I1,I3},{I1,I3}的條件模式基為{I2:2},其生成的條件FP-樹如下圖所示。  

 

在FP_growth中把I2和模式后綴{I1,I3}取並得到模式{I1 I2 I3:2}。

理論上還應該計算一下模式后綴為{I2,I3}的模式集,但是{I2,I3}的條件模式基為空,遞歸調用結束。最終模式后綴I3的支持度>2的所有模式為:{ I2 I3:4, I1 I3:4, I1 I2 I3:2}。

 

轉於: https://blog.csdn.net/sunbow0/article/details/45602415 
 

 


運行Spark fp-growth demo如下:

pom.xml中加載mllib依賴

<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-mllib_2.11</artifactId>
<version>2.3.0</version>
</dependency>


官網提供的代碼如下:

package cn.xdf.userprofile.ML

import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.fpm.FPGrowth

object FPGrowthDemo {

def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder
.appName("FPGrowthDemo").master("local")
.config("spark.sql.warehouse.dir", "C:\\study\\sparktest")
.getOrCreate()
//val spark = getSparkSession("FPGrowthDemo")

import spark.implicits._
val dataset = spark.createDataset(Seq(
"1 2 5",
"1 2 3 5",
"1 2 ")
).map(t => t.split(" ")).toDF("items")

val fpgroth=new FPGrowth().setItemsCol("items").setMinSupport(0.5).setMinConfidence(0.6)
val model=fpgroth.fit(dataset)
// Display frequent itemsets.
model.freqItemsets.show()

// Display generated association rules.
model.associationRules.show()
// transform examines the input items against all the association rules and summarize the
// consequents as prediction
model.transform(dataset).show()
// $example off$

spark.stop()
}
}

運行結果如下:

18/10/23 11:31:27 INFO CodeGenerator: Code generated in 255.413874 ms
+---------+----+
|    items|freq|
+---------+----+
|      [5]|   2|
|   [5, 1]|   2|
|[5, 1, 2]|   2|
|   [5, 2]|   2|
|      [1]|   3|
|   [1, 2]|   3|
|      [2]|   3|
+---------+----+

  

18/10/23 11:45:01 INFO CodeGenerator: Code generated in 566.235467 ms  
+----------+----------+------------------+
|antecedent|consequent|        confidence|
+----------+----------+------------------+
|    [1, 2]|       [5]|0.6666666666666666|
|    [5, 1]|       [2]|               1.0|
|       [2]|       [5]|0.6666666666666666|
|       [2]|       [1]|               1.0|
|       [5]|       [1]|               1.0|
|       [5]|       [2]|               1.0|
|       [1]|       [5]|0.6666666666666666|
|       [1]|       [2]|               1.0|
|    [5, 2]|       [1]|               1.0|
+----------+----------+------------------+  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM