官术网_书友最值得收藏!

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ù)集和代碼都放進去。在當前目錄在命令行,切換到新建的文件夾,輸入ipython3 notebook命令。——譯者注下,啟動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ī)則一條規(guī)則由前提條件和結(jié)論兩部分組成。——譯者注。簡單粗暴的做法是,找出數(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ī)則沒有多大用處n_samples, n_features = X.shape,詳見本書配套代碼。——譯者注

         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ù)挖掘的另一個功能:預測。

主站蜘蛛池模板: 余江县| 隆昌县| 和林格尔县| 鄂温| 灌阳县| 桦南县| 稻城县| 万载县| 延津县| 扎鲁特旗| 乌什县| 临澧县| 四平市| 道孚县| 肥城市| 涪陵区| 沙雅县| 长治市| 博客| 江北区| 云林县| 永兴县| 曲靖市| 海兴县| 县级市| 靖远县| 临汾市| 晴隆县| 平塘县| 射阳县| 聂荣县| 淮南市| 嘉定区| 武平县| 南靖县| 卢龙县| 山阳县| 华亭县| 峨眉山市| 桃江县| 晋中市|