挖掘商品關聯性(2): FP-growth算法

從這個貿易戰看:強權即是真理,沒有所謂的自由貿易和平等。中國之大已容不下一個安靜的鍵盤。不過是又一次鴉片戰爭。除了憤怒還是憤怒,除了一心想爲崛起而澎湃還是一心想爲崛起而澎湃。中華文明三四千年的歷史都是世界頂級,美國人區區100多年第一就想再佔100年這不是無知麼中國人有13億人,是美國人的4倍還要多,4個抵1個也是必然會超過美國
2019年5月29日 IEEE宣佈禁止任何受華爲資助的教授或學生參與IEEE審稿。聽到這個消息我是憤怒的,說好的科學無國界呢?
梳理下這個過程:
2018.12.1,華爲CFO(任正非之女)被美國下令逮捕
2018.12.1 對芯片重大貢獻的華人張首晟在美國身亡,就在2年前獲得中國國家科學技術獎(中國科技最高獎,最高領導人親自頒獎,獎金200萬美金)
2019年5月 美國撕毀兩國元首已經基本確定的協議,對中國徵收25%關稅。
2019年5月中旬 美國禁止全世界任何企業與華爲接觸或者提供設備,也禁止購買華爲手機或通訊設備。理由:“國家安全”(距離美國棱鏡門用思科通訊設備和Google監聽全世界這個事件不過幾年美國人就忘了自己幹了什麼事。)同時禁止歐洲其他國家使用華爲提供的5G服務。
2019年5月中下旬,Microsoft,ARM,Google紛紛宣佈停止和華爲任何商業來往,同時Google禁止華爲手機使用Google服務
2019年5月底, IEEE(世界上最大電子電氣學術機構禁止任何受華爲資助的教授參與審稿禁止其他高校或企業與中國的一些高校合作

1. 背景

在前面我們介紹了一種簡單的挖掘商品關聯性算法Apriori算法。今天要介紹的是更高效的FP-growth算法(FP指的是Frequent Pattern),它可以用到搜索詞提醒,常用詞,挖掘強關聯性商品,商品推薦等領域上。挖掘商品關聯繫或者詞語之間的關聯性,需要做的事是構造各種商品組合然後分析出這種組合是否是高頻率出現。Apriori算法每產生一種組合都要遍歷一次數據庫來判斷當前組合是否是高頻記錄(如果你對這句話不理解建議看下這篇文章:易懂機器學習Apriori算法商品關聯性分析)。這個在大量數據面前是很耗時間。

2. FP-growth執行過程

初衷:現在我們需要做的事是構造各種商品組合然後分析出這種組合是否是高頻率出現。由於Apriori算法每次構造出一種組合都要遍歷一遍數據集來統計當前這種組合出現次數這個耗費時間過大。那我們能不能把數據集壓縮呢?假設是賬單數據集。那麼肯定會有很多賬單會有大量公共商品組合。如果我們把這些公共商品作爲前綴,那麼就能壓縮數據集。壓縮數據集的好處就是可以減少我們統計某種組合出現次數所花費的時間。FP-growth算法就是這麼做的,它數據構造成一顆樹。相同商品在上層節點,並且每個節點記錄了當前節點重複利用次數,以方便統計出現頻率
還是拿這個舉例子:

{啤酒 雞蛋 尿布 西紅柿}
{香菸 尿布 雞蛋 啤酒 }
{土豆 西紅柿 洋蔥 醋 雞蛋}

先將它們編號:
[1]啤酒 [2]雞蛋 [3]尿布 [4]西紅柿 [5]香菸 [6]土豆 [7]洋蔥 [8]醋
上面這個數據集用編號表示就是

[
[1, 2, 3, 4],
[5, 3, 2, 1],
[6,4,7,8, 2]
]
  • Apriori算法一樣。先設定一個閾值,出現頻率超過這個閾值就認爲是高頻率。算頻率有點麻煩,這裏我們認爲超過2次就是高頻率吧。
  • Apriori算法一樣統計各個商品的出現次數,剔除低頻率商品
    在這裏插入圖片描述
  • 從這一步開始與Apriori算法不一樣了。根據頻率將每條賬單內的商品按頻率排序(並且剔除低頻率商品)。
[
[2,1, 3,4],
[2, 1, 3],
[2,4]
]

3. FP樹如何構造

  • 根據上面那個排序好並且篩選過的逐個賬單構造一棵樹。節點格式:{物品編號}-節點重複經過次數
    加入第一個賬單
    在這裏插入圖片描述
    加入第二個賬單:(與第一個賬單前綴重合,所以重複利用節點,相關節點利用次數+1)
    在這裏插入圖片描述
    加入第3個賬單(商品{2}是重合的前綴,商品{4}需要重新開一個節點):
    在這裏插入圖片描述

FP樹有什麼用(計算某種組合出現的次數不用重複查賬單,只需要根據FP樹來計算)

比如我有一個商品組合{2,3,1}我想看看它的出現頻率。此時我完全不用從賬單裏面找哪些賬單包含{2,3,1}這三個物品。先對這個組合按照物品出現頻率排序即排序爲{2,1,3}。然後我只需要之間看樹上的相應節點即可。{2}->{1}->{3}這條路徑重複利用了2次(第3個節點重複利用次數是2所以這條路徑重複利用次數是2)。證明{2,1,3}這個組合出現2次。
那麼問題來了。{4}這個節點有兩個,我們怎麼方便的找到以{4}開頭的商品組合呢?用一個表來存儲含有某個物品的節點的編號。假設我們對各個節點進行了編號(n1,n2,n3…)
在這裏插入圖片描述
然後我們構造的表是。如果我們要找{4}開頭的組合的頻率那麼只用從n5和n3這兩個節點開始往下找:
在這裏插入圖片描述

Python代碼實現構造FP樹和上面那個表

# -*- coding: utf-8 -*-
"""
Created on Mon May 27 20:19:24 2019

@author: Ai醬
"""

import numpy as np
data = [
[1, 2, 3, 4],
[5, 3, 2, 1],
[6,4,7,8, 2]
]

# 1. 設定大於等於多少纔是高頻率
high_freq = 2
# 2. 統計各商品出現次數
max_goods_id = 8
goods_num = {}
for i in range(max_goods_id):
    goods_id = i+1
    for item in data:
        if goods_id in item:
            if goods_id in goods_num.keys():
                goods_num[goods_id] +=1
            else:
                goods_num[goods_id] =1
        pass
    pass
pass


# 6. 刪除賬單中低頻商品,並且按商品頻率排序
for i in range(len(data)):
    # 刪除低頻(<high_freq)的商品
    tmp = data[i].copy()
    for goods_id in tmp:
        if goods_num[goods_id]<high_freq:
            data[i].remove(goods_id)
    # 按頻率從高到低
    data[i] = sorted(data[i])
    data[i] = sorted(data[i],key=lambda x: goods_num[x], reverse=True)
    
# 7. 構造FP樹
def addNode(root, goods_list,table):
    if len(goods_list)==0:
        return
    # 將第一商品加入到樹中
    # 如果,當前商品已經在孩子節點中那麼只需要將孩子節點重複次數+1
    # 否則,用當前這個商品id來創建孩子節點,設置重複次數爲1
    if goods_list[0] in root['child']:
        root['child'][goods_list[0]]['repeats']+=1
    else:
        root['child'][goods_list[0]]={'child':{}}
        root['child'][goods_list[0]]['repeats']=1
        # 當前這種商品增加了那新的節點記錄到表裏面方便根據前綴查樹
        table[goods_list[0]].append(root['child'][goods_list[0]])
    # 遞歸的添加下一個商品
    addNode(root['child'][goods_list[0]],goods_list[1:len(goods_list)],table)
pass

fptree = {'child':{}}
table = {i+1:[] for i in range(max_goods_id)}
for tmp_goods_list in data:
    addNode(fptree,tmp_goods_list,table)

print(fptree)

'''
{
   'child':{
      2:{
         'child':{
            1:{
               'child':{
                  3:{
                     'child':{
                        4:{
                           'child':{

                           },
                           'repeats':1
                        }
                     },
                     'repeats':2
                  }
               },
               'repeats':2
            },
            4:{
               'child':{

               },
               'repeats':1
            }
         },
         'repeats':3
      }
   }
}
'''
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章