程序猿成长之路之数据挖掘篇——频繁项集挖掘介绍

news2024/11/17 14:46:37

频繁项集挖掘可以说是数据挖掘中的重点,下面我们来分析以下频繁项集挖掘的过程和目标

如果对数据挖掘没有概念的小伙伴可以查看上次的文章
https://blog.csdn.net/qq_31236027/article/details/137046475

什么是频繁项集?

在回答这个问题之前,我们可以看一个例子:
小明、小刚、小红三人去同一家商店购物,小明、小刚两人购买了鸡蛋,牛奶和面包,小红购买了鸡蛋和牛奶,这时候一位聪明的店员便推荐小红购买面包,并且说这个面包很适合购买了鸡蛋和牛奶的客户,小红心动了。
在这个例子中,我们可以看到小明、小刚和小红都有去购买商品的行为,而其中的每一个商品可以称为一个,小明、小刚、小红所购买的商品的集合就成为项集。那么什么是频繁项集呢?所谓的频繁项集理解起来也相对容易了,就是用户频繁购买的商品的集合,也就是说会被大部分用户购买的商品的集合。显而易见,在例子中鸡蛋、牛奶可以称为一个频繁项集。

频繁项集有啥用处?

再次回到之前的那个例子中,那个聪明的店员根据小明和小刚的购买记录进行商品的推荐,这个就利用到了频繁项集的一个优势:允许系统(店员)利用已有的频繁项集(顾客的购买记录) 针对某一客户进行商品推荐。那么为什么可以这么做呢?这么做的依据是什么呢?下面让我们来看一下频繁项集挖掘的过程。

频繁项集挖掘过程

先上个例子(基于Apriori):
已知
用户B收藏了物品A、B、C,
用户C收藏了物品A、D,
用户D收藏了物品A、B、C、D,
用户E收藏了物品A、B、E
用户A收藏了物品A、B,现在需要针对用户A进行物品推荐。

  1. 首先我们选取一个集合,就设置为{物品A}
  2. 我们不难发现购买了物品A的用户3/4都收藏了物品B,这时候我们可以设定一个阈值,只有频率(出现次数)超过这个值的项集才会被保留,这个值又称作最小支持度(min_support)。假设最小支持度为0.5, 也就是说物品D不会被推荐,因为只有一个用户在收藏了物品A后收藏了物品D(是用户C), 收藏D的后验概率为1/3 < 0.5。
  3. 于是集合扩容为{物品A,物品B}
  4. 之后而我们推出收藏了物品A、B后收藏物品C的概率为 1/2,也就是{用户B,用户D}/ {用户B,用户C,用户D、用户E},而用户收藏A、B、E的概率为1/4 < 0.5 因此不被保留
  5. 集合扩容为{物品A,物品B,物品C}
  6. 因为购买物品A,物品B,物品C后购买物品D的项集只出现1次,1/4 < min_support = 0.5 因此,该项集非频繁项集,因此最大频繁项集为{物品A,物品B,物品C}
  7. 之后针对用户A进行推荐,这时候需要逐层进行筛选,不难得出{物品A,物品B} => {物品A,物品B,物品C} 的概率为2/3,超过了我们设定的第二个阈值,称为最小置信度(也就是最小关联度),而{物品A,物品B} = > {物品A,物品B,物品E} 的概率为1/3 < 0.5 。不推荐。因此会向用户A推荐物品C,

Apriori算法

好了,朋友们,看到了现在这一步可以恭喜你已经初步了解频繁项集的挖掘过程了。
下面我们来看一下Apriori的算法:

package apriori;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * apriori算法
 * @author zygswo
 *
 */
public class Apriori {
	/**
	 * 最小支持度
	 */
	private static final double MIN_SUPPORT = 0.5;
	
	/**
	 * 最小置信度
	 */
	private static final double MIN_FAITH = 0.5;

	/**
	 * 算法核心
	 * @param trainDataSet 训练集
	 * @param usersCollection 用户喜好
	 * @return
	 */
	private static List<String>
			getResult(Map<String,String[]> trainDataSet,String[] usersCollection) {
		//1.训练集训练
		Map<String,Double> res = new ConcurrentHashMap<String,Double>();
		res = trainData(res,trainDataSet);
		System.out.println(res.toString());
		//2.推荐
		return recommend(res, usersCollection);
	}
	
	/**
	 * 推荐
	 * @param res
	 * @param usersCollection
	 * @return
	 */
	private static List<String> recommend(Map<String, Double> res, String[] usersCollection) {
		// TODO Auto-generated method stub
		String key = "";
		List<String> list = new ArrayList<>();
		for (String str: usersCollection) {
			key += str;
		}
		double countNb = res.get(key);
		for (String str: res.keySet()) {
			if (str.length() != key.length() + 1) {
				continue;
			}
			boolean contains = true;
			for (char ch : key.toCharArray()) {
				if (str.indexOf(ch) == -1) {
					contains = false;
					break;
				}
			}
			if (contains){
				if (res.get(str) /countNb * 1.0 >= MIN_FAITH) {
					System.out.println(key + " -->"  + str + " faith = " +  res.get(str) / countNb * 1.0);
					list.add(str.replace(key, ""));
				}	
			}
		}
		return list;
	}

	/**
	 * 训练训练集
	 * @param res
	 * @param trainDataSet
	 * @return
	 */
	private static Map<String, Double> trainData(
			Map<String, Double> res,
			Map<String, String[]> trainDataSet) {
		res.putAll(trainData(trainDataSet.size(),0, res, trainDataSet));
		return res;
	}

	/**
	 * 训练训练集
	 * @param initSize 初始数组长度
	 * @param roundNb 轮数
	 * @param res 结果map
	 * @param trainDataSet 训练数据集
	 * @return
	 */
	private static Map<String, Double> trainData(
			int initSize,
			int roundNb,
			Map<String,Double> res,
			Map<String,String[]> trainDataSet
	) {
		//统计
//		System.out.println("roundNb = " + roundNb);
		for (String[] itemArr : trainDataSet.values()) {
			//获取当前用户的收藏item集合,也就是获取项集
			String tempStr = "";
			for (String item:itemArr) {
				tempStr += item;
			}
			//针对项集统计频率
			if (roundNb == 0) {
				for (String item:itemArr) {
					if (res.get(item) == null) {
						res.put(item, 1.0);
					} else {
						res.put(item, res.get(item) + 1.0);
					}	
				}
			} else {
				for (String resStr : res.keySet()) {
					//如果字符串长度不为roundNb+1就说明不是当前的那层项集
					if (resStr.length() != roundNb + 1) {
						continue;
					}
					boolean contains = true;
					for (char ch : resStr.toCharArray()) {
						if (tempStr.indexOf(ch) == -1) {
							contains = false;
							break;
						}
					}
					if (contains){
						res.put(resStr, res.get(resStr) + 1.0);
					}
				}
			}
		}
		//筛选
		for (String str:res.keySet()) {
			if (res.get(str) < MIN_SUPPORT * initSize) {
				res.remove(str);
			}
		}
		//新增
		Map<String,Double> newRes = new ConcurrentHashMap<String, Double>();
		for (String str:res.keySet()) {
			if (str.length() != roundNb + 1) {
				continue;
			}
			for (String substr:res.keySet()) {
				//每次获取一位,之后叠加
				if (substr.length() != 1) {
					continue;
				}
				String lastChar = str.charAt(str.length() - 1) + "";
				//判断大小,只允许字符串递增排列,如AC,AB,AD,CD
				if(substr.compareTo(lastChar) > 0) {
					newRes.put(str+substr, 0.0);
				}
			}
		}
		if (newRes.isEmpty()) {
			return res;
		} else {
			res.putAll(newRes);
			return trainData(initSize,roundNb+1,res,trainDataSet);
		}
	}

	public static void main(String[] args) {
		Map<String,String[]> trainDataSet = new ConcurrentHashMap<>();
		trainDataSet.put("userB", new String[]{"A","B","C"});
		trainDataSet.put("userC", new String[]{"A","D"});
		trainDataSet.put("userD", new String[]{"A","B","C","D"});
		trainDataSet.put("userE", new String[]{"A","B","E"});
		trainDataSet.put("userF", new String[]{"A","B","C","E"});
		System.out.println("推荐结果为" + getResult(trainDataSet,new String[]{"A","B"}));
	}
}


运行截图
在这里插入图片描述

—————————————未完待续,代码解析之后再讲—————————————————————

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

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

相关文章

蓝桥杯第101题 拉马车 C++ Java Python

目录 题目 思路和解题方法 复杂度: c 代码 Java 版本&#xff08;仅供参考&#xff09; Python 版本&#xff08;仅供参考&#xff09; 代码细节 C 版本: Java 版本: Python 版本: 题目 思路和解题方法 这个游戏是一个简单的纸牌游戏&#xff0c;两个玩家轮流出牌&am…

Springboot相关知识-图片描述(学习笔记)

学习java过程中的一些笔记&#xff0c;觉得比较重要就顺手记录下来了~ 目录 一、前后端请求1.前后端交互2.简单传参3.数组集合传参4.日期参数5.Json参数6.路径参数7.响应数据8.解析xml文件9.统一返回类10.三层架构11.分层解耦12.Bean的声明13.组件扫描14.自动注入 一、前后端请…

(免费分享)基于springboot,vue问卷调查系统

用户注册、用户登录、创建调查问卷、编辑问卷问题和选型&#xff08;支持题型&#xff1a;单选、多选、单行文本、多行文本、数字、评分、日期、文本描述&#xff09;、保存和发布问卷、停止问卷调查、游客填写调查问卷&#xff08;一个IP地址只能填写一次&#xff09; 技术&a…

4.3 IO day5

1&#xff1a;实现文件夹的拷贝功能 注意判断被拷贝的文件夹是否存在&#xff0c;如果不存在则提前创建&#xff0c;创建文件夹的函数为 mkdir 不考虑递归拷贝的问题 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h…

蓝桥杯刷题-09-三国游戏-贪心⭐⭐⭐

蓝桥杯2023年第十四届省赛真题-三国游戏 小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件&#xff0c;每个事件之间相互独立且最多只会发生一次&#xff0c;当第 i 个事件发生时会分别让 X, Y,…

清明作业 c++

1.封装一个类&#xff0c;实现对一个数求累和阶乘质数 #include <iostream>using namespace std; int mproduct(int a){if(a>1){return a*mproduct((a-1));}else{return 1;} } class number{int a; public:number():a(5){};number(int a):a(a){}void set(int a){thi…

开源的页面生成器:拖拽即可生成小程序、H5页面和网站

星搭精卫 MtBird 是一款低代码可视化页面生成器&#xff0c;可以帮助用户以可视化的形式搭建网页、小程序和表单等应用。 使用这个生成器&#xff0c;不需要代码就可以生成小程序、H5页面和网站&#xff0c;拖拽操作、样式配置快速生成页面应用&#xff0c;数据可视化接入&…

2024年【道路运输企业安全生产管理人员】找解析及道路运输企业安全生产管理人员作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 道路运输企业安全生产管理人员找解析参考答案及道路运输企业安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及道路运输企业安全生产管理人员操作证已考过的学员汇总&#xff0c;相对有效帮助道路运输…

C++高频面试知识总结 part3

哈希 1.哈希表为什么快&#xff1f;2.哈希冲突解决方法3.哈希表扩容流程4.哈希表扩容太多次&#xff0c;需要遍历所有元素&#xff0c;如何优化&#xff1f;5.渐进式扩容为何可以正确访问哈希表&#xff1f; 1.哈希表为什么快&#xff1f; 哈希表&#xff08;Hash table&#…

告别旧IP,更换网络ip地址教程分享

在数字化世界中&#xff0c;IP地址作为每个网络设备的标识符&#xff0c;扮演着至关重要的角色。它不仅是设备在网络中的“门牌号”&#xff0c;还影响着网络连接的稳定性、安全性和数据传输效率。因此&#xff0c;在某些情况下&#xff0c;更换网络IP地址成为必要操作。虎观代…

平台规则的改变会影响低价治理结果吗

许多品牌在做低价链接投诉时&#xff0c;会用一套自己的标准去做&#xff0c;但如果无视平台规则&#xff0c;会出现非常多不好的结果&#xff0c;比如帐号投诉成功率被拉低&#xff0c;会直接影响后续链接的投诉时效和成功率&#xff0c;同时因为不尊重平台规则&#xff0c;而…

美国洛杉矶大带宽服务器带宽堵塞解决方法

随着互联网的快速发展&#xff0c;大带宽服务器成为了现代企业和个人进行数据传输、存储和处理的关键设施。然而&#xff0c;在美国洛杉矶等大城市&#xff0c;由于网络流量的激增、不合理的网络配置以及网络攻击等多种原因&#xff0c;大带宽服务器带宽堵塞问题日益凸显。本文…

【力扣】94. 二叉树的中序遍历、144. 二叉树的前序遍历、145. 二叉树的后序遍历

先序遍历&#xff1a;根-左-右中序遍历&#xff1a;左-根-右后序遍历&#xff1a;左-右-根 94. 二叉树的中序遍历 题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3…

基于springboot+vue+Mysql的教学视频点播系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

洛谷 1126.机器人搬重物

思路&#xff1a;BFS 这道BFS可谓是细节爆炸&#xff0c;对于编程能力和判断条件的能力的考察非常之大。 对于这道题&#xff0c;我们还需要额外考虑一些因素&#xff0c;那就是对于障碍物的考虑和机器人方位的考虑。 首先我们看第一个问题&#xff0c;就是对于障碍物的考虑…

Qt Creator 界面

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、认识 Qt Creator 界面 1、总览 2、左边栏 3、代码编辑区 4、UI设计界面 5、构建区 一、认识 …

GitHub入门与实践

ISBN: 978-7-115-39409-5 作者&#xff1a;【日】大塚弘记 译者&#xff1a;支鹏浩、刘斌 页数&#xff1a;255页 阅读时间&#xff1a;2023-08-05 推荐指数&#xff1a;★★★★★ 好久之前读完的了&#xff0c;一直没有写笔记。 这本入门Git的书籍还是非常推荐的&#xff0c;…

【蓝桥杯】蓝桥杯算法复习(四)

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

深入浅出 -- 系统架构之Keepalived搭建双机热备

Keepalived重启脚本双机热备搭建 ①首先创建一个对应的目录并下载keepalived安装包&#xff08;提取码:s6aq&#xff09;到Linux中并解压&#xff1a; [rootlocalhost]# mkdir /soft/keepalived && cd /soft/keepalived [rootlocalhost]# wget https://www.keepalived.…

ROS2 采集虚拟仿真环境图像并发布

简介&#xff1a;ROS2功能的学习我们还是在基于OpenAI的gym虚拟仿真环境中来完成&#xff0c;gym虚拟仿真环境安装请参考另一篇教程&#xff0c;这里不再重复说明&#xff0c;接下来我们开始创建一个ROS2的功能节点&#xff0c;并发布虚拟仿真环境小车摄像头的图像&#xff0c;…