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

2024-04-07 11:52

本文主要是介绍程序猿成长之路之数据挖掘篇——频繁项集挖掘介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

如果对数据挖掘没有概念的小伙伴可以查看上次的文章
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 stubString 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,CDif(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.chinasem.cn/article/882535

相关文章

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Python运行中频繁出现Restart提示的解决办法

《Python运行中频繁出现Restart提示的解决办法》在编程的世界里,遇到各种奇怪的问题是家常便饭,但是,当你的Python程序在运行过程中频繁出现“Restart”提示时,这可能不仅仅是令人头疼... 目录问题描述代码示例无限循环递归调用内存泄漏解决方案1. 检查代码逻辑无限循环递归调用内存泄漏2.

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(