天天看點

Python-Apriori親和性分析(執行個體)

一、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')
           

三、結果

Python-Apriori親和性分析(執行個體)
Python-Apriori親和性分析(執行個體)