關(guān)聯(lián)規(guī)則挖掘算法

設(shè)I=\{i_1,i_2,...,i_m\}為所有項(xiàng)目的集合遭笋,D為事務(wù)數(shù)據(jù)庫(kù),事物T是一個(gè)項(xiàng)目子集(T\subseteq I)徒探。每一個(gè)事務(wù)具有唯一的事務(wù)標(biāo)識(shí)TID瓦呼。設(shè)A是一個(gè)由項(xiàng)目構(gòu)成的集合,稱為項(xiàng)集测暗。事務(wù)T包含項(xiàng)集A央串,當(dāng)且僅當(dāng)A\subseteq T。如果項(xiàng)集A中包含k個(gè)項(xiàng)目碗啄,則稱其為K項(xiàng)集

項(xiàng)集A在事務(wù)數(shù)據(jù)庫(kù)D中出現(xiàn)的次數(shù)占總事務(wù)的百分比叫做項(xiàng)集的支持度质和。如果項(xiàng)集的支持度超過用戶給定的最小支持度閾值,就稱該項(xiàng)集是頻繁項(xiàng)集(或頻集)

關(guān)聯(lián)規(guī)則是形如X \Rightarrow Y的邏輯蘊(yùn)含式稚字,其中X\subset I饲宿,Y\subset I,且X\cap Y=\phi

如果事務(wù)數(shù)據(jù)庫(kù)D中有s\%的事務(wù)包含X∪Y胆描, 則稱關(guān)
聯(lián)規(guī)則X?Y的?持度為s\%

關(guān)聯(lián)規(guī)則的信任度為support (X∪Y)/support (X)
也就是:
support (X?Y)=P (X ∪Y)
confidence (X?Y)=P (Y | X)

強(qiáng)關(guān)聯(lián)規(guī)則就是?持度和信任度分別滿??戶
給定閾值的規(guī)則

例子

交易ID 購(gòu)買的商品
2000 A,B,C
1000 A,C
4000 A,D
5000 B,E,F

設(shè)最??持度為50%, 最?可信度為 50%, 則可得到

  • A ? C (50%, 66.6%)
  • C ? A (50%, 100%)

Apriori算法

命名源于算法使?了頻繁項(xiàng)集性質(zhì)的先驗(yàn)( Prior) 知識(shí)瘫想。

Apriori算法將發(fā)現(xiàn)關(guān)聯(lián)規(guī)則的過程分為兩個(gè)步驟:

  • 通過迭代, 檢索出事務(wù)數(shù)據(jù)庫(kù)中的所有頻繁
    項(xiàng)集昌讲, 即?持度不低于?戶設(shè)定的閾值的項(xiàng)集国夜;
  • 利?頻繁項(xiàng)集構(gòu)造出滿??戶最?信任度的
    規(guī)則。
  • 挖掘或識(shí)別出所有頻繁項(xiàng)集是該算法的核?短绸, 占整個(gè)
    計(jì)算量的?部分

Apriori的性質(zhì)

性質(zhì)1: 頻繁項(xiàng)集的所有?空?集必為頻繁項(xiàng)集车吹。

性質(zhì)2: ?頻繁項(xiàng)集的超集?定是?頻繁的。

Apriori的步驟

連接步: 為找Lk醋闭,通過將Lk-1與??連接產(chǎn)?候選k項(xiàng)集
的集合

剪枝步: Ck是Lk 的超集窄驹, 也就是說, Ck的成員可以是
也可以不是頻繁的证逻, 但所有的頻繁k項(xiàng)集都包含在Ck中乐埠。
任何?頻繁的( k-1) 項(xiàng)集都不是頻繁k項(xiàng)集的?集

Apriori算法實(shí)例

現(xiàn)有A、 B、 C饮戳、 D、 E五種商品的交易記錄表洞拨, 試找出
三種商品關(guān)聯(lián)銷售情況(k=3)扯罐, 最小支持度=50%

交易號(hào) 商品代碼
100 A,C,D
200 B,C,E
300 A,B,C,E
400 B,E

讀入數(shù)據(jù)

data = {'交易號(hào)':range(100,500,100),'商品代碼':['A,C,D', 'B,C,E', 'A,B,C,E', 'B,E']}
df_data = pd.DataFrame(data=data)

算一個(gè)事務(wù)集在事務(wù)數(shù)據(jù)庫(kù)的支持度

def get_score(values):
    score = 0.0
    b = True
    for value_code in df_data['商品代碼'].values:
        if values.difference(value_code.split(',')) == set():
            score += 1
    return score/len(df_data)

首先構(gòu)造等候集C

c = []
for code in df_data['商品代碼'].values:
    for _ in code.split(','):
        if {_} not in c:
            c.append({_})

輸出c

 [{'A'}, {'C'}, {'D'}, {'B'}, {'E'}]

計(jì)算L

from collections import defaultdict

score = 0.5
# 這里用字典來保存頻繁項(xiàng)集
L = defaultdict(list)
i = 0
length = len(c)
while c:
    i += 1
    for ci in c:
        if get_score(ci) >= score:
            L[i].append(ci)
    print L[i]
    c = get_c(L[i])
[set(['A']), set(['C']), set(['B']), set(['E'])]
[set(['A', 'C']), set(['C', 'B']), set(['C', 'E']), set(['B', 'E'])]
[set(['C', 'B', 'E'])]

可以得出三種商品關(guān)聯(lián)銷售情況(k=3), 最小支持度=50%只有一組(CBE)

Apriori算法的不?

  • C_k中的項(xiàng)集是?來產(chǎn)?頻集的候選集.

  • 最后的頻集L_k必須是C_k的?個(gè)?集烦衣。

  • C_k中的每個(gè)元素需在交易數(shù)據(jù)庫(kù)中進(jìn)?驗(yàn)證來決定其是否加
    ?L_k

  • 驗(yàn)證過程是性能瓶頸
    交易數(shù)據(jù)庫(kù)可能?常?
    ?如頻集最多包含10個(gè)項(xiàng)歹河, 那么就需要掃描交易數(shù)據(jù)庫(kù)10遍
    需要很?的I/O負(fù)載。

FP-tree算法(不??成候選集)

2000年花吟, Han等提出了?個(gè)稱為FP-tree的算法秸歧。
FP-tree算法只進(jìn)?2次數(shù)據(jù)庫(kù)掃描。

  • no候選集
  • 直接壓縮數(shù)據(jù)庫(kù)成?個(gè)頻繁模式樹
  • 通過這棵樹?成關(guān)聯(lián)規(guī)則衅澈。

FP-tree兩個(gè)主要步驟

  • ①利?事務(wù)數(shù)據(jù)庫(kù)中的數(shù)據(jù)構(gòu)造FP-tree键菱;
  • ②從FP-tree中挖掘頻繁模式

步驟1: 構(gòu)造 FP-tree樹

具體過程:
1.? 掃描數(shù)據(jù)庫(kù)?次, 得到頻繁1-項(xiàng)集
2.? 把項(xiàng)按?持度遞減排序
3.? 再?次掃描數(shù)據(jù)庫(kù)今布, 建?FP-tree

FP-tree 結(jié)構(gòu)的好處

  • 完備
    不會(huì)打破交易中的任何模式
    包含了頻繁模式挖掘所需的全部信息
  • 緊密
    去除不相關(guān)信息—不包含?頻繁項(xiàng)
    ?持度降序排列: ?持度?的項(xiàng)在FP-tree中共享的機(jī)會(huì)也?
    決不會(huì)?原數(shù)據(jù)庫(kù)?(如果不計(jì)算樹節(jié)點(diǎn)的額外開銷)

步驟2: 頻繁模式的挖掘

  • 具體過程:
    根據(jù)事務(wù)數(shù)據(jù)庫(kù)D 和最??持度min_sup经备, 調(diào)?建樹過程建?FP-tree;
    if (FP-tree 為簡(jiǎn)單路徑)
    將路徑上?持度計(jì)數(shù)?于等于min_sup 的節(jié)點(diǎn)任意組合, 得到所需
    的頻繁模式
    else
    初始化最?頻繁模式集合為空
    按照?持頻率升序部默, 以每個(gè)1 - 頻繁項(xiàng)為后綴侵蒙, 調(diào)?挖掘算法挖掘
    最?頻繁模式集
    根據(jù)最?頻繁模式集合中最?頻繁模式, 輸出全部的頻繁模式

FP-tree算法的一個(gè)例子

事物數(shù)據(jù)庫(kù):

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
df_fp_data = pd.DataFrame({'Tid':xrange(1,10,1), 'Items':['I1,I2,I5', 'I2,I4','I2,I3','I1,I2,I4',
                                                         'I1,I3', 'I2,I3','I1,I3','I1,I2,I3,I5',
                                                         'I1,I2,I3']})
def get_item_number(item):
    for el in item.split(','):
        dic_items[el]+=1   
dic_items = defaultdict(int)

df_fp_data['Items'].map(get_item_number)
dic_items

統(tǒng)計(jì)了每一項(xiàng)頻數(shù)傅蹂,輸出

defaultdict(int, {'I1': 6, 'I2': 7, 'I3': 6, 'I4': 2, 'I5': 2})

按照頻數(shù)對(duì)Items由大到小排序

df_fp_data['Items'] = df_fp_data['Items'].map(lambda items: 
        ','.join(sorted(items.split(','), key=lambda item:-dic_items[item])))

創(chuàng)建節(jié)點(diǎn)類與樹類

# 節(jié)點(diǎn)
class Node():
    def __init__(self, item):
        self.item = item
        self.numbers = 1
        self.children = []
        
class Tree():
    def __init__(self, root=None):
        self.root = root
    # 加入items
    def add_nodes(self, items):
        # 建立根節(jié)點(diǎn)
        if self.root is None:
            self.root = Node('null')
        temp = self.root.children
        if temp == [] and len(items)>0:
            temp.append(Node(items[0]))
            items.pop(0)
            temp_tree = Tree(temp[0])
            temp_tree.add_nodes(items)
        elif temp != []:
            for item in items:
                b = False
                for node in temp:
                    if node.item == item:
                        node.numbers += 1
                        temp = node.children
                        b = True
                        break
                if b is False:
                    temp_tree = Tree(Node(item))
                    temp_tree.add_nodes(items[items.index(item)+1:])
                    temp.append(temp_tree.root)
                    break
    def print_tree(self):
        node = self.root
        stack = [node]
        while stack != []:
            temp_node = stack.pop(0)
            print temp_node.item,temp_node.numbers
            stack += temp_node.children   
    def preorder_traversal(self):
        # 采用先序遍歷
        stack = []
        path = []
        temp = self.root
        while temp or stack:
            if temp is not None:
                print temp.item, temp.numbers
                stack.append(temp)
                if temp.children == []:
                    temp = None
                else:
                    temp = temp.children.pop(0)
            else:
                children = stack[-1].children
                if children == []:
                    stack.pop()
                else:
                    if len(children) == 1:
                        stack.pop()
                    temp = children.pop(0)
         

將節(jié)點(diǎn)加入樹中

tree = Tree(Node('null'))
for item in df_fp_data['Items'].values:
    tree.add_nodes(item.split(','))

打印樹(層次打印)

tree.print_tree()
null 1
I2 7
I1 2
I1 4
I4 1
I3 2
I3 2
I5 1
I4 1
I3 2
I5 1
FP-tree樹
tree.preorder_traversal()

輸出

null 1
I2 7
I1 4
I5 1
I4 1
I3 2
I5 1
I4 1
I3 2
I1 2
I3 2
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纷闺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子份蝴,更是在濱河造成了極大的恐慌犁功,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搞乏,死亡現(xiàn)場(chǎng)離奇詭異波桩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)请敦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門镐躲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侍筛,你說我怎么就攤上這事萤皂。” “怎么了匣椰?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵裆熙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)入录,這世上最難降的妖魔是什么蛤奥? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮僚稿,結(jié)果婚禮上凡桥,老公的妹妹穿的比我還像新娘。我一直安慰自己蚀同,他們只是感情好缅刽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蠢络,像睡著了一般衰猛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刹孔,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天啡省,我揣著相機(jī)與錄音,去河邊找鬼髓霞。 笑死冕杠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酸茴。 我是一名探鬼主播分预,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼薪捍!你這毒婦竟也來了笼痹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤酪穿,失蹤者是張志新(化名)和其女友劉穎凳干,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體被济,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡救赐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了只磷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片经磅。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钮追,靈堂內(nèi)的尸體忽然破棺而出预厌,到底是詐尸還是另有隱情,我是刑警寧澤元媚,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布窒百,位于F島的核電站,受9級(jí)特大地震影響艺配,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜待逞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望网严。 院中可真熱鬧飒焦,春花似錦、人聲如沸屿笼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驴一。三九已至,卻和暖如春灶壶,著一層夾襖步出監(jiān)牢的瞬間肝断,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工驰凛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胸懈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓恰响,卻偏偏與公主長(zhǎng)得像趣钱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子胚宦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 關(guān)聯(lián)規(guī)則挖掘是一種基于規(guī)則的機(jī)器學(xué)習(xí)算法首有,該算法可以在大數(shù)據(jù)庫(kù)中發(fā)現(xiàn)感興趣的關(guān)系。它的目的是利用一些度量指標(biāo)來分辨...
    曾梓華閱讀 25,230評(píng)論 4 25
  • 加權(quán)關(guān)聯(lián)規(guī)則挖掘 在 R 語(yǔ)言中的 arules 包有該算法的實(shí)現(xiàn)枢劝,故花時(shí)間研究了一下該算法的原理和產(chǎn)生的背景井联。關(guān)...
    曾梓華閱讀 5,070評(píng)論 0 8
  • 定義 ??關(guān)聯(lián)分析是一種簡(jiǎn)單、實(shí)用的分析技術(shù)您旁,就是發(fā)現(xiàn)存在于大量數(shù)據(jù)集中的關(guān)聯(lián)性或相關(guān)性烙常,從而描述了一個(gè)事物中某些...
    老羊_肖恩閱讀 3,323評(píng)論 0 1
  • 1. 關(guān)聯(lián)規(guī)則概述 反映一個(gè)事物與其他事物之間的相互依存性和關(guān)聯(lián)性。如果兩個(gè)或者多個(gè)事物之間存在一定的關(guān)聯(lián)關(guān)系鹤盒,那...
    七八音閱讀 7,245評(píng)論 0 5
  • 按照規(guī)劃蚕脏,這次是一個(gè)ffmpeg編碼的例子,下面介紹下Demo流程 1.把一個(gè)yuv文件編碼成h264文件 2.編...
    棍子哥丸子妹閱讀 426評(píng)論 0 0