关联算法Apriori的java实现,数据库使用redis

该算法是为了实现对一些专业文章的词汇关联分析而实现的,并不是Apriori的最佳应用,确实对词频分析的一种实践。
package com.my.analysis;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import redis.clients.jedis.Jedis;

public class AprioriMyImpl {
	private double minsup = 0.3;// 最小支持度
	private double minconf = 0.99;// 最小置信度
	private int limitword = 100;// 参加统计的

	private ArrayList<Set<String>> aricleWL;//

	private ArrayList<Set<Set<String>>> candidateList;//候选项list
	private ArrayList<Set<Set<String>>> frequencyList;//频繁项list

	public Set<Set<String>> allSub = new HashSet<Set<String>>();//最大频繁项的所有子集

	private long filecount;//文件的总数量

	private int step = 1;//表示进行到第一步了

	private Jedis jedis = new Jedis("localhost", 6379);

	public AprioriMyImpl() {
		candidateList = new ArrayList<Set<Set<String>>>();
		frequencyList = new ArrayList<Set<Set<String>>>();
		aricleWL = new ArrayList<Set<String>>();

		filecount = jedis.llen(AnsjTxtFileParserForRedis.FILELIST);
		for(int i = 0;i < filecount;i++){
			aricleWL.add(jedis.smembers(AnsjTxtFileParserForRedis.FILEPREFIX+i));
		}

	}

	/**
	 * 初始化第一个候选项集合
	 */
//	public void item1_init(){
//		Set<Set<String>> candidate1 = new HashSet<Set<String>>();
//		Set<String> tset = jedis.zrevrange(AnsjTxtFileParserForRedis.TABLENAME, 0,limitword-1);
//		for(String s:tset){
//			HashSet<String> one = new HashSet<String>();
//			one.add(s);
//			candidate1.add(one);
//		}
//		candidateList.add(candidate1);
//		System.out.println("候选项集-"+(step)+":");
//		printSetSetString(candidate1);
//	}

	public void item1_init(){
		String[] keys ={"睡眠","时间","宝宝","治疗","疾病","身体","呼吸","质量","孩子","入睡","人体","精神","习惯","心理","障碍","枕头","保健","关注","医生","女性","症状","食物","饮食","运动","中医","床垫","儿童","婴儿","阅读","大脑","按摩","效果","癫痫","环境","营养","压力","血液","智能","休息","妈妈","男人","生理","医学","社会","药物","肌肉","男性","科技","恢复","减肥","放松","神经","危害","情绪","怀孕","午睡","分泌","下降","反馈","音乐","刺激","糖尿病","姿势","老人","熬夜","消化","记忆","消除","起床","客户","食品","感冒","高血压","招聘","老年人","孕妇","手表","解决","现象","超过","颈椎","全身","空调","侧卧","位置","体温","金笔","达到","打鼾","电视","能量","催眠","物质","状况","精力","作者","设备","价格","病人","保护","数据","经验","正文","适合","妇科","锻炼","新生儿","咳嗽","抑郁症","血管","抑制","幼儿","失眠症","心脏病","食疗","血压","肿瘤","诱发","重视","心血管","寿命","小便","免疫力","月经","评测","记忆力","智力"};
		Set<Set<String>> candidate1 = new HashSet<Set<String>>();
		for(String s:keys){
			HashSet<String> one = new HashSet<String>();
			one.add(s);
			candidate1.add(one);
		}
		candidateList.add(candidate1);
		System.out.println("候选项集-"+(step)+":");
		printSetSetString(candidate1);
	}
	/**
	 * 候选项集转化为频繁项集
	 */
	public boolean candidateToFrequency(){
		Set<Set<String>> candItems = candidateList.get(step-1);
		Set<Set<String>> freqItems = new HashSet<Set<String>>();
		for(Set<String> item:candItems){
			if((count_sup(item)/filecount)>=minsup){
				freqItems.add(item);
			}
		}
		if(freqItems.size()==0){//无法产生符合条件的频繁项集
			return false;
		}
		frequencyList.add(freqItems);
		System.out.println("频繁项集-"+(step)+":");
		printSetSetString(freqItems);//输出频繁项集
		step++;
		return true;
	}
	/**
	 * 频繁项集形成新的候选项集
	 */
	public boolean frequencyToCandidate(){
		Set<Set<String>> frequencyItems = frequencyList.get(step-2);
		Set<String> maxSub = maxSubSet(frequencyItems);
		Set<Set<String>> candidateItems = new HashSet<Set<String>>();
		for(Set<String> freqs : frequencyItems){
			int len = freqs.size();
			for(String sub:maxSub){
				Set<String> pItem = new HashSet<String>();
				pItem.addAll(freqs);
				pItem.add(sub);
				if(pItem.size()==(len+1)&&subIsFreq(frequencyItems,pItem)){
					candidateItems.add(pItem);
				}
			}
		}
		if(candidateItems.size()==0){//没有形成新的候选集
			return false;
		}
		candidateList.add(candidateItems);
		System.out.println("候选项集-"+(step)+":");
		printSetSetString(candidateItems);//输出频繁项集
		return true;
	}

	/**
	 * parentSet的子集在频繁集合freq中
	 * @param freq
	 * @param parentSet
	 * @return true 是 ; false 否
	 */
	public boolean subIsFreq(Set<Set<String>> freq,Set<String> parentSet){
		for(String s:parentSet){
			Set<String> item = new HashSet<String>();
			item.addAll(parentSet);
			item.remove(s);
			if(!freq.contains(item)){
				return false;
			}
		}
		return true;
	}
	/**
	 * 获得频繁项集的最大项集
	 * @param freqIntems
	 */
	public Set<String> maxSubSet(Set<Set<String>> freqIntems){
		Set<String> maxSub = new HashSet<String>();
		for(Set<String> ss:freqIntems){
			for(String s:ss){
				maxSub.add(s);
			}
		}
		return maxSub;
	}

	/**
	 * 计算支持度
	 * @param x
	 * @return
	 */
	public double count_sup(Set<String> x){
		int temp = 0;
		for(Set<String> ss:aricleWL){
			if(ss.containsAll(x)){
				temp++;
			}
		}
		return temp;
	}
	/**
	 * 计算集合x=>y的置信度
	 * @param x
	 * @param y
	 * @return
	 */
	public double cout_cand(Set<String> x,Set<String> y){
		Set<String> z = new HashSet<String>();
		z.addAll(x);
		z.addAll(y);
		return count_sup(z)/count_sup(x);
	}

	/**
	 * 获得所有的子集
	 * @param parent
	 */
	public void genSub(Set<String> parent){
		if(parent.size()>0){
			allSub.add(parent);
		}
		Set<String> ss = new HashSet<String>();
		ss.addAll(parent);
		for(String s:ss){
			Set<String> ss2 = new HashSet<String>();
			ss2.addAll(ss);
			ss2.remove(s);
			genSub(ss2);
		}
	}

	/**
	 * 输出
	 * @param sss
	 */
	public void printSetSetString(Set<Set<String>> sss){
		for(Set<String> ss:sss){
			System.out.println(ss);
		}
	}
	/**
	 * 关联度分析
	 * @param subSet
	 */
	public void releRuleCount(Set<Set<String>> subSet){
		for(Set<String> x:subSet){
			for(Set<String> y:subSet){
				Set<String> xy = new HashSet<String>();
				xy.addAll(x);
				xy.addAll(y);
				if(xy.size()==(x.size()+y.size())){
					double sup_count = cout_cand(x,y);
					if(sup_count>minconf){
						System.out.println(x+"==>>"+y+"=="+sup_count);
					}
				}
			}
		}
	}

	public void jisuan(){
		item1_init();//第一个候选项集的初始化
		while(true){
			if(!candidateToFrequency())
				break;
			if(!frequencyToCandidate())
				break;
		}
		Set<Set<String>> maxfreqs = frequencyList.get(frequencyList.size()-1);
		for(Set<String> maxfreq:maxfreqs){
			allSub = new HashSet<Set<String>>();
			genSub(maxfreq);
			releRuleCount(allSub);
		}
	}

	public static void main(String[] args) {
		//初始化候选项,取前几位word
		new AprioriMyImpl().jisuan();
	}

}

时间: 2024-10-18 10:13:37

关联算法Apriori的java实现,数据库使用redis的相关文章

Apriori 关联算法学习

1. 挖掘关联规则 1.1   什么是关联规则 一言蔽之,关联规则是形如X→Y的蕴涵式,表示通过X可以推导“得到”Y,其中X和Y分别称为关联规则的先导(antecedent或left-hand-side, LHS)和后继(consequent或right-hand-side, RHS) 1.2   如何量化关联规则 关联规则挖掘的一个典型例子便是购物车分析.通过关联规则挖掘能够发现顾客放入购物车中的不同商品之间的关联,分析顾客的消费习惯.这种关联规则的方向能够帮助卖家了解哪些商品被顾客频繁购买,

频繁模式挖掘apriori算法介绍及Java实现

频繁模式是频繁地出现在数据集中的模式(如项集.子序列或者子结构).例如,频繁地同时出现在交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B)=P(A并B) 置信度:confidence(A=>B)=P(B|A) 频繁k项集:如果项集I的支持度满足预定义的最小支持度阈值,则称I为频繁项集,包含k个项的项集称为k项集. 算法思想 Apriori算法是Agrawal和R. Srikant于1994年提出,为布尔关联规则挖掘频繁项集的原创性算法.通过名

机器学习算法-Apriori关联分析

引文: 学习一个算法,我们最关心的并不是算法本身,而是一个算法能够干什么,能应用到什么地方.很多的时候,我们都需要从大量数据中提取出有用的信息,从大规模数据中寻找物品间的隐含关系叫做关联分析(association analysis)或者关联规则学习(association rule learning).比如在平时的购物中,那些商品一起捆绑购买销量会比较好,又比如购物商城中的那些推荐信息,都是根据用户平时的搜索或者是购买情况来生成的.如果是蛮力搜索的话代价太高了,所以Apriori就出现了,就是

数据挖掘算法 Apriori 例子+源码

转自这里 Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法.其核心是基于 两阶段频集思想的递推算法.该关联规则在分类上属于单维.单层.布尔关联规 则.在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集. 由Agrawal等人提出的Apriori是经典的关联规则和频繁项集挖掘算法,围绕着它的改进和实现有大量的文献.该算法是挖掘产生布尔关联规则频繁项目集的经典算法,从其产生到现在对关联规则挖掘方面的研究有着很大的影响. 为了提高频繁项目的挖掘效率,Apriori算法利用了两

数据挖掘十大算法--Apriori算法

一.Apriori 算法概述 Apriori 算法是一种最有影响力的挖掘布尔关联规则的频繁项集的 算法,它是由Rakesh Agrawal 和RamakrishnanSkrikant 提出的.它使用一种称作逐层搜索的迭代方法,k- 项集用于探索(k+1)- 项集.首先,找出频繁 1- 项集的集合.该集合记作L1.L1 用于找频繁2- 项集的集合 L2,而L2 用于找L2,如此下去,直到不能找到 k- 项集.每找一个 Lk 需要一次数据库扫描.为提高频繁项集逐层产生的效率,一种称作Apriori

关联算法

一.概念   关联算法常用于购物篮分析:找到正向.强关联的商品集合,用来优化货架商品摆放和捆绑销售. 关联算法需要明确:频繁项集(A,B),A->B和B->A的关联方向(正.负)与关联程度(强.弱). 频繁项集:出现次数不小于设定阀值的商品集合 电商常用单品推荐单品,称为频繁2项集,形如(A,B). 关联算法重要定理:频繁项集的所有非空子集也都必须是频繁的. 比如(A,B,C)是频繁项集,那(A,B)肯定也是频繁项集.如果(A,B)不是频繁项集,那(A,B,C)肯定也不是频繁项集. 支持度(S

数据挖掘——关联算法

一.概念 关联(Association) 关联就是把两个或两个以上在意义上有密切联系的项组合在一起. 关联规则(AR,Assocaition Rules) 用于从大量数据中挖掘出有价值的数据项之间的相关关系.(购物篮分析) 协同过滤(CF,Collaborative Filtering) 协同过滤常常被用于分辨某位特定顾客可能感兴趣的东西,这些结论来自于对其他相似顾客对哪些产品感兴趣的分析.(推荐系统) 二.关联规则 1.相关数据指标 两个不相交的非空集合X.Y,如果X -> Y,就说X ->

Java开发数据库设计的14个技巧,你知道几个?

1. 原始单据与实体之间的关系 可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体.在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证对应多个实体,或多张原始单证对应一个实体.这里的实体可以理解为基本表.明确这种对应关系后,对我们设计录入界面大有好处.[例1]:一份员工履历资料,在人力资源信息系统中,就对应三个基本表:员工基本情况表.社会关系表.工作简历表.这就是"一张原始单证对应多个实体"的典型例子. 2. 主键与外键

基于Java图片数据库Neo4j 3.0.0发布 全新的内部架构

基于Java图片数据库Neo4j 3.0.0发布 全新的内部架构 Neo4j 3.0.0 正式发布,这是 Neo4j 3.0 系列的第一个版本.此版本对内部架构进行了全新的设计;提供给开发者更强大的生产力;提供更广阔的部署选择.Neo4j 3.0 被认为是世界上最具伸缩性的基于Java的图片数据库. Neo4j 3.0.0 主要的新特性: Neo4j 3.0 新特性架构图 全新设计了内部架构移除了所有节点数量限制,数据库关系和属性都可以被存储和索引提供官方支持语言驱动器 (Java.JavaSc