Apriori算法预测电影代码与数据下载

作者: _aLIEz | 来源:发表于2020-01-19 12:25 被阅读0次

    ml-100k数据下载: https://pan.baidu.com/s/1niJ367imL5LGNL5LnmqMZw

    • 加载数据集
    import pandas as pd
    ratings_filename = "C:/Users/‘/Desktop/ml-100k/u.data"
    all_ratings = pd.read_csv(ratings_filename, delimiter="\t", header=None, names = ["UserID", "MovieID", "Rating", "Datetime"]) #加载数据集时,把分隔符设置为制表符,告诉pandas不要把第一行作为表头(header=None),设置好各列的名称。
    all_ratings["Datetime"] = pd.to_datetime(all_ratings['Datetime'],unit='s')#时间格式转换
    all_ratings[:5]   #运行下面的代码,看一下前五条记录
    
    • 数据处理
    all_ratings["Favorable"] = all_ratings["Rating"] > 3    #为此创建新特征Favorable,若用户喜欢该电影,值为True。
    all_ratings[10:15] 
    
    # # 从数据集中选取一部分数据用作训练集,这能有效减少搜索空间,提升Apriori算法的速度。我们取前200名用户的打分数据
    ratings = all_ratings[all_ratings['UserID'].isin(range(200))]  
    # 选择用户喜欢的电影
    favorable_ratings = ratings[ratings["Favorable"]]
    favorable_ratings[:5]
    
    #字典中k:userId,v:电影集合 favorable_ratings.groupby("UserID")["MovieID"]为series
    favorable_reviews_by_users = dict((k, frozenset(v.values)) for k, v in favorable_ratings.groupby("UserID")["MovieID"])#frozenset不
    # 统计每部电影的喜欢程度
    num_favorable_by_movie = ratings[["MovieID", "Favorable"]].groupby("MovieID").sum()   #创建一个数据框,以便了解部电影的影迷数量。
    num_favorable_by_movie.sort_values("Favorable", ascending=False)[:5]#最受欢迎的五部电影  
    
    • Apriori算法应用
      1. 创建初始频繁项集
      2. 通过当前的频繁项集创建后继项集。
      3. 判断后继项集是否为频繁项集,舍去那些不是的。
      4. 返回所有的频繁项集。
    #画出过程图就能明白了
    from collections import defaultdict
    #定义一个函数,实现算法第二、三步:用现有的频繁项集生成备选集,判断是否频繁
    def find_frequent_itemsets(favorable_reviews_by_users, k_1_itemsets, min_support):#输入:用户喜欢的电影(字典),初代频繁项集,支持度
        counts = defaultdict(int)
        #遍历用户和他们打分的数据(喜欢的电影)
        for user, reviews in favorable_reviews_by_users.items():
            #遍历项集,判断他们是否是当前评分项集的子集
            for itemset in k_1_itemsets: #itemset为电影ID集合
                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])
    import sys
    frequent_itemsets = {} # 键:项集长度 值:频繁项集(字典结构,键:包含电影ID的集合,值:支持度)
    min_support = 50 #预设最小支持度
    # k=1,项集长度为1,算法第一步,为每一部电影生成只包含自己的项集,判断是否频繁
    frequent_itemsets[1] = dict((frozenset((movie_id,)), row["Favorable"])for movie_id, row in num_favorable_by_movie.iterrows()if row["Favorable"] > min_support)
    print("有{}部电影超过{}支持度".format(len(frequent_itemsets[1]), min_support))
    sys.stdout.flush()
    for k in range(2, 20):
        cur_frequent_itemsets = find_frequent_itemsets(favorable_reviews_by_users, frequent_itemsets[k-1],min_support)
        if len(cur_frequent_itemsets) == 0:
            print("没有找到新的频繁项集长度为{}的集合".format(k))
            sys.stdout.flush()
            break
        else:
            print("找到了繁项集{}长度为{}".format(len(cur_frequent_itemsets), k))
            #print(cur_frequent_itemsets)
            sys.stdout.flush()
            frequent_itemsets[k] = cur_frequent_itemsets
    del frequent_itemsets[1]
    print("一共{0}个频繁项集".format(sum(len(itemsets) for itemsets in frequent_itemsets.values())))
    
    # 每个项集生成一个规则
    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))
    print("一共有{}个备选规则 ".format(len(candidate_rules)))
    
    # 用两个字典,存储规则应验(正例)和规则不适用(反例)的次数
    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[candid for candidate_rule in candidate_rules}
    rule_confidence = {candidate_rule: correct_counts[candidate_rule] / float(correct_counts[candidate_rule] + incorrect_counts[candidate_rule]) for candidate_rule in candidate_rules}                                                                                                          
    min_confidence = 0.9
    # 挑出置信度大于0.9的置信度
    rule_confidence = {rule: confidence for rule, confidence in rule_confidence.items() if confidence > min_confidence}
    #置信度字典排序
    from operator import itemgetter
    sorted_confidence = sorted(rule_confidence.items(), key=itemgetter(1), reverse=True)
    for index in range(5):
         print("规则 #{0}".format(index + 1))
         (premise, conclusion) = sorted_confidence[index][0]
         print("规则: 如果一个人喜欢{0},也会喜欢{1}".format(premise, conclusion))
         print(" - 置信")
    
    规则 #1
    规则: 如果一个人喜欢frozenset({98, 181}),也会喜欢50
     - 置信
    规则 #2
    规则: 如果一个人喜欢frozenset({172, 79}),也会喜欢174
     - 置信
    规则 #3
    规则: 如果一个人喜欢frozenset({258, 172}),也会喜欢174
     - 置信
    规则 #4
    规则: 如果一个人喜欢frozenset({1, 181, 7}),也会喜欢50
     - 置信
    规则 #5
    规则: 如果一个人喜欢frozenset({1, 172, 7}),也会喜欢174
     - 置信
    

    参考《Python数据挖掘入门与实践》第四章

    相关文章

      网友评论

        本文标题:Apriori算法预测电影代码与数据下载

        本文链接:https://www.haomeiwen.com/subject/qilrzctx.html