1. 程式人生 > >《Python資料分析與挖掘實戰》第8章——Apriori關聯規則

《Python資料分析與挖掘實戰》第8章——Apriori關聯規則

本文是基於《Python資料分析與挖掘實戰》的實戰部分的第八章的資料——《中醫證型關聯規則挖掘》做的分析。

旨在補充原文中的細節程式碼,並給出文中涉及到的內容的完整程式碼。

主要有:1)將原始資料按照聚類結果進行標記類別

1 背景與目標分析

    此專案旨在根據相關資料建模,獲取中醫證素與乳腺癌TNM分期之間的關係。

2 資料預處理

2.1 資料變換

2.1.1 資料離散化

datafile = 'data.xls'
resultfile = 'data_processed.xlsx'

typelabel = {u'肝氣鬱結證型係數':'A',u'熱毒蘊結證型係數':'B',u'衝任失調證型係數':'C',u'氣血兩虛證型係數':'D',u'脾胃虛弱證型係數':'E',u'肝腎陰虛證型係數':'F'}

k = 4 #需要進行的聚類類別數

#讀取檔案進行聚類分析
data = pd.read_excel(datafile)
keys = list(typelabel.keys())
result = DataFrame()

for i in range(len(keys)):
    #呼叫k-means演算法 進行聚類
    print(u'正在進行%s的聚類' % keys[i])
    kmodel = KMeans(n_clusters = k, n_jobs = 4)  # n_job是執行緒數,根據自己電腦本身來調節
    kmodel.fit(data[[keys[i]]].as_matrix())# 訓練模型
#     kmodel.fit(data[[keys[i]]]) # 不轉成矩陣形式結果一樣
#KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
#     n_clusters=4, n_init=10, n_jobs=4, precompute_distances='auto',
#     random_state=None, tol=0.0001, verbose=0)
    
    r1 = DataFrame(kmodel.cluster_centers_, columns = [typelabel[keys[i]]]) # 聚類中心
    r2 = Series(kmodel.labels_).value_counts() #分類統計
    r2 = DataFrame(r2,columns = [typelabel[keys[i]]+'n'])# 轉成DataFrame格式,記錄各個類別的數目
    r = pd.concat([r1,r2], axis=1).sort_values(typelabel[keys[i]])
    r.index = range(1,5)
    r[typelabel[keys[i]]] = pd.rolling_mean(r[typelabel[keys[i]]],2) # rolling_mean用來計算相鄰兩列的均值,以此作為邊界點
    r[typelabel[keys[i]]][1] = 0.0 # 將原來的聚類中心改成邊界點
    result = result.append(r.T)
result = result.sort_index() # 以index排序,以ABCDEF排序
result.to_excel(resultfile)
    
print (result)

2.1.2 劃分原始資料中的類別

# 將分類後資料進行處理(*****)
data_cut = DataFrame(columns = data.columns[:6])
types = ['A','B','C','D','E','F']
num = ['1','2','3','4']
for i in range(len(data_cut.columns)):
    value = list(data.iloc[:,i])
    bins = list(result[(2*i):(2*i+1)].values[0])
    bins.append(1)
    names = [str(x)+str(y) for x in types for y in num]
    group_names = names[4*i:4*(i+1)]
    cats = pd.cut(value,bins,labels=group_names,right=False)
    data_cut.iloc[:,i] = cats
data_cut.to_excel('apriori.xlsx')
data_cut.head()
# 注意!本文中作者最後建模的時候並沒有使用這份資料進行建模,當輸入這份資料時,結果為空!

3 模型建立

inputfile ='apriori.txt' #輸入事務集檔案
# '''apriori.txt中檔案格式如下
# A1,B2,C1,D3,E2,F1,H2
# A2,B2,C1,D2,E2,F1,H3
# A3,B4,C2,D3,E4,F1,H4
# A3,B1,C2,D1,E1,F1,H1
# '''
data2 = pd.read_csv(inputfile, header=None, dtype=object)# 此檔案是作者建模時的資料,執行後正常。
# data2 = pd.read_excel('apriori.xlsx', header=0) # !!!此檔案是在預處理時進行離散化後得到的,輸出結果有誤!為空!

start = time.clock() # 計時開始
print(u'\n轉換原始資料至0-1矩陣')

ct = lambda x: Series(1, index = x[pd.notnull(x)]) # 將標籤資料轉換成1,是轉換0-1矩陣的過渡函式
b = map(ct, data2.as_matrix())# 用map方式執行
data3 = DataFrame(b).fillna(0)
end = time.clock() #計時開始

print (u'轉換完畢,用時%s秒' % (end-start))
del b #刪除中間變數b 節省記憶體

support = 0.06 #最小支援度
confidence = 0.75 #最小置信度
ms = '---'# 用來區分不同元素,需要保證原始表格中無該字元

start = time.clock() #計時開始
print(u'\n開始搜尋關聯規則...')
find_rule(data3, support, confidence, ms)
end = time.clock() 
print (u'\n搜尋完成,用時:%.2f秒' % (end-start))

模型改進:

由於書中作者給出的程式碼並沒有運用到剪枝策略,因此採用了這篇文章的程式碼,將該程式碼中load_data_set()函式中的內容改成如圖:


其執行的結果如下:


備註:本章節完整程式碼詳見點選開啟連結