Apriori算法代码疑问:频繁项集是否存在重复计数问题?
问题解答
这段代码确实存在错误,会导致同一用户对同一个2项频繁项集重复计数,原因如下:
- 虽然
frozenset是无序集合,frozenset({A,B})和frozenset({B,A})会被视为同一个键,不会被拆分成两个不同项集,但代码逻辑会让同一用户的同一个2项集被多次统计:
比如某用户同时评论了电影A和B,当遍历1项集{A}时,会生成{A,B}并给计数加1;当遍历1项集{B}时,又会生成同一个{A,B}并再次加1。最终该用户对{A,B}的贡献被算成2次,但实际上支持度的定义是“包含该项目集的用户数量”,正确统计应该是1次。
修正思路
要解决这个问题,核心是确保每个用户的每个目标项集只被统计一次,有两种常见修正方式:
方式1:直接生成所有2项集(适合k=2的场景)
利用itertools.combinations直接生成用户评论列表中的所有2项组合,每个组合仅统计一次:
from collections import defaultdict from itertools import combinations def find_frequent_itemsets(favorable_reviews_by_users, min_support): counts = defaultdict(int) for user, reviews in favorable_reviews_by_users.items(): # 生成当前用户所有可能的2项集 for pair in combinations(reviews, 2): counts[frozenset(pair)] += 1 # 过滤出满足最小支持度的项集 return {itemset: freq for itemset, freq in counts.items() if freq >= min_support}
方式2:保留Apriori迭代扩展逻辑(适合通用k项集生成)
先收集当前用户所有符合条件的k-1项集,生成候选k项集后去重,再统一统计:
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(): # 筛选出当前用户评论中包含的所有k-1项集 user_valid_k1 = [itemset for itemset in k_1_itemsets if itemset.issubset(reviews)] # 生成候选k项集并去重 candidate_sets = set() for itemset in user_valid_k1: for other_movie in reviews - itemset: candidate_sets.add(itemset | frozenset((other_movie,))) # 每个候选集仅统计一次当前用户的贡献 for candidate in candidate_sets: counts[candidate] += 1 return {itemset: freq for itemset, freq in counts.items() if freq >= min_support}
内容的提问来源于stack exchange,提问作者rd z
相关产品推荐
相关产品推荐

