- Python數(shù)據(jù)挖掘入門與實踐
- Robert Layton
- 3743字
- 2020-01-10 15:40:58
1.3 親和性分析示例
終于迎來了第一個數(shù)據(jù)挖掘的例子,我們拿這個親和性分析的示例來具體看下數(shù)據(jù)挖掘到底是怎么回事。數(shù)據(jù)挖掘有個常見的應用場景,即顧客在購買一件商品時,商家可以趁機了解他們還想買什么,以便把多數(shù)顧客愿意同時購買的商品放到一起銷售以提升銷售額。當商家收集到足夠多的數(shù)據(jù)時,就可以對其進行親和性分析,以確定哪些商品適合放在一起出售。
1.3.1 什么是親和性分析
親和性分析根據(jù)樣本個體(物體)之間的相似度,確定它們關系的親疏。親和性分析的應用場景如下。
? 向網(wǎng)站用戶提供多樣化的服務或投放定向廣告。
? 為了向用戶推薦電影或商品,而賣給他們一些與之相關的小玩意。
? 根據(jù)基因?qū)ふ矣杏H緣關系的人。
親和性有多種測量方法。例如,統(tǒng)計兩件商品一起出售的頻率,或者統(tǒng)計顧客購買了商品1后再買商品2的比率。當然還有別的方法,比如后面章節(jié)要講的計算個體之間的相似度。
1.3.2 商品推薦
商品銷售從線下搬到線上后,很多之前靠人工完成的工作只有實現(xiàn)自動化,才有望將生意做大。以向上銷售為例,向上銷售出自英文up-selling,指的是向已經(jīng)購買商品的顧客推銷另一種商品。原來線下由人工來完成的商品推薦工作,現(xiàn)在依靠數(shù)據(jù)挖掘技術就能完成,而且每年能為商家多進賬幾億美元,強力助推電子商務革命的發(fā)展!
我們一起看下簡單的商品推薦服務,它背后的思路其實很好理解:人們之前經(jīng)常同時購買的兩件商品,以后也很可能會同時購買。該想法確實很簡單吧,可這就是很多商品推薦服務的基礎,無論線上還是線下。
這種想法很容易轉(zhuǎn)化為算法。顧客購買商品后,在向他們推薦商品前,先查詢一下歷史交易數(shù)據(jù),找到以往他們購買同樣商品的交易數(shù)據(jù),看看同時購買了什么,再把它們推薦給顧客即可。該算法實際表現(xiàn)也不錯,至少比隨機推薦商品更有效。然而,它還有很大的提升空間,這正是數(shù)據(jù)挖掘一展身手的好機會。
為了簡化代碼,方便講解,我們只考慮一次購買兩種商品的情況。例如,人們?nèi)コ屑荣I了面包,又買了牛奶。作為數(shù)據(jù)挖據(jù)入門性質(zhì)的例子,我們希望得到下面這樣的規(guī)則:
如果一個人買了商品X,那么他很有可能購買商品Y。
多件商品的規(guī)則會更為復雜,比如購買香腸和漢堡包的顧客比起其他顧客更有可能購買番茄醬,本書中不涉及這樣的規(guī)則。
1.3.3 在NumPy中加載數(shù)據(jù)集
下載本書配套代碼包,保存到你的計算機上,然后找到這個例子的數(shù)據(jù)集。本例中,建議你新建一個文件夾,把數(shù)據(jù)集和代碼都放進去。在當前目錄下,啟動IPython Notebook,導航進入新建的文件夾,創(chuàng)建一個新的筆記本文件。
處理該數(shù)據(jù)集要用到NumPy的二維數(shù)組,書中大部分例子都會用到這種數(shù)據(jù)結(jié)構(gòu)。數(shù)組看上去像是一張表,每一行表示樣本中一個個體,每一列表示一種特征。
數(shù)組的每一項為個體的某項特征值。說起來有些拗口,為方便講解,使用如下代碼把數(shù)據(jù)集加載進來,稍后輸出數(shù)組的部分數(shù)據(jù)看看效果:
import numpy as np dataset_filename = "affinity_dataset.txt" X = np.loadtxt(dataset_filename)
運行IPython Notebook,創(chuàng)建筆記本文件,在第一個格子中輸入上述代碼。按下Shift+Enter(同時創(chuàng)建新的格子)運行代碼。代碼運行完畢后,第一個格子左側(cè)的方括號中出現(xiàn)一個表示序號的數(shù)字,看到這個數(shù)字就表明程序運行結(jié)束。第一個格子應該如下所示:

對于筆記本文件,前面的代碼運行完后,后面的才能運行;還沒有輪到它運行或是在運行中時,方括號中顯示一個星號。運行結(jié)束后,星號立刻變?yōu)樾蛱枴?/p>
記得把數(shù)據(jù)集文件和筆記本文件放到同一目錄下。否則,請修改上述代碼中dataset_filename變量的值。
接下來,我們看看數(shù)據(jù)集到底是什么樣子。在筆記本空格子中輸入以下代碼,輸出數(shù)據(jù)集的前5行看看:
print(X[:5])
如果你從http://www.packtpub.com網(wǎng)站購買的圖書,登錄后即可下載已購圖書的代碼文件。如果你是從別處購買的圖書,訪問http://www.packtpub.com/support,注冊后,我們可以用電子郵件把你需要的文件發(fā)給你。
上述代碼的運行結(jié)果為前5次交易中顧客都買了什么。

輸出結(jié)果從橫向和縱向看都可以。橫著看,每次只看一行。第一行(0, 0, 1, 1, 1)表示第一條交易數(shù)據(jù)所包含的商品。豎著看,每一列代表一種商品。在我們這個例子中,這五種商品分別是面包、牛奶、奶酪、蘋果和香蕉。從第一條交易數(shù)據(jù)中,我們可以看到顧客購買了奶酪、蘋果和香蕉,但是沒有買面包和牛奶。
每個特征只有兩個可能的值,1或0,表示是否購買了某種商品,而不是購買商品的數(shù)量。1表示顧客至少買了1個單位的該商品,0表示顧客沒有買該種商品。
1.3.4 實現(xiàn)簡單的排序規(guī)則
正如之前所說,我們要找出“如果顧客購買了商品X,那么他們可能愿意購買商品Y”這樣的規(guī)則。簡單粗暴的做法是,找出數(shù)據(jù)集中所有同時購買的兩件商品。找出規(guī)則后,還需要判斷其優(yōu)劣,我們挑好的規(guī)則用。
規(guī)則的優(yōu)劣有多種衡量方法,常用的是支持度(support)和置信度(confidence)。
支持度指數(shù)據(jù)集中規(guī)則應驗的次數(shù),統(tǒng)計起來很簡單。有時候,還需要對支持度進行規(guī)范化,即再除以規(guī)則有效前提下的總數(shù)量。我們這里只是簡單統(tǒng)計規(guī)則應驗的次數(shù)。
支持度衡量的是給定規(guī)則應驗的比例,而置信度衡量的則是規(guī)則準確率如何,即符合給定條件(即規(guī)則的“如果”語句所表示的前提條件)的所有規(guī)則里,跟當前規(guī)則結(jié)論一致的比例有多大。計算方法為首先統(tǒng)計當前規(guī)則的出現(xiàn)次數(shù),再用它來除以條件(“如果”語句)相同的規(guī)則數(shù)量。
接下來,通過一個例子來說明支持度和置信度的計算方法,我們看一下怎么求“如果顧客購買了蘋果,他們也會購買香蕉”這條規(guī)則的支持度和置信度。
如下面的代碼所示,通過判斷交易數(shù)據(jù)中sample[3]的值,就能知道一個顧客是否買了蘋果。這里,sample表示一條交易信息,也就是數(shù)據(jù)集里的一行數(shù)據(jù)。

同理,檢測sample[4]的值是否為1,就能確定顧客有沒有買香蕉。現(xiàn)在可以計算題目給定規(guī)則在數(shù)據(jù)集中的出現(xiàn)次數(shù),從而計算置信度和支持度。
我們需要統(tǒng)計數(shù)據(jù)集中所有規(guī)則的相關數(shù)據(jù)。首先分別為規(guī)則應驗和規(guī)則無效這兩種情況創(chuàng)建字典。字典的鍵是由條件和結(jié)論組成的元組,元組元素為特征在特征列表中的索引值,不要用實際特征名,比如“如果顧客購買了蘋果,他們也會買香蕉”就用(3, 4)表示。如果某個個體的條件和結(jié)論均與給定規(guī)則相符,就表示給定規(guī)則對該個體適用,否則如果通過給定條件推出的結(jié)論與給定規(guī)則的結(jié)論不符,則表示給定規(guī)則對該個體無效。
為了計算所有規(guī)則的置信度和支持度,首先創(chuàng)建幾個字典,用來存放計算結(jié)果。這里使用defaultdict,好處是如果查找的鍵不存在,返回一個默認值。需要統(tǒng)計的量有規(guī)則應驗、規(guī)則無效及條件相同的規(guī)則數(shù)量。
from collections import defaultdict valid_rules = defaultdict(int) invalid_rules = defaultdict(int) num_occurances = defaultdict(int)
計算過程需要用到循環(huán)結(jié)構(gòu),依次對樣本的每個個體及個體的每個特征值進行處理。第一個特征為規(guī)則的前提條件——顧客購買了某一種商品。
for sample in X: for premise in range(5):
檢測個體是否滿足條件,如果不滿足,繼續(xù)檢測下一個條件。
if sample[premise] == 0: continue
如果條件滿足(即值為1),該條件的出現(xiàn)次數(shù)加1。在遍歷過程中跳過條件和結(jié)論相同的情況,比如“如果顧客買了蘋果,他們也買蘋果”,這樣的規(guī)則沒有多大用處。
num_occurances[premise] += 1 for conclusion in range(n_features): if premise == conclusion: continue
如果規(guī)則適用于個體,規(guī)則應驗這種情況(valid_rules字典中,鍵為由條件和結(jié)論組成的元組)增加一次,反之,違反規(guī)則情況(invalid_rules字典中)就增加一次。
if sample[conclusion] == 1: valid_rules[(premise, conclusion)] += 1 else: invalid_rules[(premise, conclusion)] += 1
得到所有必要的統(tǒng)計量后,我們再來計算每條規(guī)則的支持度和置信度。如前所述,支持度就是規(guī)則應驗的次數(shù)。
support = valid_rules
置信度的計算方法類似,遍歷每條規(guī)則進行計算。
confidence = defaultdict(float) for premise, conclusion in valid_rules.keys(): rule = (premise, conclusion) confidence[rule] = valid_rules[rule] / num_occurances[premise]
我們得到了支持度字典和置信度字典,分別包含每條規(guī)則的支持度和置信度。我們再來聲明一個函數(shù),接收的參數(shù)有:分別作為前提條件和結(jié)論的特征索引值、支持度字典、置信度字典以及特征列表。輸出每條規(guī)則及其支持度和置信度,對輸出進行格式化,以方便查看。
之前建立的features列表派上用場了,每條規(guī)則的條件、結(jié)論就是用features列表中特征的索引來表示的。輸出時,把索引替換成相應的特征,更容易讀懂。
premise_name = features[premise] conclusion_name = features[conclusion] print("Rule: If a person buys {0} they will also buy {1}".format(premise_name, conclusion_name))
接著輸出規(guī)則的支持度和置信度。
print(" - Support: {0}".format(support[(premise, conclusion)])) print(" - Confidence: {0:.3f}".format(confidence[(premise, conclusion)]))
寫完后,自己測試一下代碼是否可用——嘗試更換條件和結(jié)論,看看輸出結(jié)果如何。

1.3.5 排序找出最佳規(guī)則
得到所有規(guī)則的支持度和置信度后,為了找出最佳規(guī)則,還需要根據(jù)支持度和置信度對規(guī)則進行排序,我們分別看一下這兩個標準。
要找出支持度最高的規(guī)則,首先對支持度字典進行排序。字典中的元素(一個鍵值對)默認為沒有前后順序;字典的items()函數(shù)返回包含字典所有元素的列表。我們使用itemgetter()類作為鍵,這樣就可以對嵌套列表進行排序。itemgetter(1)表示以字典各元素的值(這里為支持度)作為排序依據(jù),reverse=True表示降序排列。
from operator import itemgetter sorted_support = sorted(support.items(), key=itemgetter(1), re verse=True)
排序完成后,就可以輸出支持度最高的前5條規(guī)則。
for index in range(5): print("Rule #{0}".format(index + 1)) premise, conclusion = sorted_support[index][0] print_rule(premise, conclusion, support, confidence, features)
結(jié)果如下所示:

同理,我們還可以輸出置信度最高的規(guī)則。首先根據(jù)置信度進行排序。
sorted_confidence = sorted(confidence.items(), key=itemgetter(1), reverse=True)
再次輸出看看結(jié)果。注意輸出方法相同,但是請留意下面第三行代碼里sorted_confidence的變化,不要繼續(xù)使用sorted_support。
for index in range(5): print("Rule #{0}".format(index + 1)) premise, conclusion = sorted_confidence[index][0] print_rule(premise, conclusion, support, confidence, features)

從排序結(jié)果來看,“顧客買蘋果,也會買奶酪”和“顧客買奶酪,也會買香蕉”,這兩條規(guī)則的支持度和置信度都很高。超市經(jīng)理可以根據(jù)這些規(guī)則來調(diào)整商品擺放位置。例如,如果本周蘋果促銷,就在旁邊擺上奶酪。但是香蕉和奶酪同時搞促銷就沒有多大意義了,因為我們發(fā)現(xiàn)購買奶酪的顧客中,接近66%的人即使不搞促銷也會買香蕉——即使搞促銷,也不會給銷量帶來多大提升。
從上面這個例子就能看出數(shù)據(jù)挖掘的洞察力有多強大。人們可以用數(shù)據(jù)挖掘技術探索數(shù)據(jù)集中各變量之間的關系,尋找新發(fā)現(xiàn)。接下來一節(jié),我們看看數(shù)據(jù)挖掘的另一個功能:預測。
- Dreamweaver CS3+Flash CS3+Fireworks CS3創(chuàng)意網(wǎng)站構(gòu)建實例詳解
- Div+CSS 3.0網(wǎng)頁布局案例精粹
- 傳感器技術實驗教程
- 機器人智能運動規(guī)劃技術
- Expert AWS Development
- 深度學習中的圖像分類與對抗技術
- 統(tǒng)計策略搜索強化學習方法及應用
- Kubernetes for Developers
- 水下無線傳感器網(wǎng)絡的通信與決策技術
- HTML5 Canvas Cookbook
- 所羅門的密碼
- 和機器人一起進化
- 計算機應用基礎實訓(職業(yè)模塊)
- 軟件質(zhì)量管理實踐
- 工業(yè)機器人技術