推荐算法——Apriori算法原理

news2024/11/25 10:27:12

0、前言:

  • 首先名字别读错:an pu ruo ao rui 【拼音发音】
  • Apriori是一种推荐算法
  • 推荐系统:从海量数据中,帮助用户进行信息的过滤和选择。主要推荐方法有:基于内容的推荐、协同过滤推荐、基于关联规则的推荐、基于知识的推荐、混合推荐。
  • 关联分析:是一种在大规模数据集中寻找有趣关系的非监督学习算法,是利用一些有趣性的量度来识别数据库中发现的强规则。

1、基础概念

  • 频繁项集:经常【需要量化】出现在一块的物品的集合
  • 关联规则:暗示两种物品之间可能存在很强的关系
  • 事务:将数据看成一条条交易记录的集合,事务就是一条交易
  • 项:交易的每一个物品称为一个项
  • 项集:包含零个或者多个项的集合
  • k-项集:包含k个项的项集
  • 前件和后件:一个规则中先买了尿布后买了啤酒,尿布就是啤酒的前件、啤酒就是尿布的后件
  • 常用频繁项集的评估标准有:支持度、置信度、提升度;
    • 支持度就是几个关联的数据在数据集中出现次数占总数据集的比重。(举例:超市一天卖了5单,其中有2单同时出现了尿布和啤酒,那么{尿布、啤酒}的支持度就是2/5=0.4),支持度常用来删除一些没意义的规则。
    • 置信度就是一个数据出现后,另一个数据出现的概率。(举例:买了尿布后会买啤酒的概率=两者同时出现的概率(两者的支持度)/尿布出现的概率(尿布的支持度))
    • 提升度:如果A事件的支持度本来就很高,然后求B事件发生后A事件的置信度,发现也很高,但并没有A事件本身的支持度高,就有可能误以为B事件的发生导致A事件发生的可能性增加了。所以加入了提升度的概念(举例:求A事件发生对B事件的提升度=AB同时发生的支持度/B事件发生的持度度),提升度大于1,表明A对B是有效的强关联规则,小于1表明A对B是无效的强关联规则。等于1,说明没有提升。
  • ★发现频繁项集和关联规则:如果一一遍历去找关联规则和频繁项集,计算量非常大,所以要进行筛选。
    • 1、首先设定最小支持度,最小置信度,找到满足最小支持度的所有项集,这些项集叫做频繁项集。
    • 2、从频繁项集中提取所有高置信度的规则,这些规则就是强关联规则。
    • 注意:如果一个项集是频繁的,那么它的所有子集也是频繁的。
    • 注意:如果一个项集是非频繁的,那么所有包含它的集合也是非频繁的。【通过这条规则减少计算量】

2、算法实现过程

  • Apriori算法原理:所有非频繁项集不用计算,减少计算量。获取apriori频繁项集是第一步,要通过apriori最终获取强关联规则,就要在频繁项集支持度的基础上,计算每种规则的支持度。
    在这里插入图片描述
  • 原始候选集构建1-项集:
# 数据集
dataset = [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
# 让候选集每一项变成不可变集合,进而获取1-项集
def creat_c1(data_set):
    c1 = []
    for data in data_set:
        for i in data:
            if i not in c1:
                c1.append(i)
    c1.sort()
    return list(map(frozenset,[{i} for i in c1])) # frozenset是将集合变成不可变集合,目的是最后让frozenset作为字典的key
c1 = creat_c1(dataset)
'''
[frozenset({1}),
 frozenset({2}),
 frozenset({3}),
 frozenset({4}),
 frozenset({5})]
'''
  • 由1-项集(C1)转为1-项频繁集(L1)推出k-项集转k-项频繁集的函数:通过支持度筛选频繁集;scanD()函数:获取所有k-项集的支持度和k-项集对应的k-项频繁集
# C1(1项集):L1(1项频繁项集)
# D:数据集
# Ck:k项集
# min_support:最小支持度
def scanD(D,Ck,min_support=0.1):
    support_dic = {}
    # 遍历原始交易记录
    for d in D:
        for c in Ck:
            # 判断是否是子集,是的话数量加1
            if c.issubset(d):
                support_dic[c] = support_dic.get(c,0) + 1 # 防止刚开始support_dic是空
    support_data = {} # 所有项集的支持度
    LK = [] # 频繁项集
    # 计算支持度
    for k,v in support_dic.items():
        support = v/len(D)
        support_data[k] = support
#     print(support_data) # 打印支持度
        # 获得频繁项集
        if support >= min_support:
            LK.append(k)
    # 返回频繁项集、所有项集支持度:
    return LK, support_data
  • 由1-项频繁集产生2-项集的方法推出:k-项频繁集产生k+1-项集的方法;apriori_gen()函数:获取所有k-项频繁集(Lk)对应的k+1-项集(Ck+1),如下图以2-项集生成方法说明:
    在这里插入图片描述
# L1(1频繁项集) => C2(2项集)
def apriori_gen(LK):
    Ck = []
    for i in range(len(LK)-1):
        for j in range(i+1,len(LK)):
            f_set = LK[i] | LK[j]
            # print(f_set)
            # 不能重复,新项集只能是k+1项
            if f_set not in Ck and len(f_set) == len(LK[0])+1:
                Ck.append(f_set)
    # print(Ck)
    return Ck   
  • 获取频繁项集和频繁项集生成过程中产生的项集的支持度
import time
def apriori(D, min_support=0.1):
    c1 = creat_c1(D)
    L1,support1 = scanD(D,c1,min_support)
    
    # 所有频繁项集
    L_f = []
    # 所有项集支持度就直接添加到support1中
    
    # 循环
    while True:
        L_f.append(L1)
        # 项集
        C = apriori_gen(L1)
        # 项集——频繁项集
        L,support = scanD(D,C,min_support)
        L1 = L
        support1.update(support)
        if len(L1)==0:
            break
    return L_f,support1
  • 获取k项集满足最小置信度的强关联规则的集合
    计算置信度:confidence(X -> Y) = P(Y|X) = P(XY) / P(X)【在x发生的条件下Y发生的置信度】
    calculate_conf()函数:计算某个频繁项集对应的满足最小置信度的强关联规则的集合。
# 计算一个项集的所有强关联规则
# 计算置信度
# freqSet: 频繁项集
# H=[frozenset({i}) for i in freqSet]
# L, support_Data = apriori(dataset, min_support=n)
# brl = [ ]   # 保存强关联规则的列表
def calculate_conf(freqSet, H, supportData, brl, minConf=0.5):
    newH = [ ]
    
    # 遍历H
    for s in H:
        # 置信度
        conf = supportData[freqSet] / supportData[freqSet - s]
        # conf(3,5->1) = P(1, 3, 5) / P(3,5)  
        # display(f'--- {freqSet - s} -> {s} = {conf} ---')
        
        # 大于最小置信度的规则是强规则
        if conf >= minConf:
            # 保存强关联规则到brl中
            brl.append( (freqSet - s, "->" , s, ' = ', conf) )  
            newH.append(s)
    
    return newH

用一个2-项集测试下函数calculate_conf,发现对于2-项集,函数能够获取所有满足置信度要求的关联规则。

freqSet = frozenset({1, 3})
H = [frozenset({i}) for i in freqSet]
L, support_data = apriori(dataset, min_support=0.2)
brl = [ ]   # 保存强关联规则的列表
# display(freqSet, H)

# 计算单个项集的置信度
calculate_conf(freqSet, H, support_data, brl, minConf=0.1)
brl
'''
[(frozenset({3}), '->', frozenset({1}), ' = ', 0.6666666666666666),
 (frozenset({1}), '->', frozenset({3}), ' = ', 1.0)]
'''
# 3-项集
freqSet = frozenset({1, 3, 5})
H = [frozenset({i}) for i in freqSet]
L, support_data = apriori(dataset, min_support=0.2)
brl = [ ]   # 保存强关联规则的列表
# display(freqSet, H)

# 计算单个项集的置信度
calculate_conf(freqSet, H, support_data, brl, minConf=0.1)
brl
'''
[(frozenset({3, 5}), '->', frozenset({1}), ' = ', 0.5),
 (frozenset({1, 5}), '->', frozenset({3}), ' = ', 1.0),
 (frozenset({1, 3}), '->', frozenset({5}), ' = ', 0.5)]
'''

可以发现:在3项集中出现了问题,3项集中只有2-项集作为前件的情况,没有1-项集作为前件的情况,出现了统计不完全的情况。因此为了让统计结果齐全,需要重新写个函数完善calculate_conf()函数。

# 考虑2-项集,3-项集,4-项集...
def rules_from_freq(freqSet, H, supportData, brl, minConf=0.7):
    tmp = True
    while tmp:
        tmp = False
        
        # 计算置信度
        newH = calculate_conf(freqSet, H, supportData, brl, minConf=minConf)
        # display(f'newH: {newH}')
        
        H = apriori_gen(newH)
        # display(f'H: {H}')
        # print('*' * 100)
        
        tmp =  not  (H==[ ] or len(H[0]) == len(freqSet))
        

测试:通过测试结果可以看出,完善之后的函数就能够获得所有满足要求置信度的关联规则

# 3-项集
freqSet = frozenset({1, 3, 5})
H = [frozenset({i}) for i in freqSet]
L, support_data = apriori(dataset, min_support=0.2)
brl = [ ]   # 保存强关联规则的列表
# display(freqSet, H)

# 计算单个项集的置信度
rules_from_freq(freqSet, H, support_data, brl, minConf=0.1)
brl
'''
[(frozenset({3, 5}), '->', frozenset({1}), ' = ', 0.5),
 (frozenset({1, 5}), '->', frozenset({3}), ' = ', 1.0),
 (frozenset({1, 3}), '->', frozenset({5}), ' = ', 0.5),
 (frozenset({5}), '->', frozenset({1, 3}), ' = ', 0.3333333333333333),
 (frozenset({3}), '->', frozenset({1, 5}), ' = ', 0.3333333333333333),
 (frozenset({1}), '->', frozenset({3, 5}), ' = ', 0.5)]
'''
  • 获取强关联规则的置信度:获取给定项集L中满足置信度要求的强关联规则
def gen_rules(L, support_data, min_conf=0.5):
    big_rule_list = [ ]
    
    for i in range(1, len(L)):  # 遍历所有行,第一行除外
        for freqSet in L[i]:  # 遍历每一行的所有元素
            # display(freqSet)
            H = [frozenset({i}) for i in freqSet]
            # 求每个项集的强关联规则,会保存在big_rule_list中
            rules_from_freq(freqSet, H, support_data, big_rule_list, minConf=min_conf)
    
    return big_rule_list

3、apriori算法总结:通过总结疏通下apriori算法中求频繁项集和求强关联规则的函数构造方法

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1053760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

八大排序源码(含优化)

文章目录 1、直接插入排序2、希尔排序3、选择排序4、冒泡排序5、堆排序6、快速排序快速排序递归实现霍尔法挖坑法前后指针法快速排序小区间优化 快速排序非递归实现 7、归并排序归并排序递归实现归并排序非递归 8、计数排序 大家好,我是纪宁,这篇文章是关…

36.骑士周游算法及其基于贪心算法的优化

概述 骑士周游算法,叫做“马踏棋盘算法”或许更加直观。在国际象棋8x8的棋盘中,马也是走“日字”进行移动,相应的产生了一个问题:“如果要求马 在每个方格只能进入一次,走遍全部的64个方格需要如何行进?”…

【STM32基础 CubeMX】按键的检测

文章目录 前言一、按键原理图分析二、cubeMX配置key GPIO三、代码分析3.1 cubemx生成的代码3.2 1个库函数 四、按键点灯示例代码总结 前言 在嵌入式系统开发中,按键检测是一个基础而重要的任务,特别是在使用STM32系列微控制器的项目中。按键通常被用于与…

C++ - 开放地址法的哈希介绍 - 哈希表的仿函数例子

前言 哈希其实是一种搜索方式,像暴力查找,有序数组的二分查找,二分查找就很快了,可以达到O(log n)。但是有序数组有一个 弊端,就是要先进行排序,这就有消耗,这还好,当要插入删除修改…

Go-Python-Java-C-LeetCode高分解法-第八周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏,每日一题,和博主一起进步 LeetCode专栏 本文部分内容来自网上搜集与个人实践。如果任何信息存在错误,欢迎…

UE5.1编辑器拓展【一、脚本化资产行为,通知,弹窗,高效复制多个同样的资产】

目录​​​​​​​ 插件制作 添加新的类:AssetActionUtility 添加新的模块:EditorScriptingUtilities 路径了解 添加debug的头文件 代码【debug.h】内涵注释: 写函数 .h文件 .cpp文件 插件制作 首先第一步是做一个插件&#xff1a…

Flink中序列化RoaringBitmap不同方式的对比

背景 在flink中,我们有时候会使用到RoaringBitmap进行统计计数等操作,而当使用RoaringBitmap时,这就涉及到了最重要的问题,如何序列化?序列化的目的是为了进行网络通信或者状态序列化的目的,本文的重点是比…

根据GWAS数据估算样本量N和使用千人基因组填充maf的参考文献

https://github.com/GenomicSEM/GenomicSEM/wiki/2.1-Calculating-Sum-of-Effective-Sample-Size-and-Preparing-GWAS-Summary-Statistics

【LeetCode热题100】--104.二叉树的最大深度

104.二叉树的最大深度 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) …

尚硅谷谷粒商城部分报错问题处理

1、启动报错: 内容: org.springframework.beans.factory.BeanCreationException: Error creating bean with name attrAttrgroupRelationController: Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed t…

使用prometheus监控java服务

在prometheus官方下载页面没有看到jvm_exproter的下载地址但是官方页面是有推荐下载地址的 访问 Prometheus - Monitoring system & time series database prometheus官方网址 官方推荐地址下载是在github网络访问不方便的可以用下面的网址 wget https://repo1.maven…

【小程序 - 基础】页面导航、页面事件、生命周期、WXS脚本_04

目录 一、页面导航 1. 什么是页面导航 2. 小程序中实现页面导航的两种方式 2.1 声明式导航 2.1.1 导航到 tabBar 页面 2.1.2 导航到非 tabBar 页面 2.1.3 后退导航 2.2 编程式导航 2.2.1 导航到 tabBar 页面 2.2.2 导航到非 tabBar 页面 2.2.3 后退导航 2.3. 导航…

Proxyer实现内网穿透云服务器

Proxyer Proxyer是一个网络代理工具,它可以将本地计算机的网络流量(如HTTP、HTTPS、TCP等)转发到远程服务器。使用Proxyer可以在本地计算机上建立一个代理服务器,通过代理服务器来访问互联网上的资源。 yum仓库设置 rm -f /etc…

在Ubuntu上通过Portainer部署微服务项目

这篇文章主要记录自己在ubuntu上部署自己的微服务应用的过程,文章中使用了docker、docker-compose和portainer,在部署过程中遇到了不少问题,因为博主也是初学docker-compose,通过这次部署实战确实有所收获,在这篇文章一…

LeetCode【121. 买卖股票的最佳时机】

你才不是什么小人物,你在我这里,是所有的天气和心情。 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一…

idea Springboot 校园助学贷款系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 校园助学贷款系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统 具有完整的源代码和数据库&…

小谈设计模式(8)—代理模式

小谈设计模式(8)—代理模式 专栏介绍专栏地址专栏介绍 代理模式代理模式角色分析抽象主题(Subject)真实主题(Real Subject)代理(Proxy) 应用场景远程代理虚拟代理安全代理智能引用代…

ubuntu22.04 x11窗口环境手势控制

ubuntu22.04 x11窗口环境手势控制 ubuntu x11窗口环境的手势控制并不优秀,我们可以使用touchegg去代替 这个配置过程非常简单,并且可以很容易在一定范围内达到你想到的效果,类比mac的手势控制 关于安装 首先添加源,并安装 sud…

数据结构-----二叉排序树

目录 前言 1.什么是二叉排序树 2.如何构建二叉排序树 3.二叉排序树的操作 3.1定义节点储存方式 3.2插入节点操作 3.2创建二叉排序树 3.4遍历输出(中序遍历) 3.5数据查找操作 3.6获取最大值和最小值 3.7删除节点操作 3.8销毁二叉排序树 4.完…

漏斗分析模型

从业务流程起点开始到最后日标完成的每个环节都会有用户流失,因此需要一种分析方法来衡量业务流程每一步的转化效率,漏斗分析方法就是这样的分析方法。 例如,在淘宝上一款商品的浏览量是 300、点击量是 100、订单量是 20、支付量是 10&#…