- Apriori 代碼
import pandas as pd
#自定義連接函數(shù),用于實(shí)現(xiàn)L_{k-1}到C_k的連接
def connect_string(x, ms):
"""
x:頻繁項(xiàng)集列表
ms: 連接符,這里用 ‘---’
return: 返回長度+1的頻繁項(xiàng)集,即L_{k-1}到C_k的連接
"""
x = list(map(lambda i:sorted(i.split(ms)), x)) #去除序列中的連接符,并將元素排列
n = len(x[0]) #每個頻繁項(xiàng)集的長度為 n
r = []
for i in range(len(x)):
for j in range(i,len(x)): # 遍歷每個元素,并與后面所有元素一一比對
if x[i][:n-1] == x[j][:n-1] and x[i][n-1] != x[j][n-1]:# 當(dāng)兩個序列的前 n-1 項(xiàng)相同且第 n 項(xiàng)不同
r.append(x[i][:n-1]+sorted([x[j][n-1],x[i][n-1]])) # 將兩個序列不同的第 n 項(xiàng)和前 n-1 項(xiàng)拼接
return r
#尋找關(guān)聯(lián)規(guī)則的函數(shù)
def find_rule(d, support, confidence, ms = u'---'):
"""
d:轉(zhuǎn)換后的0-1數(shù)據(jù)矩陣
"""
result = pd.DataFrame(index=['support', 'confidence']) #定義輸出結(jié)果
support_series = 1.0*d.sum()/len(d) #支持度序列
column = list(support_series[support_series > support].index) #初步根據(jù)支持度篩選,得一項(xiàng)頻繁集
k = 0
while len(column) > 1:
k = k+1
print(u'\n正在進(jìn)行第%s次搜索...' %k)
column = connect_string(column, ms) # 獲取新的頻繁項(xiàng)集
print(u'數(shù)目:%s...' %len(column))
sf = lambda i: d[i].prod(axis=1, numeric_only = True) #新一批支持度的計(jì)算函數(shù)
# DataFrame.prod() 計(jì)算各軸的乘積,axis=1計(jì)算橫軸
# i 為項(xiàng)集列表,形如:[a,c,e],計(jì)算三列的橫向乘積,結(jié)果為‘1’表示該項(xiàng)集出現(xiàn)一次
#創(chuàng)建連接數(shù)據(jù),這一步耗時、耗內(nèi)存最嚴(yán)重。當(dāng)數(shù)據(jù)集較大時,可以考慮并行運(yùn)算優(yōu)化。
d_2 = pd.DataFrame(list(map(sf,column)), index = [ms.join(i) for i in column]).T
support_series_2 = 1.0*d_2[[ms.join(i) for i in column]].sum()/len(d) #計(jì)算連接后的支持度
column = list(support_series_2[support_series_2 > support].index) #新一輪支持度篩選
support_series = support_series.append(support_series_2)
column2 = []
for i in column: #遍歷可能的推理,如{A,B,C}究竟是A+B-->C還是B+C-->A還是C+A-->B?
i = i.split(ms)
for j in range(len(i)):
column2.append(i[:j]+i[j+1:]+i[j:j+1])
cofidence_series = pd.Series(index=[ms.join(i) for i in column2]) #定義置信度序列
for i in column2: #計(jì)算置信度序列
cofidence_series[ms.join(i)] = support_series[ms.join(sorted(i))]/support_series[ms.join(i[:len(i)-1])]
for i in cofidence_series[cofidence_series > confidence].index: #置信度篩選
result[i] = 0.0 # 建新列
result[i]['confidence'] = cofidence_series[i]
result[i]['support'] = support_series[ms.join(sorted(i.split(ms)))]
result = result.sort_index(ascending=False) #結(jié)果整理,輸出
print(u'\n結(jié)果為:')
print(result.T)
return result.T
- 使用代碼
import pandas as pd
from apriori import * #導(dǎo)入自行編寫的apriori函數(shù)
inputfile = '../data/menu_orders.xls'
outputfile = '../tmp/apriori_rules.xls' #結(jié)果文件
data = pd.read_excel(inputfile, header = None)
print(u'\n轉(zhuǎn)換原始數(shù)據(jù)至0-1矩陣...')
ct = lambda x : pd.Series(1, index = x[pd.notnull(x)]) #轉(zhuǎn)換0-1矩陣的過渡函數(shù),非空值轉(zhuǎn)換成‘1’
b = map(ct, data.values) #用map方式執(zhí)行
data = pd.DataFrame(list(b)).fillna(0) #實(shí)現(xiàn)矩陣轉(zhuǎn)換,空值用0填充
print(u'\n轉(zhuǎn)換完畢。')
del b #刪除中間變量b,節(jié)省內(nèi)存
support = 0.2 #最小支持度
confidence = 0.5 #最小置信度
ms = '---' #連接符,默認(rèn)'--',用來區(qū)分不同元素,如A--B。需要保證原始表格中不含有該字符
find_rule(data, support, confidence, ms).to_excel(outputfile) #保存結(jié)果
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
