關(guān)聯(lián)分析用來尋找事務(wù)之間的相關(guān)性,這些關(guān)系主要有兩種形式恨搓,頻繁項(xiàng)目集或者關(guān)聯(lián)規(guī)則弟跑。
關(guān)聯(lián)分析涉及的術(shù)語和指標(biāo):
術(shù)語
? ?頻繁項(xiàng)目集合(frequent item )經(jīng)常出現(xiàn)在一塊的物品的集合眯勾;
? ?關(guān)聯(lián)規(guī)則(association rules),暗示兩種物品之間可能會存在很強(qiáng)的關(guān)系夭织。
指標(biāo)
支持度:數(shù)據(jù)集合中包含該項(xiàng)集的記錄比例。(集合出現(xiàn)概率p(a))
可信度:支持度(ab)/支持度(a) 吠撮。(集合的條件概率p(ab)/p(a))
重要定理:
1.0 如果一個項(xiàng)目集是頻繁的那么它的子集也是頻繁的?
2.0如果項(xiàng)目abc對d的支持度不夠那么尊惰,那么ab>-cd,ac>-bd也是不夠的
Apriori算法圖解:
0,1,2,3表示4種不同的商品泥兰,下面是他們可能的集合
1.0 關(guān)于支持度的?
Apriori:如果一個項(xiàng)目集合是頻繁的弄屡,那么它的子集也是頻繁的
反過來說:如果一個項(xiàng)目集是非頻繁的,那么它的所有超集也是非頻繁的?
(如果p(a)<0.5鞋诗,那么p(ab)一定小于0.5)膀捷,見下圖23組合被排除,灰色的組合也將被排除
2.0關(guān)于置信度?
對于集合{a,b,c,d}而言削彬,如果abc全庸,對d的支持度是不夠的那么,ab對cd吃警,ac對bd糕篇,a對bcd的支持度也是不夠的。
通過這兩種算法可以排除大量的酌心,非候選項(xiàng)目拌消,從而減少運(yùn)算量。
--------py代碼實(shí)現(xiàn)
#coding: utf-8
import? xlrd ,xlwt
from? pprint? import? pprint
import chardet
data=xlrd.open_workbook(r"C:\Users\mei-huang\Desktop\data1.xlsx")
try:
? ? table=data.sheets()[1]? #通過索引順序獲取
? ? # table = data.sheet_by_index(0)? # 通過索引順序獲取
? ? # table = data.sheet_by_name(u'Sheet1')? # 通過名稱獲取
except:
? ? print("no sheet? in %s named? sheet1"%data)
print(table.nrows,table.ncols)
# print(table.cell(2,3).value)
dataset=[]
for? n? in? range(table.nrows):
? ? col=[]
? ? for? c in range(table.ncols):
? ? ? ? if? not? len(table.cell(n,c).value)==0 :
? ? ? ? ? ? col.append(table.cell(n,c).value)
? ? dataset.append(col)
# pprint(len(dataset)安券,type(dataset)))
#1.1 定義函數(shù)集合 返回整個數(shù)據(jù)集的單元素集合
def createS1(Dataset):
? ? S1=[]
? ? for? a? in dataset :
? ? ? ? for? b? in? a :
? ? ? ? ? ? if? [b] not in? S1 :
? ? ? ? ? ? ? ? S1.append([b])
? ? S1.sort()
? ? return map(frozenset,S1)
# 1.2返回滿足支持度的集合(用于構(gòu)建二元集合)和集合的支持度
def? applyS1(Dataset,S1,MINsuport):
? ? supportS1_dir1 = {}
? ? for? a? in S1? :
? ? ? ? x=0
? ? ? ? for? b? in? dataset :
? ? ? ? ? if? ? set(a).issubset(b) :
? ? ? ? ? ? ? x+=1
? ? ? ? ? ? ? supportS1_dir1[frozenset(a)]=x
? ? # print(supportS1_dir1)
? ? supportS1_list=[]
? ? supportS1_dir = {}
? ? itemlen=len(dataset)
? ? for? x? ,y? in? supportS1_dir1.items():
? ? ? ? if? y>= MINsuport*itemlen :
? ? ? ? ? ? supportS1_list.append(x)
? ? ? ? ? ? supportS1_dir[x]=supportS1_dir1[x]/itemlen
? ? return supportS1_list ,supportS1_dir
# 查看返回結(jié)果
xx,yy=applyS1(dataset,createS1(dataset),0)
print(sorted(yy.items(), key=lambda e: e[1], reverse=True))
import? xlwt
book = xlwt.Workbook(encoding='utf-8', style_compression=0)
sheet = book.add_sheet('test', cell_overwrite_ok=True)
n=0
for? x,y in? yy.items():
? ? sheet.write(n, 1, str(x))
? ? sheet.write(n, 2, str(y))
? ? n+=1
book.save(r'e:\test1.csv')
#生成包含兩個元素的集合S2
def createS2(Lk, k=1): #creates s2
? ? retList = []
? ? lenLk = len(Lk)
? ? for i in range(lenLk):
? ? ? ? for j in range(i+1, lenLk):
? ? ? ? ? ? #?(以下三行)前k-2個項(xiàng)相同時墩崩,將兩個集合合并
? ? ? ? ? ? # 一個k+1集合存在的話,其中每個元素都在k集合中出現(xiàn)
? ? ? ? ? ? L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
? ? ? ? ? ? L1.sort(); L2.sort()
? ? ? ? ? ? if L1==L2: #如果出現(xiàn)共同集合就合并
? ? ? ? ? ? ? ? retList.append(set(Lk[i]) | set(Lk[j]))
? ? return retList
# xx=createS2(createS1(dataset))
# x,y=applyS1(dataset,xx,0.1)
# print(sorted(y.items(), key=lambda e: e[1], reverse=True))
def apriori(dataSet, minSupport = 0.5):
? ? #算出單元素的頻繁項(xiàng)目集
? ? C1 = createS1(dataSet)
? ? D = map(set, dataSet)
? ? L1, supportData = applyS1(D, C1, minSupport)
? ? L = [L1]
? ? k = 2
? ? #計(jì)算多元素的頻繁項(xiàng)目集合
? ? while (len(L[k-2]) > 0):
? ? ? ? Ck = createS2(L[k-2], k)
? ? ? ? #?? 掃描數(shù)據(jù)集侯勉,從Ck得到Lk
? ? ? ? Lk, supK = applyS1(D, Ck, minSupport)
? ? ? ? supportData.update(supK)
? ? ? ? L.append(Lk)
? ? ? ? k += 1
? ? return L, supportData
xx, yy = apriori(dataset, 0.0)
# print(type(yy))
# print(yy)
# print(len(yy),sorted(yy.items(), key=lambda e: e[1], reverse=True))
# # print(yy[('丹參', '黃芪', '大黃')])
#導(dǎo)出excel
# #生成關(guān)聯(lián)規(guī)則
#主函數(shù)
def generateRules(L, supportData, minConf=0.7):? #頻繁項(xiàng)目集鹦筹,頻繁項(xiàng)目集合字典,支持度
? ? bigRuleList = []
? ? #? 只獲取有兩個或更多元素的集合
? ? for i in range(1, len(L)):? #循環(huán)頻繁項(xiàng)目集
? ? ? ? for freqSet in L[i]:? #頻繁項(xiàng)目集中的元素
? ? ? ? ? ? # print(freqSet)
? ? ? ? ? ? H1 = [tuple([item]) for item in freqSet]
? ? ? ? ? ? # print("aa",H1)
? ? ? ? ? ? if (i > 1):? #頻繁集的元素>2
? ? ? ? ? ? ? ? rulesFromConseq(freqSet, H1, supportData, bigRuleList,minConf)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? calcConf(freqSet, H1, supportData, bigRuleList, minConf)
? ? return bigRuleList
#判斷指定的規(guī)則是否滿足
def calcConf(freqSet, H, supportData, brl, minConf=0.7):
? ? prunedH = []
? ? for conseq in H:
? ? ? ? conseq=frozenset(list(conseq))
? ? ? ? conf = supportData[freqSet]/ supportData[freqSet - conseq]
? ? ? ? #若果找不就對變量進(jìn)行順序倒置然后再找
? ? ? ? if conf >= minConf:
? ? ? ? ? ? print (freqSet-conseq,'-->',conseq,'conf:',conf)
? ? ? ? ? ? brl.append((freqSet-conseq, conseq, conf))
? ? ? ? ? ? prunedH.append(conseq)
? ? return prunedH
#生成關(guān)聯(lián)規(guī)則
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7): #頻繁項(xiàng)目集址貌,可以出現(xiàn)在右側(cè)的元素列表
? ? m = len(H[0])? #右側(cè)列表第一個元素的長度
? ? #? 嘗試進(jìn)一步合并
? ? if (len(freqSet) > (m + 1)):
? ? ? ? #? 創(chuàng)建Hm+1條新候選規(guī)則
? ? ? ? Hmp1 = createS2(H, m + 1)
? ? ? ? Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
? ? ? ? if (len(Hmp1) > 1): #遞歸函數(shù)
? ? ? ? ? ? rulesFromConseq(freqSet, Hmp1,supportData, brl, minConf)
# print(sorted(yy.items(), key=lambda e: e[1], reverse=True))
z=generateRules(xx, yy, minConf=0.1)
print(z)
#導(dǎo)出數(shù)據(jù)
import? xlwt
book = xlwt.Workbook(encoding='utf-8', style_compression=0)
sheet = book.add_sheet('test', cell_overwrite_ok=True)
sheet2 = book.add_sheet('test2', cell_overwrite_ok=True)
n=0
for? x in? yy.items():
? ? # print(x)
? ? sheet.write(n, 1, str(x))
? ? n+=1
b=0
for? y? in? z:
? ? sheet2.write(b, 1, str(y))
? ? b += 1
book.save(r'e:\test1.csv')