一、Apriori算法原理
從資料集頻繁出現的商品中選出共同出現的商品組成頻繁項集,生成關聯規則
如果通過周遊每一種組合,那麼資料量太大了,我們這裡引入支援度的概念
例如:
要生成包含商品A、B的頻繁項集(A,B),要求支援度至少為30
那麼A和B都必須至少在資料集中出現30次,(A,B)至少也要出現30次
二、執行個體
現有100k有關電影打分的資料
目标:輸出“如果使用者喜歡A,那麼他有可能喜歡B”
1.擷取資料
資料下載下傳位址:http://grouplens.org/datasets/movielens/
下載下傳100k的那一個資料
2.pandas加載資料
import os
import pandas as pd
from collections import defaultdict
import sys
from operator import itemgetter
ratings_filename='C:/Users/F.S.Z/Desktop/資料挖掘學習ing/Data/ml-100k/u.data'
all_ratings=pd.read_csv(ratings_filename,delimiter="\t",header=None,names=["UserID","MovieId","Rating","Datetime"],engine='python')
all_ratings["Favorable"]=all_ratings["Rating"]>3#評分大于3認為喜歡這部電影
3.Apriori算法實作
(1)選取200名使用者,擷取每個使用者喜歡的所有電影,擷取熱門電影排名
ratings=all_ratings[all_ratings["UserID"].isin(range(200))]
favorable_ratings=ratings[ratings["Favorable"]]#隻要喜歡的電影
favorable_reviews_by_users=dict((k,frozenset(v.values))for k,v in favorable_ratings.groupby("UserID")["MovieId"])
num_favorable_by_movie=ratings[["MovieId","Favorable"]].groupby("MovieId").sum()
(2)設定最小支援度,擷取頻繁項集
frequent_itemsets={}#頻繁項集的字典
min_support=50#最小支援度
frequent_itemsets[1]=dict((frozenset((movie_id,)),row["Favorable"])for movie_id,row in num_favorable_by_movie.iterrows() if row["Favorable"]>min_support)#包含一個元素的平凡項集
def find_frequent_itemsets(favorable_reviews_by_users,k_i_itemsets,min_support):#在前一個頻繁項集的基礎上使頻繁項集包含的元素個數加一
counts=defaultdict(int)#計數字典
for user,reviews in favorable_reviews_by_users.items():#周遊每一個使用者喜歡的所有電影
for itemset in k_i_itemsets:#周遊上一個頻繁項集
if itemset.issubset(reviews):#如果頻繁項集中的一個集合是這個使用者喜歡所有電影集合的子集
for other_reviewed_movie in reviews-itemset:#把這個使用者喜歡的其他電影單個周遊
current_superset=itemset|frozenset((other_reviewed_movie,))#與前一個頻繁項集進行合并,生成新的頻繁項集
counts[current_superset]+=1#該個頻繁項集計數加一
return dict([(itemset,frequency)for itemset,frequency in counts.items() if frequency>=min_support])#傳回新的頻繁項集
for k in range(2,20):#生成含2-20個元素的頻繁項集
cur_frequent_itemsets=find_frequent_itemsets(favorable_reviews_by_users,frequent_itemsets[k-1],min_support)
frequent_itemsets[k]=cur_frequent_itemsets
if len(cur_frequent_itemsets)==0:
print("Did not find any frequent itemsets of length{}".format(k))
sys.stdout.flush()#這個是確定代碼還在運作時,把緩沖區内容輸出到終端
else:
print("I found {} frequent itemsets of length {}".format(len(cur_frequent_itemsets),k))
sys.stdout.flush()
del frequent_itemsets[1]#删除隻含一個元素的頻繁項集
(3)提取關聯規則
candidate_rules=[]
for itemset_length,itemset_counts in frequent_itemsets.items():
for itemset in itemset_counts.keys():
for conclusion in itemset:
premise=itemset-set((conclusion,))
candidate_rules.append((premise,conclusion))
(4)計算訓練置信度
correct_counts=defaultdict(int)
incorrect_counts=defaultdict(int)
for user,reviews in favorable_reviews_by_users.items():
for candidate_rule in candidate_rules:
premise,conclusion=candidate_rule
if premise.issubset(reviews):
if conclusion in reviews:
correct_counts[candidate_rule]+=1
else:
incorrect_counts[candidate_rule]+=1
rule_confidence={candidate_rule:correct_counts[candidate_rule]/float(correct_counts[candidate_rule]+incorrect_counts[candidate_rule])for candidate_rule in candidate_rules}
sorted_confidence=sorted(rule_confidence.items(),key=itemgetter(1),reverse=True)#按置信度排序
(5)選擇測試資料集
test_dataset=all_ratings[~all_ratings["UserID"].isin(range(200))]#選取除訓練資料中200位使用者外的使用者
test_favorable=test_dataset[test_dataset["Favorable"]]
test_favorable_by_users=dict((k,frozenset(v.values))for k,v in test_favorable.groupby("UserID")["MovieId"])
(6)計算測試置信度
correct_counts=defaultdict(int)
incorrect_counts=defaultdict(int)
for user,reviews in test_favorable_by_users.items():
for candidate_rule in candidate_rules:
premise,conclusion=candidate_rule
if premise.issubset(reviews):
if conclusion in reviews:
correct_counts[candidate_rule]+=1
else:
incorrect_counts[candidate_rule]+=1
test_confidence={candidate_rule:correct_counts[candidate_rule]/float(correct_counts[candidate_rule]+incorrect_counts[candidate_rule])for candidate_rule in rule_confidence}
(7)輸出關聯規則
for index in range(5):
print("#Rule #{}".format(index+1))
(premise,conclusion)=sorted_confidence[index][0]
print("Rule:If a person recommends{},they will also recommend {}".format(premise,conclusion))
print("- Confidence:{0:.3f}".format(rule_confidence[(premise,conclusion)]))
print("- test Confidence:{0:.3f}".format(test_confidence[(premise, conclusion)]))
print('\n')