牛客题解 | 关联规则发现(Apriori算法)

题目## 题目

题目链接

Apriori算法是关联规则挖掘中的一种经典算法,用于发现数据集中频繁项集和关联规则。

频繁项集:在数据集中频繁出现的项集。
关联规则:在数据集中,若A则B的规则形式。
支持度:项集A在数据集中出现的次数除以数据集的总数。通俗点说,就是项集A在数据集中出现的概率。
置信度:项集A和项集B同时出现的次数除以项集A出现的次数。通俗点说,就是项集A出现时,项集B出现的概率。

频繁项集的生成:

  1. 扫描数据集,生成1-频繁项集。
  2. 对当前频繁项集,生成候选频繁项集,并计算其支持度。
  3. 根据支持度阈值,筛选出频繁项集,并更新当前频繁项集。
  4. 重复2-3,直到无法生成新的频繁项集。

关联规则的生成:

  1. 对一个频繁项集,枚举其所有非空子集作为规则前件,剩余部分作为规则后件。
  2. 对每个规则,计算其置信度。
  3. 根据置信度阈值,筛选出关联规则。
  4. 重复2-3,直到无法生成新的关联规则。

在本题中,频繁项集的生成和关联规则的生成是分开的,需要先生成频繁项集,再生成关联规则。

此外,在频繁项集的生成和关联规则的生成中,本题预先给出使用位运算来枚举子集的代码,但实际运用上,有其他高效的方法。这里不做赘述。

代码实现

def apriori(transactions, min_sup, min_conf):
    itemCount = defaultdict(int)
    
    # 计算每个单项的支持度
    for transaction in transactions:
        for item in transaction:
            itemCount[item] += 1
            
    # 筛选频繁1项集
    frequent_itemsets = {frozenset([item]) for item in itemCount if itemCount[item] / len(transactions) >= min_sup}
    
    k = 2
    all_frequent_itemsets = frequent_itemsets.copy()  # 存储所有频繁项集
    
    while frequent_itemsets:
        itemset_count = defaultdict(int)
        
        # 生成候选k项集
        candidate_itemsets = [frozenset(x) for x in combinations(list(set().union(*frequent_itemsets)), k)]
        
        # 计算候选项集的支持度
        for transaction in transactions:
            for candidate in candidate_itemsets:
                if candidate.issubset(transaction):
                    itemset_count[candidate] += 1
        
        # 筛选频繁k项集
        frequent_itemsets = {itemset for itemset, count in itemset_count.items() if count / len(transactions) >= min_sup}
        
        # 更新所有频繁项集
        all_frequent_itemsets.update(frequent_itemsets)
        
        k += 1
    
    # 生成关联规则
    rules = []
    # 遍历所有频繁项集
    for itemset in all_frequent_itemsets:
        itemlist = list(itemset)
        # 遍历频繁项集的子集大小
        for i in range(1, len(itemlist)):
            # 枚举子集作为规则前件
            for subset in combinations(itemlist, i):
                antecedent = subset
                consequent = itemset - antecedent
                conf = confidence(antecedent, consequent, transactions)
                if conf >= min_conf:
                    rules.append((antecedent, consequent, conf))
    
    return rules

题目链接

行阶梯形矩阵是一种特殊的矩阵,其特点是每一行的非零元素都出现在前一行的非零元素的右侧。

而像则是指矩阵的列空间,即矩阵的列向量所张成的空间。本题则是要求出矩阵的列空间。

标准代码如下

def rref(A):
    # Convert to float for division operations
    A = A.astype(np.float32)
    n, m = A.shape
    for i in range(n):
        if A[i, i] == 0:
            nonzero_current_row = np.nonzero(A[i:, i])[0] + i
            if len(nonzero_current_row) == 0:
                continue
            A[[i, nonzero_current_row[0]]] = A[[nonzero_current_row[0], i]]
        A[i] = A[i] / A[i, i]
        for j in range(n):
            if i != j:
                A[j] -= A[i] * A[j, i]
    return A

def find_pivot_columns(A):
    n, m = A.shape
    pivot_columns = []
    for i in range(n):
        nonzero = np.nonzero(A[i, :])[0]
        if len(nonzero) != 0:
            pivot_columns.append(nonzero[0])
    return pivot_columns

def matrix_image(A):
    # Find the RREF of the matrix
    Arref = rref(A)
    # Find the pivot columns
    pivot_columns = find_pivot_columns(Arref)
    # Extract the pivot columns from the original matrix
    image_basis = A[:, pivot_columns]
    return image_basis

在本题中,使用了比较直接的求解行阶梯形矩阵的方法,然后求出矩阵的列空间。其实可以使用numpy库或scipy库中的线性代数模块来简化代码编写。不过返回的值不符合题目要求,因此具体实现交由读者自行探索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值