【白话机器学习】算法理论+实战之关联规则
1. 寫在前面
如果想從事數據挖掘或者機器學習的工作,掌握常用的機器學習算法是非常有必要的,常見的機器學習算法:
監督學習算法:邏輯回歸,線性回歸,決策樹,樸素貝葉斯,K近鄰,支持向量機,集成算法Adaboost等
無監督算法:聚類,降維,關聯規則, PageRank等
已發布:
【白話機器學習】算法理論+實戰之K近鄰算法
【白話機器學習】算法理論+實戰之決策樹
【白話機器學習】算法理論+實戰之樸素貝葉斯
【白話機器學習】算法理論+實戰之支持向量機(SVM)
【白話機器學習】算法理論+實戰之AdaBoost算法
【白話機器學習】算法理論+實戰之K-Means聚類算法
【白話機器學習】算法理論+實戰之PCA降維
【白話機器學習】算法理論+實戰之EM聚類
為了詳細的理解這些原理,曾經看過西瓜書,統計學習方法,機器學習實戰等書,也聽過一些機器學習的課程,但總感覺話語里比較深奧,讀起來沒有耐心,并且理論到處有,而實戰最重要, 所以在這里想用最淺顯易懂的語言寫一個白話機器學習算法理論+實戰系列。
個人認為,理解算法背后的idea和使用,要比看懂它的數學推導更加重要。idea會讓你有一個直觀的感受,從而明白算法的合理性,數學推導只是將這種合理性用更加嚴謹的語言表達出來而已,打個比方,一個梨很甜,用數學的語言可以表述為糖分含量90%,但只有親自咬一口,你才能真正感覺到這個梨有多甜,也才能真正理解數學上的90%的糖分究竟是怎么樣的。如果算法是個梨,本文的首要目的就是先帶領大家咬一口。另外還有下面幾個目的:
檢驗自己對算法的理解程度,對算法理論做一個小總結
能開心的學習這些算法的核心思想, 找到學習這些算法的興趣,為深入的學習這些算法打一個基礎。
每一節課的理論都會放一個實戰案例,能夠真正的做到學以致用,既可以鍛煉編程能力,又可以加深算法理論的把握程度。
也想把之前所有的筆記和參考放在一塊,方便以后查看時的方便。
學習算法的過程,獲得的不應該只有算法理論,還應該有樂趣和解決實際問題的能力!
今天是白話機器學習算法理論+實戰的第二篇,關聯規則挖掘的學習, 通過今天的學習,應該可以掌握關聯規則挖掘算法apriori算法和FPgrowth的基本原理,并且會通過后面的小實戰掌握算法的運用。
大綱如下:
搞懂關聯規則中的幾個重要概念(頻繁項集,支持度,置信度,提升度)
關聯規則算法之Apriori算法
關聯規則算法之FP-Growth算法
項目實戰(通過幾個小例子說明如何使用mlxtend進行數據關聯分析,然后再介紹一個工具包efficient_apriori,并基于這個工具包進行“導演是如何選擇演員的”一個項目實戰)
OK, let's go !
2. 關聯規則挖掘:我打算還是從啤酒和尿布開始談起:
為了避免后面的故事有點晦澀,先講講數據挖掘界的經典案例:啤酒和尿布的故事吧:
★在美國有嬰兒的家庭中,一般是母親在家中照看嬰兒,年輕的父親前去超市購買尿布。父親在購買尿布的同時,往往會順便為自己購買啤酒,這樣就會出現啤酒與尿布這兩件看上去不相干的商品經常會出現在同一個購物籃的現象。如果這個年輕的父親在賣場只能買到兩件商品之一,則他很有可能會放棄購物而到另一家商店,直到可以一次同時買到啤酒與尿布為止。沃爾瑪發現了這一獨特的現象,開始在賣場嘗試將啤酒與尿布擺放在相同的區域,讓年輕的父親可以同時找到這兩件商品,并很快地完成購物;而沃爾瑪超市也可以讓這些客戶一次購買兩件商品、而不是一件,從而獲得了很好的商品銷售收入,這就是“啤酒與尿布”故事。
”看完這個故事的感想是啥?是不是很奇怪啊?啤酒和尿布這兩個聽起來完全不相關的東西,竟然能夠產生關聯,并且通過挖掘兩個其中的關系,可以使得銷售更好,這背后起作用的就是關聯規則的挖掘。
只要掌握了這項技能,你不僅可以根據超市里的客戶商品明細表,挖掘出哪些商品放在一起可以增大銷售,還可以分析出銀行理財產品的交叉預售,每個手機用戶的APP之間的關聯,還可以自己爬取電影數據,分析關聯,得到導演喜歡用哪些演員,以及哪個演員常和哪個演員經常在一塊拍戲等(后面的實戰里面都有涉及,這叫做一通百通)
哈哈,是不是開始有誘惑力了呢?但需要一些知識作為鋪墊,比如,到底什么是關聯規則呢?
關聯規則這個概念,最早是由 Agrawal 等人在 1993 年提出的。
關聯規則挖掘可以讓我們從數據集中發現項與項(item 與 item)之間的關系,它在我們的生活中有很多應用場景,“購物籃分析”就是一個常見的場景,這個場景可以從消費者交易記錄中發掘商品與商品之間的關聯關系,進而通過商品捆綁銷售或者相關推薦的方式帶來更多的銷售量。
但是在學習具體算法之前,先搞懂幾個概念,因為這些算法選關聯規則時候,都是先依賴著這些標準。
3. 搞懂關聯規則中的幾個概念
為了白話一點,還是通過例子來介紹吧,看一個超市里面購物的例子:
3.1 頻繁項集
頻繁項集是指那些經常出現在一起的物品,例如上圖的{啤酒、尿布、牛奶},從上面的數據集中也可以找到尿布->啤酒的關聯規則,這意味著有人買了尿布,那很有可能他也會購買啤酒。那如何定義和表示頻繁項集和關聯規則呢?這里引入支持度和可信度(置信度)。
3.2 支持度
支持度是個百分比,它指的是某個商品組合出現的次數與總次數之間的比例。支持度越高,代表這個組合出現的頻率越大。
★比如上面的例子里面,我們看到“牛奶”出現了4次,那么5筆訂單中,“牛奶”的支持度就是4/5=0.8。
同理, 我們看到"牛奶+面包"出現了3次,那么這5筆訂單里面"牛奶+面包" 的支持度就是3/5 = 0.6
3.3 置信度
它指的就是當你購買了商品 A的條件下,會有多大的概率購買商品 B,這其實是一個條件概率。
置信度(牛奶→啤酒)=2/4=0.5,代表如果你購買了牛奶,會有0.5的概率會購買啤酒。
置信度(啤酒→牛奶)=2/3=0.67,代表如果你購買了啤酒,會有0.67的概率會購買。
在上面這個例子中:我們看到在4次購買了牛奶的情況下,有2次購買了啤酒,所以(牛奶 -> 啤酒)的置信度就是2/4 = 0.5。
同理, 3 次購買啤酒的情況下,有 2 次購買了牛奶,所以置信度(啤酒→牛奶)=0.67。
3.4?提升度
我們在做商品推薦的時候,重點考慮的是提升度,因為提升度代表的是“商品 A 的出現,對商品 B 的出現概率提升的”程度。
★還是看上面的例子,如果我們單純看置信度 (可樂→尿布)=1,也就是說可樂出現的時候,用戶都會購買尿布,那么當用戶購買可樂的時候,我們就需要推薦尿布么?
”實際上,就算用戶不購買可樂,也會直接購買尿布的,所以用戶是否購買可樂,對尿布的提升作用并不大。(也就是說,沒有可樂出現的地方,用戶也會買尿布,或者說不要根據冷門物品去推薦熱門物品)
我們可以用下面的公式來計算商品 A 對商品 B 的提升度:
★提升度 (A→B)= 置信度 (A→B) / 支持度 (B)
這個公式是用來衡量 A 出現的情況下,是否會對 B 出現的概率有所提升。
所以提升度有三種可能:
提升度 (A→B)>1:代表有提升;
提升度 (A→B)=1:代表有沒有提升,也沒有下降;
提升度 (A→B)<1:代表有下降。
關于關聯規則挖掘,上面的幾個概念也比較關鍵了,基于這幾個關鍵,下面才有了幾個挖掘算法,比較著名的也就是Apriori算法和FP—Growth算法了。下面具體看看。
4. Apriori的工作原理
明白了關聯規則中支持度、置信度和提升度這幾個重要概念,我們來看下 Apriori 算法是如何工作的。
Apriori 算法其實就是查找頻繁項集 (frequent itemset) 的過程。而頻繁項集的定義,需要最小支持度,大于等于最小支持度的項集就是頻繁項集。項集這個概念,英文叫做 itemset,它可以是單個的商品,也可以是商品的組合。還是用例子來說明一下怎么算:
★我們把上面案例中的商品用 ID 來代表,牛奶、面包、尿布、可樂、啤酒、雞蛋的商品 ID 分別設置為 1-6,上面的數據表可以變為:
”假設我隨機指定最小支持度是 50%,也就是 0.5。看下Apriori算法是怎么運算的。
★首先,我們先計算單個商品的支持度,也就是得到 K=1 項的支持度:因為最小支持度是 0.5,所以你能看到商品 4、6 是不符合最小支持度的,不屬于頻繁項集,于是經過篩選商品的頻繁項集就變成:在這個基礎上,我們將商品兩兩組合,得到 k=2 項的支持度:我們再篩掉小于最小值支持度的商品組合,可以得到:我們再將商品進行 K=3 項的商品組合,可以得到:再篩掉小于最小值支持度的商品組合,可以得到:
”通過上面這個過程,我們可以得到 K=3 項的頻繁項集{1,2,3},也就是{牛奶、面包、尿布}的組合。
上面模擬了一遍整個 Apriori 算法的流程,下面總結下 Apriori 算法的遞歸流程:
K=1,計算 K 項集的支持度;
篩選掉小于最小支持度的項集;
如果項集為空,則對應 K-1 項集的結果為最終結果。否則 K=K+1,重復 1-3 步。
但是Apriori 在計算的過程中有以下幾個缺點:
可能產生大量的候選集。因為采用排列組合的方式,把可能的項集都組合出來了;
每次計算都需要重新掃描數據集,來計算每個項集的支持度。
所以 Apriori 算法會浪費很多計算空間和計算時間,為此人們提出了 FP-Growth 算法,它的特點是:
創建了一棵 FP 樹來存儲頻繁項集。在創建前對不滿足最小支持度的項進行刪除,減少了存儲空間。我稍后會講解如何構造一棵 FP 樹;
整個生成過程只遍歷數據集 2 次,大大減少了計算量。
下面來看看FP-Growth算法。
5. Apriori的改進算法:FP-Growth算法
頻繁項集挖掘分為構建 FP 樹,和從 FP 樹中挖掘頻繁項集兩步。
構建 FP 樹 構建 FP 樹時,首先統計數據集中各個元素出現的頻數,將頻數小于最小支持度的元素刪除,然后將數據集中的各條記錄按出現頻數排序,剩下的這些元素稱為頻繁項;接著,用更新后的數據集中的每條記錄構建 FP 樹,同時更新頭指針表。頭指針表包含所有頻繁項及它們的頻數,還有每個頻繁項指向下一個相同元素的指針,該指針主要在挖掘 FP 樹時使用。下面看看例子:統計商品的支持度,去掉不頻繁的項:然后排序:
下面開始構建FP樹的詳細過程:
掃描編號1:
掃描編號2
掃描編號3
掃描編號4
掃描編號5上面就是完整的FP建樹過程。最終版如下:
通過FP樹挖掘頻繁項集 到這里,我們就得到了一個存儲頻繁項集的 FP 樹,以及一個項頭表。我們可以通過項頭表來挖掘出每個頻繁項集。
具體的操作會用到一個概念,叫“條件模式基”,它指的是以要挖掘的節點為葉子節點,自底向上求出 FP 子樹,然后將 FP 子樹的祖先節點設置為葉子節點之和。
我以“啤酒”的節點為例,從 FP 樹中可以得到一棵 FP 子樹,將祖先節點的支持度記為葉子節點之和,得到:
你能看出來,相比于原來的 FP 樹,尿布和牛奶的頻繁項集數減少了。這是因為我們求得的是以“啤酒”為節點的 FP 子樹,也就是說,在頻繁項集中一定要含有“啤酒”這個項。你可以再看下原始的數據,其中訂單 1{牛奶、面包、尿布}和訂單 5{牛奶、面包、尿布、可樂}并不存在“啤酒”這個項,所以針對訂單 1,尿布→牛奶→面包這個項集就會從 FP 樹中去掉,針對訂單 5 也包括了尿布→牛奶→面包這個項集也會從 FP 樹中去掉,所以你能看到以“啤酒”為節點的 FP 子樹,尿布、牛奶、面包項集上的計數比原來少了 2。
”條件模式基不包括“啤酒”節點,而且祖先節點如果小于最小支持度就會被剪枝,所以“啤酒”的條件模式基為空。同理,我們可以求得“面包”的條件模式基為:所以可以求得面包的頻繁項集為{尿布,面包},{尿布,牛奶,面包}。同樣,我們還可以求得牛奶,尿布的頻繁項集,這里就不再計算展示。
這就是FPGrowth的工作原理了。
6. 項目實戰前的熱身
這里是項目實戰前的熱身,在這里主要說一下如何通過工具包使用Apriori算法進行購物籃的分析(調用Apriori算法的庫有兩個,這里都分別使用一下,并說一下區別),然后把購物籃分析的這個思想遷移到超市訂單上以及銀行理財產品的交叉預售和APP的關聯挖掘上。這些任務基本上相似。
6.1 購物籃的商品分析
首先構造數據集:
data = [['牛奶','面包','尿布'],['可樂','面包', '尿布', '啤酒'],['牛奶','尿布', '啤酒', '雞蛋'],['面包', '牛奶', '尿布', '啤酒'],['面包', '牛奶', '尿布', '可樂']]實現Apriori算法的,好多方式,這里介紹兩種:
利用mlxtend包里面的Apriori算法進行數據關聯分析 如果是使用這個包的話, apriori和association_rules一塊使用的,并且這個對處理的數據的格式又要求(必須是寬表的格式) 先導入如下:
TransactionEncoder是進行數據轉換中的,需要先將上面的data數據轉成寬表的形式,何謂寬表,下面的這種:
"""數據轉換""" transEn = TransactionEncoder() oht_ary = transEn.fit_transform(data) new_data = pd.DataFrame(oht_ary, columns=transEn.columns_) new_data數據就變成了下面的這個樣子,所謂寬表,就是把所有的商品都放在列上,每一條購買記錄,如果買了該商品,相應的地方就是1,否則就是0.只有上面這樣的數據,apriori才能處理,下面就很簡單了。兩步搞定:
第一步:計算頻繁項集,在這里可以定義最小支持度進行篩選頻繁項集:
結果如下:
第二步:挖取關聯規則, 這里的準則部分可以使用置信度(confidence),或者是提升度(lift)
這里就挖掘出了關聯規則{啤酒} -> {尿布}, {牛奶} -> {尿布}, {面包} -> {尿布}, {牛奶, 面包} -> {尿布}。
下面小總一下這種方式:
★這種方式一般會用三個函數:
TransactionEncoder: 需要把數據轉成寬表的形式
apriori(): 這里面需要指定最小支持度
association_rules(): 這里面指定篩選準則(置信度或者提升度或者支持度都可以)
優點:最后顯示的關聯規則中,支持度,置信度,提升度等信息非常詳細,一目了然。缺點:數據有特殊的規則要求,處理起來比較麻煩,并且用關聯規則那塊兩個函數分開,用起來麻煩一些。
”efficient-apriori工具包 這個包使用起來簡單一些,只需要一行代碼就可同時把頻繁項集合關聯規則找出來,并且數據不用特殊的處理。
其中 data 是我們要提供的數據集,它是一個 list 數組類型。min_support 參數為最小支持度,在 efficient-apriori 工具包中用 0 到 1 的數值代表百分比,比如 0.5 代表最小支持度為 50%。min_confidence 是最小置信度,數值也代表百分比,比如 1 代表 100%。
”下面用這個包實現以下:
from efficient_apriori import apriori # 設置數據集 data = [('牛奶','面包','尿布'),('可樂','面包', '尿布', '啤酒'),('牛奶','尿布', '啤酒', '雞蛋'),('面包', '牛奶', '尿布', '啤酒'),('面包', '牛奶', '尿布', '可樂')] # 挖掘頻繁項集和頻繁規則 itemsets, rules = apriori(data, min_support=0.5, min_confidence=1) print(itemsets) print(rules)結果如下(和上面產生的關聯規則一樣):這個的優點是使用起來簡單,并且efficient-apriori 工具包把每一條數據集里的項式都放到了一個集合中進行運算,并沒有考慮它們之間的先后順序。因為實際情況下,同一個購物籃中的物品也不需要考慮購買的先后順序。而其他的 Apriori 算法可能會因為考慮了先后順序,出現計算頻繁項集結果不對的情況。所以這里采用的是 efficient-apriori 這個工具包。
6.2 思想遷移以下,完成其他的例子
上面的這個關聯規則方式可以遷移以下,完成許多其他的任務,比如超市中的真實訂單數據,銀行理財產品交叉預售,手機APP之間的關聯等。怎么遷移一下呢? 主要是數據的處理方式:如何把普通的數據轉成寬表的形式。
6.2.1 超市訂單的真實數據
超市訂單的數據data一般長這樣:這種數據的話,需要轉成寬表,但是再轉寬表之前,需要先分類匯總一下:下面的一行代碼
new_data = data.groupby(['訂單號', '購買商品'])['數量'].sum().unstack().reset_index().fillna(0).set_index('訂單號') new_data下面再把數值映射一下,就成了寬表的形式:
def encode_unit(x):if x <= 0:return 0if x >=1 :return 1new_data = new_data.applymap(encode_unit) new_data這就是寬表的形式了,后面和購物籃分析的一樣了,計算頻繁項集,挖掘關聯規則:
frequent_itemset = apriori(new_data, min_support=0.5, use_colnames=True) rules = association_rules(frequent_itemset, metric='confidence', min_threshold=1)6.2.2 銀行理財產品交叉預售
bank數據長這樣:其實和上面的那個差不多,也是先分類匯總 -> 轉成寬表的形式 -> 挖掘
bankset = bank.groupby(['CSR_ID', 'FIN_PROD']).size().unstack().reset_index().set_index('CSR_ID').fillna(0) bank_data = bankset.applymap(encode_unit) # 這個函數見上面 bank_data最后成這個樣子,再和上面一樣的分析方式
6.2.3 手機APP之間的關聯
APP數據長這樣:看了這個是不是懂了遷移的方式了,先根據設備識別號,APP名稱匯總,然后轉成寬表的形式,然后進行挖掘。
app_new = app.groupby(['設備識別號', 'APP名稱']).size().unstack().fillna(0) app_data = app_new.applymap(encode_unit) 在這里插入圖片描述7. 項目實戰 - 導演是如何選擇演員的
這個是通過Apriori算法進行關聯規則挖掘,分析出導演一般喜歡哪些演員,哪個演員一般和哪個演員在一塊演電影。
這里用的導演是寧浩(你也可以用別的), 使用的數據集的格式如下:(前面是寧浩導演的電影的名稱,后面是里面的演員名稱。)關于這個數據,需要使用爬蟲技術,去https://movie.douban.com搜索框中輸入導演姓名,比如“寧浩”。關于爬蟲技術的編寫,這里不多說,之前寫過一個Python爬蟲快速入門,完全可以解決這里的數據爬取問題。下面只給出代碼:
"""下載某個導演的電影數據集""" def dowloaddata(director):# 瀏覽器模擬driver = webdriver.Chrome('C:/Users/ZhongqiangWu/AppData/Local/Google/Chrome/Application/chromedriver')# 寫入csv文件file_name = './' + director + '.csv'out = open(file_name,'w', newline='', encoding='utf-8-sig')csv_write = csv.writer(out, dialect='excel')flags = []"""下載某個指定頁面的數據"""def download(request_url):driver.get(request_url)time.sleep(1)html = driver.find_element_by_xpath("//*").get_attribute("outerHTML")html = etree.HTML(html)# 設置電影名稱,導演演員的XPATHmovie_lists = html.xpath("/html/body/div[@id='wrapper']/div[@id='root']/div[1]//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']")name_lists = html.xpath("/html/body/div[@id='wrapper']/div[@id='root']/div[1]//div[@class='item-root']/div[@class='detail']/div[@class='meta abstract_2']") # 獲取返回的數據個數# 獲取返回的數據個數num = len(movie_lists)if num > 15: # 第一頁會有16條數據, 第一條是導演的介紹# 默認第一個不是,所以需要去掉movie_lists = movie_lists[1:]name_lists = name_lists[1:]for (movie, name_list) in zip(movie_lists, name_lists):# 會存在數據為空的情況if name_list.text is None:continueprint(name_list.text)names = name_list.text.split('/')# 判斷導演是否為指定的directorif names[0].strip() == director and movie.text not in flags:# 將第一個字段設置為電影名稱names[0] = movie.textflags.append(movie.text)csv_write.writerow(names)if num >=14: # 有可能一頁會有14個電影# 繼續下一頁return Trueelse:# 沒有下一頁return False# 開始的ID為0, 每頁增加15個base_url = 'https://movie.douban.com/subject_search?search_text='+director+'&cat=1002&start='start = 0while start < 10000: # 最多抽取10000部電影request_url = base_url + str(start)# 下載數據,并返回是否有下一頁flag = download(request_url)if flag:start = start + 15else:breakout.close()print('finished')"""調用上面的函數""" directorname = '寧浩' dowloaddata(directorname)下面進行關聯規則挖掘,用第二種方式:
director = '寧浩' file_name = './'+director+'.csv' lists = csv.reader(open(file_name, 'r', encoding='utf-8-sig'))# 數據加載 data = [] for names in lists:name_new = []for name in names:# 去掉演員數據中的空格name_new.append(name.strip())data.append(name_new[1:])# 挖掘頻繁項集和關聯規則 itemsets, rules = apriori(data, min_support=0.3, min_confidence=0.8) print(itemsets) print(rules)結果如下:你能看出來,寧浩導演喜歡用徐崢和黃渤,并且有徐崢的情況下,一般都會用黃渤。你也可以用上面的代碼來挖掘下其他導演選擇演員的規律。
8. 總結
今天用了一天的時間,學習了一下關聯規則挖掘,這里的知識淺層的不是太多,上面的這些足夠用,但是只能夠入門的,apriori和FPgrowth的原理希望能理解。?如果想深層次的學習這塊,請查閱其他資料吧。關聯規則可以用到推薦系統的相關方向。
參考:
http://note.youdao.com/noteshare?id=9e93478498d6442cdfccf8b31a52c9d0&sub=0564206895AD473E8986AABC26807269
https://www.ibm.com/developerworks/cn/analytics/library/machine-learning-hands-on2-fp-growth/index.html
https://github.com/xiaomiwujiecao/DataAnalysisInAction
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am喜歡文章,點個在看
總結
以上是生活随笔為你收集整理的【白话机器学习】算法理论+实战之关联规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新的推荐系统论文两篇
- 下一篇: 博士扩招!反正我是你们得不到的学生...