用Python淺嘗數據挖掘
數據挖掘是啥:
簡單來說,就是對數據進行挖掘,找到數據中的知識或者模式。
數據挖掘的工作就是對數據進行自動或半自動的分析,以提出數據中的模式或知識,例如:數據的分類(聚類分析)、數據異常記錄(異常檢測)、數據間的關係(關聯式規則挖掘)。
工具介紹:
- Python 3.3(及之後的版本)
- 安裝Jupyter Notebook(點此到官網指南):可用命令行安裝 或 直接下載圖形化界面(Jupyter Navigator)
- 「安裝完後在命令行 或 cmd輸入「jupyter notebook」就可以運行啦,如下」
- Jupyter Notebook 有點介於IDE跟編輯器之間,可以做到逐行運行,並且實時展示運行結果(尤其是數據的可視化),並且可以把結果輸出成html5 進行分享或者嵌入網頁。
- 不過初學者直接使用Notebook的話,要注意代碼邏輯之類的,避免養成東一塊西一塊的習慣。
$jupyter notebook
- 安裝scikit-learn(點此前往官網指南)「需要提前安裝NumPy、SciPy」
- - scikit-learn 是個機器學習的庫,包括許多用來做機器學習的演算法、數據集、部件、框架,反正就是蠻適合新手上路的,try it。- NumPy是個擴展庫,核心就是支持多維的矩陣運算(ndarray)。
- SciPy是個演算法庫,也是個數學工具包。
PS:這三個庫會成為我們這段日子最忠實的夥伴。
結合性分析(affinity analyse):
- 舉個小栗子:一個顧客在買某件商品的時候,通常也會買另一件商品。那麼我們就可以通過結合性分析來展示這種關聯關係。「ps:這種結合性分析展示的是數據上的關聯關係(correlation)而不是因果關係(causation),我們資訊管理的教授就經常強調,數據上的關聯不代表因果的推導,謹記,謹記」
- 接下來跑跑程式,看看這種結合性分析是咋樣的。我們假設:客戶在超市買產品X時,很大程度上也會買產品Y。我們的數據在這裡(affinity_dataset.txt),建議先保存到本地,然後在Jupyter上用numpy來載入數據集。
import numpy as np#把路徑改為你數據集的路徑dataset_filename = "/Users/vincentyau/DataMining/withPython/affinity_dataset.txt" #讀取txt文件,但要求每一行數據格式相同x = np.loadtxt(dataset_filename)
- 來查看一下數據集的前5行數據長什麼樣子。「當然最好還是要事先了解數據集的結構」其中每一行數據都代表一次交易購買的產品。如第一行[ 0. 0. 1. 1. 1.],分別代表是bread、milk、cheese、apples和bananas(1代表有購買此商品,0代表沒有)
print(x[:5])
- 這個數據集有100個樣本和5個特徵(features),我們可以通過ndarray的shape方法來將值賦給n_samples, n_features:
n_samples, n_features = x.shape
- 現在將真實的features保存到一個list中:
features = ["bread", "milk", "cheese", "apple", "bananas"]
- 接下來我們要實現一個排序方法,來根據顧客購買的X產品,推測最有可能買的Y產品。這裡先講幾個個概念:支持度(support)、置信度(confidence)、前提索引(premise)與結論索引(conclusion)。
- 支持度:某種情況(稱之為:規則X => Y)在數據集中出現的次數。例如:同時購買bread 與 milk的情況有多少次P(XUY)。(就是某種情況出現的次數有多少)置信度:某種情在數據集中出現的次數與規則中某一部分單獨出現次數的比值。例如:(同時購買bread與mik的次數)/(只購買bread而不購買mik的次數)。前提索引:規則的前提,這裡的bread就被稱為前提索引。
結論索引:規則的結論,這裡的milk就被稱為結論索引。
- 我們可以將數據集中的規則都計算出來,看客戶購買商品之間的關聯:
from collections import defaultdict#設置一些字典來存結果,valid_rules存放有效的規則,num_occurences存放premise出現的次數#valid_rules{鍵(前提,結論),值(字典)}valid_rules = defaultdict(int)invalid_rules = defaultdict(int)#{鍵(前提),值(字典)}num_occurences = defaultdict(int)#對於x中的每一行中的每一個元素(features)for sample in x: for premise in range(n_features): if sample[premise] == 0: continue #如果這個產品沒有被購買的話,則前提不存在,跳出循環 num_occurences[premise] += 1.0 #出現一次前提條件 +1 for conclusion in range(n_features): if premise == conclusion: continue #如果前提和結論是同一件產品,跳出循環 if sample[conclusion] == 1: #如果用戶也購買了這個產品 valid_rules[(premise, conclusion)] += 1 else: invalid_rules[(premise, conclusion)] += 1#支持度就是有效的規則support = valid_rules#confidence字典{鍵(前提,結論),值(字典)}confidence = defaultdict(float)#必須循環每一對rule, 然後構建confidencefor premise, conclusion in valid_rules.keys(): rule = (premise, conclusion) confidence[rule] = valid_rules[rule] / num_occurences[premise] #用可閱讀的方式把規則列印出來for premise, conclusion in confidence: premise_name = features[premise] conclusion_name = features[conclusion] print("規則: 如果一個顧客買了{0},他也會買{1}".format(premise_name, conclusion_name)) print("- Confidence: {0:.3f}".format(confidence[(premise, conclusion)])) print("- Support: {0}".format(support[(premise, conclusion)])) print("")
- 我們可以把列印規則寫成一個函數,之後直接調用:
#把列印的方式寫成函數def print_rule(premise, conclusion, confidence, support, features): premise_name = features[premise] conclusion_name = features[conclusion] print("規則: 如果一個顧客買了{0},他也會買{1}".format(premise_name, conclusion_name)) print("- Confidence: {0:.3f}".format(confidence[(premise, conclusion)])) print("- Support: {0}".format(support[(premise, conclusion)])) print("")
- 把規則都計算完之後,我們來排個序,把最有關聯的情況列印出來:
#對規則進行排序,即同時對support與confidence進行排序,求最好#字典默認沒有順序,因此可以用item()把字典的的數據轉成list,然後用itemgetter來排序from operator import itemgettersorted_support = sorted(support.items(), key = itemgetter(1), reverse = True)sorted_confidence = sorted(confidence.items(), key = itemgetter(1), reverse = True)#列印top5個數據for index in range(5): print("Rule #{0}".format(index + 1)) premise, conclusion = sorted_confidence[index][0] print_rule(premise, conclusion, confidence, support, features)
- 當然也可以用matplotlib把數據結果直接可視化,jupyter對數據可視化的支持賊好:
jupyter#可視化數據結果from matplotlib import pyplot as pltplt.plot([confidence[rule[0]] for rule in sorted_confidence])plt.show()
參考資料:
- Robert Layton. (2017). Learning Data Mining with Python, (2nd ed). Birmingham, UK: Packt Publishing Ltd.
- https://zh.wikipedia.org/wiki/數據挖掘
推薦閱讀:
※python 函數中傳值,傳的是引用還是複製一份傳給另一個函數,會修改調用函數裡面的值嘛?
※如何用Python做詞雲?(基礎篇視頻教程)
※python線程通信與生產者消費者模式
※LocalNote,讓你像使用本地文件一樣使用印象筆記(支持 markdown 格式)
※Python 抓取網頁亂碼原因分析