基于Python的A-Priori算法发现购物篮关联规则
基于Python的A-Priori算法發現購物籃關聯規則
前言
一個生動的例子介紹購物籃模型——啤酒與尿布的故事
 有10000個消費者購買了商品,其中購買尿布1000個,購買啤酒2000個,購買面包500個,同時購買尿布和啤酒800個,同時購買尿布和面包100個,
 我們發現同時購買啤酒與尿布的消費者比較多,一個可能的猜測是年輕的爸爸們在為孩子購買尿布時順便買了啤酒。
 基于上述發現,可以給我們的商品上架或者劃分消費人群等提供參考。
本篇給定超市購物記錄集sales_detail.csv,提取其中的交易標識符和商品名稱構成購物籃數據集。用A-Priori算法發現其中的關聯規則。
原理分析及流程
頻繁項集定義
如果項集 I 的支持度不小于閾值 s ,則稱 I 是頻繁項集。
 s: 支持度閾值 (support threshold);
 項集 I 的支持度(support):包含 I 的購物籃 (記錄) 的數目。
一個8購物籃的例子,假設有如下8個購物籃:
 (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 }
我們來發現其頻繁項:
“cat” :6 ( 除了(4)和(8)的全部購物籃中 ) “dog” :7 ( 除了(5)之外的全部購物籃中 ) “and” :5 “a”、“traning” :3 “for”、“is” :2 其它不多于1假定給出的支持度閾值 s 為3,頻繁項集為:{dog}、{cat}、{and}、{a}、{training}
 單元素的頻繁項在商品銷售中可應用于發現人們經常購買的商品。
雙元素頻繁項集合
 一個雙元素頻繁項集合中的兩個元素本身都必須是頻繁的,這樣該集合才有可能是頻繁的。
 如上述例子中,可能的雙元素頻繁項集合只有10個,分別是:
 {dog, cat}、{dog, and}、{dog, a}、{dog, training}、{cat, and}
 {cat, a}、{cat, training}、{and, a}、{and, training}、{a, training}
 更多元素的頻繁項集同理。
對于多元素的頻繁項集在商品銷售中的一個應用就是發現那些顧客經常一起購買的商品,以為我們上架提供參考。
關聯規則
不同項集和項之間有許多關聯規則,關聯規則表示形式如下:
 I→j(I為項集,j為項)I \rightarrow j ( I 為項集, j 為項 )I→j(I為項集,j為項)III為先決條件,jjj為相應的關聯結果,用于表示數據內隱含的關聯性。
1.支持度 Support
 支持度是指在所有項集中{I,j}\left \{ I, j \right \}{I,j}出現的可能性,即項集中同時含有III和jjj的概率,該指標作為建立強關聯規則的第一個門檻,衡量了所考察關聯規則在"量"上的多少。
 2.可信度 Confidence
 I∩j的支持度/I的支持度I \cap { j }的支持度 / I 的支持度I∩j的支持度/I的支持度即所有包含項集 III 的數據記錄中同時包含項 jjj 的比例。置信度表示在先決條件III發生的條件下,關聯結果jjj發生的概率,這是生成強關聯規則的第二個門檻,衡量了所考察的關聯規則在“質”上的可靠性。
 3. 提升度 Lift
 表示“購買III的用戶中同時購買j的比例”與“購買j的用戶比例”的比值,該指標與置信度同樣衡量規則的可靠性,可以看作是置信度的一種互補指標。
 以上三個參數用于衡量關聯規則的可采用性。
關聯規則參數設置問題
在進行關聯規則的發現時,我們應該注意以下問題:對支持度和置信度等參數的設置應該合理。
 我們設想以下情況:支持度如果設置過低將導致過多頻繁項集的發現,從而對于所得結果不具有代表性,而如果支持度設置過高,則可能頻繁項集發現的商品是人們每次購物都會大概率購買的(比如塑料袋),但這并不是我們想要得到的結果,我們想要發現的是那些平時看上去沒有聯系的商品(如啤酒與尿布)。
 對于置信度的設置也是如此,如果置信度設置過低,則關聯規則將變得不太可信,而如果設置過高,我們考慮以下情況:某調和油做活動附贈醬油,置信度設置過高將會導致我們發現的結果是這類“捆綁”銷售的商品,而不是那些真正有關聯的商品。
 其他參數也應該合理設置(可多次實驗看輸出結果)。
A-Priori算法
該算法運用于尋找頻繁項集及頻繁項集推出高支持度和可信度的關聯規則。基于如下理論:
 如果某個項集是頻繁的,那么它的所有子集都是頻繁的;而如果它的超集不再頻繁,則稱該項集是最大頻繁項集。
 當項對的數目太多而無法在內存中對所有的項對計數時,A-Priori算法可以減少必須計數的項對數目,其代價是要對數據做兩遍而不是一遍掃描。
A-Priori算法對于更大頻繁項集的發現做法如下:
先找到頻繁 1 - 項集集合 L1,然后利用 L1找到頻繁 2 -項集集合 L2,接著用L2找頻繁3-項集集合L3……,直到最后找不到為止。
實現流程
所給數據集的每一行的數據是訂單號、商品名稱及其他參數,首先我們提取所要的訂單號及商品名稱(去除商品規格),然后按照訂單號劃分商品所屬的購物籃,再利用Python的第三方模塊apriori庫的apriori包完成頻繁項集及關聯規則的發現。
具體實現
讀入并查看數據集的前5行數據
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 苦瓜(一級) 公斤 0.262 4 1.048 3.6 0.94 1 34121002436593 2 2012-08-01 07:45:39 5440483 2186463 苦瓜(一級) 公斤 0.192 4 0.768 3.6 0.69 2 34121002436593 3 2012-08-01 07:45:45 5440466 2186359 南瓜(一級) 公斤 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如上,我們所需要的數據是訂單號和商品名,分別在第0列和第5列,且我們觀察商品名,去掉其不同規格只需要對商品名做如下處理:截取部分是從左邊第一個中文字符開始,到右邊第一個非中文字符結束,所以我們定義去除商品規格的函數并進行測試:
In [8]: deprive_bracket_specification('L三全面包(草莓味)1.25kg') Out[8]: '三全面包'如上,我們定義了一個去除商品規格的函數并進行了測試,最終結果和我們想要的一致。
 接下來就是提取出我們需要的第0列和第5列,并對第5列商品名去除規格。
如上,我們提取出了單號和商品名,并對商品名去除了規格。
 接下來按照單號進行分籃子。
分籃結果如上所示,同一個訂單中的商品被分到了一起。
 接下來我們利用Python的第三方模塊apriori庫的apriori包完成頻繁項集及關聯規則的發現。
如上,我們經過多次實驗,設置了較為合理的參數,并將結果保存在結果列表中,下面我們查看結果列表的一部分數據。
In [34]: # 查看發現的頻繁項集...: for meb in result_list[0:10]:...: print(meb.items)...: frozenset({'云煙', '七匹狼'}) frozenset({'利群', '七匹狼'}) frozenset({'紅雙喜', '七匹狼'}) frozenset({'紅塔山', '七匹狼'}) frozenset({'七匹狼', '雄獅'}) frozenset({'云煙', '萬寶路'}) frozenset({'萬寶路', '利群'}) frozenset({'萬寶路', '南京'}) frozenset({'萬寶路', '紅雙喜'}) frozenset({'萬寶路', '紅塔山'})如上結果所示,前十個頻繁項集中兩個項均為香煙,這并沒有太大的參考價值,因為我們習慣性是將同一類商品放在一起。
 我們對所有頻繁項集進行觀察,發現了下面這條較為有趣的數據:
如上,本來看上去毫無關聯的冰紅茶和毛巾,卻被多次一同購買。這可以為我們的商品上架提供參考。
另外,我們還可以通過調整參數,發現其他頻繁項集和關聯規則。
總結
“啤酒與尿布”的故事給了我們許多啟示,看似毫無聯系的兩件商品,被同時購買的次數卻不少,通過對頻繁項集及關聯規則的挖掘,不僅可以尋找到事物之間平時不容易被人們發現的內在聯系,跟深層次的挖掘是我們可以去分析形成此種現象背后的原因。
總而言之,它能夠為我們提供許多指導。
附錄
數據集:sales_detail.csv 及完整代碼已放置于:Github
總結
以上是生活随笔為你收集整理的基于Python的A-Priori算法发现购物篮关联规则的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 【地图服务-nginx代理】
 - 下一篇: 科学研究的方法-笔记01-如何提出科学研