基于Python的A-Priori算法发现购物篮关联规则
基于Python的A-Priori算法發(fā)現(xiàn)購(gòu)物籃關(guān)聯(lián)規(guī)則
前言
一個(gè)生動(dòng)的例子介紹購(gòu)物籃模型——啤酒與尿布的故事
有10000個(gè)消費(fèi)者購(gòu)買了商品,其中購(gòu)買尿布1000個(gè),購(gòu)買啤酒2000個(gè),購(gòu)買面包500個(gè),同時(shí)購(gòu)買尿布和啤酒800個(gè),同時(shí)購(gòu)買尿布和面包100個(gè),
我們發(fā)現(xiàn)同時(shí)購(gòu)買啤酒與尿布的消費(fèi)者比較多,一個(gè)可能的猜測(cè)是年輕的爸爸們?cè)跒楹⒆淤?gòu)買尿布時(shí)順便買了啤酒。
基于上述發(fā)現(xiàn),可以給我們的商品上架或者劃分消費(fèi)人群等提供參考。
本篇給定超市購(gòu)物記錄集sales_detail.csv,提取其中的交易標(biāo)識(shí)符和商品名稱構(gòu)成購(gòu)物籃數(shù)據(jù)集。用A-Priori算法發(fā)現(xiàn)其中的關(guān)聯(lián)規(guī)則。
原理分析及流程
頻繁項(xiàng)集定義
如果項(xiàng)集 I 的支持度不小于閾值 s ,則稱 I 是頻繁項(xiàng)集。
s: 支持度閾值 (support threshold);
項(xiàng)集 I 的支持度(support):包含 I 的購(gòu)物籃 (記錄) 的數(shù)目。
一個(gè)8購(gòu)物籃的例子,假設(shè)有如下8個(gè)購(gòu)物籃:
(1) { Cat, and, dog, bites }
(2) { Yahoo, new, claims, a , cat, mated, with, a, dog, and, produced, viable, offspring }
(3) { Cat, killer, likely, is, a, big, dog }
(4) { Professional, free, advice, on, dog, training, puppy, training }
(5) { Cat, and, kitten, training, and, behavior }
(6) { Dog, &, Cat, provides, dog, training, in, Eugene, Oregon }
(7) { “ Dog, and, cat “, is, a, slang, term, used, by, police, officers, for, a, male-female, relationship }
(8) { Shop, for, your, show, dog, grooming, and, pet, supplies }
我們來(lái)發(fā)現(xiàn)其頻繁項(xiàng):
“cat” :6 ( 除了(4)和(8)的全部購(gòu)物籃中 ) “dog” :7 ( 除了(5)之外的全部購(gòu)物籃中 ) “and” :5 “a”、“traning” :3 “for”、“is” :2 其它不多于1假定給出的支持度閾值 s 為3,頻繁項(xiàng)集為:{dog}、{cat}、{and}、{a}、{training}
單元素的頻繁項(xiàng)在商品銷售中可應(yīng)用于發(fā)現(xiàn)人們經(jīng)常購(gòu)買的商品。
雙元素頻繁項(xiàng)集合
一個(gè)雙元素頻繁項(xiàng)集合中的兩個(gè)元素本身都必須是頻繁的,這樣該集合才有可能是頻繁的。
如上述例子中,可能的雙元素頻繁項(xiàng)集合只有10個(gè),分別是:
{dog, cat}、{dog, and}、{dog, a}、{dog, training}、{cat, and}
{cat, a}、{cat, training}、{and, a}、{and, training}、{a, training}
更多元素的頻繁項(xiàng)集同理。
對(duì)于多元素的頻繁項(xiàng)集在商品銷售中的一個(gè)應(yīng)用就是發(fā)現(xiàn)那些顧客經(jīng)常一起購(gòu)買的商品,以為我們上架提供參考。
關(guān)聯(lián)規(guī)則
不同項(xiàng)集和項(xiàng)之間有許多關(guān)聯(lián)規(guī)則,關(guān)聯(lián)規(guī)則表示形式如下:
I→j(I為項(xiàng)集,j為項(xiàng))I \rightarrow j ( I 為項(xiàng)集, j 為項(xiàng) )I→j(I為項(xiàng)集,j為項(xiàng))III為先決條件,jjj為相應(yīng)的關(guān)聯(lián)結(jié)果,用于表示數(shù)據(jù)內(nèi)隱含的關(guān)聯(lián)性。
1.支持度 Support
支持度是指在所有項(xiàng)集中{I,j}\left \{ I, j \right \}{I,j}出現(xiàn)的可能性,即項(xiàng)集中同時(shí)含有III和jjj的概率,該指標(biāo)作為建立強(qiáng)關(guān)聯(lián)規(guī)則的第一個(gè)門檻,衡量了所考察關(guān)聯(lián)規(guī)則在"量"上的多少。
2.可信度 Confidence
I∩j的支持度/I的支持度I \cap { j }的支持度 / I 的支持度I∩j的支持度/I的支持度即所有包含項(xiàng)集 III 的數(shù)據(jù)記錄中同時(shí)包含項(xiàng) jjj 的比例。置信度表示在先決條件III發(fā)生的條件下,關(guān)聯(lián)結(jié)果jjj發(fā)生的概率,這是生成強(qiáng)關(guān)聯(lián)規(guī)則的第二個(gè)門檻,衡量了所考察的關(guān)聯(lián)規(guī)則在“質(zhì)”上的可靠性。
3. 提升度 Lift
表示“購(gòu)買III的用戶中同時(shí)購(gòu)買j的比例”與“購(gòu)買j的用戶比例”的比值,該指標(biāo)與置信度同樣衡量規(guī)則的可靠性,可以看作是置信度的一種互補(bǔ)指標(biāo)。
以上三個(gè)參數(shù)用于衡量關(guān)聯(lián)規(guī)則的可采用性。
關(guān)聯(lián)規(guī)則參數(shù)設(shè)置問(wèn)題
在進(jìn)行關(guān)聯(lián)規(guī)則的發(fā)現(xiàn)時(shí),我們應(yīng)該注意以下問(wèn)題:對(duì)支持度和置信度等參數(shù)的設(shè)置應(yīng)該合理。
我們?cè)O(shè)想以下情況:支持度如果設(shè)置過(guò)低將導(dǎo)致過(guò)多頻繁項(xiàng)集的發(fā)現(xiàn),從而對(duì)于所得結(jié)果不具有代表性,而如果支持度設(shè)置過(guò)高,則可能頻繁項(xiàng)集發(fā)現(xiàn)的商品是人們每次購(gòu)物都會(huì)大概率購(gòu)買的(比如塑料袋),但這并不是我們想要得到的結(jié)果,我們想要發(fā)現(xiàn)的是那些平時(shí)看上去沒(méi)有聯(lián)系的商品(如啤酒與尿布)。
對(duì)于置信度的設(shè)置也是如此,如果置信度設(shè)置過(guò)低,則關(guān)聯(lián)規(guī)則將變得不太可信,而如果設(shè)置過(guò)高,我們考慮以下情況:某調(diào)和油做活動(dòng)附贈(zèng)醬油,置信度設(shè)置過(guò)高將會(huì)導(dǎo)致我們發(fā)現(xiàn)的結(jié)果是這類“捆綁”銷售的商品,而不是那些真正有關(guān)聯(lián)的商品。
其他參數(shù)也應(yīng)該合理設(shè)置(可多次實(shí)驗(yàn)看輸出結(jié)果)。
A-Priori算法
該算法運(yùn)用于尋找頻繁項(xiàng)集及頻繁項(xiàng)集推出高支持度和可信度的關(guān)聯(lián)規(guī)則。基于如下理論:
如果某個(gè)項(xiàng)集是頻繁的,那么它的所有子集都是頻繁的;而如果它的超集不再頻繁,則稱該項(xiàng)集是最大頻繁項(xiàng)集。
當(dāng)項(xiàng)對(duì)的數(shù)目太多而無(wú)法在內(nèi)存中對(duì)所有的項(xiàng)對(duì)計(jì)數(shù)時(shí),A-Priori算法可以減少必須計(jì)數(shù)的項(xiàng)對(duì)數(shù)目,其代價(jià)是要對(duì)數(shù)據(jù)做兩遍而不是一遍掃描。
A-Priori算法對(duì)于更大頻繁項(xiàng)集的發(fā)現(xiàn)做法如下:
先找到頻繁 1 - 項(xiàng)集集合 L1,然后利用 L1找到頻繁 2 -項(xiàng)集集合 L2,接著用L2找頻繁3-項(xiàng)集集合L3……,直到最后找不到為止。
實(shí)現(xiàn)流程
所給數(shù)據(jù)集的每一行的數(shù)據(jù)是訂單號(hào)、商品名稱及其他參數(shù),首先我們提取所要的訂單號(hào)及商品名稱(去除商品規(guī)格),然后按照訂單號(hào)劃分商品所屬的購(gòu)物籃,再利用Python的第三方模塊apriori庫(kù)的apriori包完成頻繁項(xiàng)集及關(guān)聯(lián)規(guī)則的發(fā)現(xiàn)。
具體實(shí)現(xiàn)
讀入并查看數(shù)據(jù)集的前5行數(shù)據(jù)
In [5]: f = pd.read_csv('sales_detail.csv', encoding='utf-8', sep='\t', header=None) In [6]: f.head() Out[6]:0 1 2 3 4 5 6 7 8 9 10 11 0 34121002436593 1 2012-08-01 07:45:38 5440483 2186463 苦瓜(一級(jí)) 公斤 0.262 4 1.048 3.6 0.94 1 34121002436593 2 2012-08-01 07:45:39 5440483 2186463 苦瓜(一級(jí)) 公斤 0.192 4 0.768 3.6 0.69 2 34121002436593 3 2012-08-01 07:45:45 5440466 2186359 南瓜(一級(jí)) 公斤 4.052 1.98 8.023 1.78 7.21 3 34121002436594 1 2012-08-01 07:45:26 5110324 6934665081392 蒙牛益生菌酸牛奶(原味)1.2kg 桶 1 19.59 19.59 19.59 19.59 4 34121002436595 1 2012-08-01 07:47:18 5110467 6901209206146 光明酸牛奶(紅棗味)180g 盒 2 3.5 7 3.5 7如上,我們所需要的數(shù)據(jù)是訂單號(hào)和商品名,分別在第0列和第5列,且我們觀察商品名,去掉其不同規(guī)格只需要對(duì)商品名做如下處理:截取部分是從左邊第一個(gè)中文字符開(kāi)始,到右邊第一個(gè)非中文字符結(jié)束,所以我們定義去除商品規(guī)格的函數(shù)并進(jìn)行測(cè)試:
In [8]: deprive_bracket_specification('L三全面包(草莓味)1.25kg') Out[8]: '三全面包'如上,我們定義了一個(gè)去除商品規(guī)格的函數(shù)并進(jìn)行了測(cè)試,最終結(jié)果和我們想要的一致。
接下來(lái)就是提取出我們需要的第0列和第5列,并對(duì)第5列商品名去除規(guī)格。
如上,我們提取出了單號(hào)和商品名,并對(duì)商品名去除了規(guī)格。
接下來(lái)按照單號(hào)進(jìn)行分籃子。
分籃結(jié)果如上所示,同一個(gè)訂單中的商品被分到了一起。
接下來(lái)我們利用Python的第三方模塊apriori庫(kù)的apriori包完成頻繁項(xiàng)集及關(guān)聯(lián)規(guī)則的發(fā)現(xiàn)。
如上,我們經(jīng)過(guò)多次實(shí)驗(yàn),設(shè)置了較為合理的參數(shù),并將結(jié)果保存在結(jié)果列表中,下面我們查看結(jié)果列表的一部分?jǐn)?shù)據(jù)。
In [34]: # 查看發(fā)現(xiàn)的頻繁項(xiàng)集...: for meb in result_list[0:10]:...: print(meb.items)...: frozenset({'云煙', '七匹狼'}) frozenset({'利群', '七匹狼'}) frozenset({'紅雙喜', '七匹狼'}) frozenset({'紅塔山', '七匹狼'}) frozenset({'七匹狼', '雄獅'}) frozenset({'云煙', '萬(wàn)寶路'}) frozenset({'萬(wàn)寶路', '利群'}) frozenset({'萬(wàn)寶路', '南京'}) frozenset({'萬(wàn)寶路', '紅雙喜'}) frozenset({'萬(wàn)寶路', '紅塔山'})如上結(jié)果所示,前十個(gè)頻繁項(xiàng)集中兩個(gè)項(xiàng)均為香煙,這并沒(méi)有太大的參考價(jià)值,因?yàn)槲覀兞?xí)慣性是將同一類商品放在一起。
我們對(duì)所有頻繁項(xiàng)集進(jìn)行觀察,發(fā)現(xiàn)了下面這條較為有趣的數(shù)據(jù):
如上,本來(lái)看上去毫無(wú)關(guān)聯(lián)的冰紅茶和毛巾,卻被多次一同購(gòu)買。這可以為我們的商品上架提供參考。
另外,我們還可以通過(guò)調(diào)整參數(shù),發(fā)現(xiàn)其他頻繁項(xiàng)集和關(guān)聯(lián)規(guī)則。
總結(jié)
“啤酒與尿布”的故事給了我們?cè)S多啟示,看似毫無(wú)聯(lián)系的兩件商品,被同時(shí)購(gòu)買的次數(shù)卻不少,通過(guò)對(duì)頻繁項(xiàng)集及關(guān)聯(lián)規(guī)則的挖掘,不僅可以尋找到事物之間平時(shí)不容易被人們發(fā)現(xiàn)的內(nèi)在聯(lián)系,跟深層次的挖掘是我們可以去分析形成此種現(xiàn)象背后的原因。
總而言之,它能夠?yàn)槲覀兲峁┰S多指導(dǎo)。
附錄
數(shù)據(jù)集:sales_detail.csv 及完整代碼已放置于:Github
總結(jié)
以上是生活随笔為你收集整理的基于Python的A-Priori算法发现购物篮关联规则的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【地图服务-nginx代理】
- 下一篇: python-patterns