1,简介

自己研究的一个小软件,已经申请专利,这里分享出我的思路以及代码作为纪念,也希望能帮到大家,可以根据已经购买的东西利用算法推荐出可能还会购买哪些,类似于淘宝的推荐系统啊之类的巴拉巴拉,不过是简易版,改一改就可以推荐电影啊,音乐啊都行,需要大量的数据集作为基础,废话不多说 ,上代码

1需求分析

1.1开发背景

关联规则挖掘是数据挖掘中最活跃的研究方法之一 。最早是由 Agrawal 等人提出的1993最初提出的动机是针对购物篮分析问题提出的,其目的是为了发现交易数据库中不同商品之间的联系规则。这些规则刻画了顾客购买行为模式,可以用来指导商家科学地安排进货,库存以及货架设计等。之后诸多的研究人员对关联规则的挖掘问题进行了大量的研究。他们的工作涉及到关联规则的挖掘理论的探索,原有的算法的改进和新算法的设计,并行关联规则挖掘Parallel Association Rule Mining,以及数量关联规则挖掘Quantitive Association Rule Mining 等问题。
Apriori算法是种挖掘关联规则的频繁项集算法,一种最有影响的挖掘布尔关联规则频繁项集的算法。其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集。其核心是基于两阶段频集思想的递推算法。该关联规则在分类上属于单维、单层、布尔关联规则。在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集。Apriori算法已经被广泛的应用到商业、网络安全等各个领域。Apriori算法采用了逐层搜索的迭代的方法,算法简单明了,没有复杂的理论推导,也易于实现。

1.2开发目的

1、找到集合中的频繁元素,发现顾客购买的规律。
2、对海量数据进行关联分析,分析出其潜在的规则,之后对在在超市购买的顾客,基于其已经购买的产品,分析出顾客大概率还想要什么产品并给出推荐。提高购买效率。

1.3开发环境

•操作系统:Windows 10
•开发语言:java

2系统总体设计

2.1系统总体框架

该系统主要分为如下四个模块:
(1) 数据的获取与建立数据类型
数据首先通过java BufferedReader类进行读入,在读入数据之后,对相应的数据进行包装加工成设定的Token序列,本软件读取的文件未.csv格式数据集,本系统用例为bread basket.csv,此数据集来自www.kaggle.com网站。
本系统主要使用第一列的购买的人的编号和购买的物品名称,此数据集大小为20587,数据没有达到十万或者百万乃至千万级别,所以在最终使用Apriori迭代出的最大的频繁项集在支持度和置信度没有设置特别小的情况下,一般不会大于5。
在读入这样的数据集之后,首先利用String的split方法,对数据的每一行按照以“,”为间隔进行分割,分割之后选择第一和第二列作为基础,建立一张以所有顾客的购买记录的List表,List里面存储的是Token类。
在建立这样一张数据表的过程中,使用的是ListPerson方法中的creat方法,creat方法将依次读取原始数据集中的每一行,如果表为空,那么选取相同的顾客编号添加到相应的位置即可,如果表不为空,那么首先会与之前的数据进行顾客编号上的比对,保证没有问题的情况下会进行添加。同时,如果在读取数据的过程中出现问题,那么将由catch抛出相应的异常。
最终得到ListPerson集合传回供下一步使用。
(2) 逐层迭代搜索
本模块是此系统的核心之一,主要就是利用Apriori方法进行相应计算与分析,得到数据集中潜在的关联规则
首先,利用(1)中传回的顾客表,建立一层数据,顾客表将首先被传到ListOne类中,此类的主要功能是建立一个List类型的链表,其中,链表的每一项的Token的List中只有一个数据,这一个数据代表一个商品,在对ListPerson链表进行迭代的过程中,逐步完善所有商品的项,在读取ListPerson的每一项时,都会与之前已经存在的项进行比对。
如果曾经出现过,那么将会把之前已经记录的这一项的Count数据加1,证明这一项又被计数了一次,如果在循环比对之前的数据的过程中,发现并没有这一项数据,那么将会新建立一行数据,并继续进行下去,直到数据完全被循环一遍,在这一链表建立完成之后,将会由Count类中的count函数进行分析。
Count的主要功能有计数,这一部分是可复用性代码,在传入之后,首先将会计数传入的数据的Token的str有多大,并生成相应大小的布尔判断函数,在进行计数的过程中,将由一个四层循环完成。
因为每一次要进行计算的Listmatch的每一项的尺寸都是固定的,即每一项的str都是相同的大小,所以布尔类型的判定数组的大小在最开始就可以固定。
在每一次循环比对的过程中,如果由一项相同,那么,布尔数组的相应位置将会被置为true,在本次循环比对结束的时候,对这个布尔数组循环计算是否全为true,如果全为true的话,也就是证明这一项出现国一次,直接将Count加1即可。
在每一次循环结束的时候,将会对布尔类型的判定数组进行刷新全为false以供下次比对。
在本次比对结束之后,将已经计算完成的Listmatch连边传入Cut类的cut函数中进行剪枝。
Cut类中的int support 是由Support中的getsupport函数导入的,support 也就是支持度,可以预先设置,导入之后,将会对刚才传入的listmatch函数的支持度进行判断,如果支持度不满足,那么将会被删去。
在一便循环之后,即可将本层中不满足支持度的项全部删去。
在得到第一层之后,将会把第一层得到的数据传入到Listtwo类中,
在此处由一个二层循环,生成出二层的频繁项集,第一层循环和第二层循环都由传入的已经经过计算和修剪的第一层循环链表的大小作为循环次数。
在经过这两层循环之后,就可以生成一个二层的未经计算和剪枝的二层链表。
然后,将这个链表传入到Count类中进行次数的计算,由于Count类中的count方法在最开始设计时就保证了其复用性,所以在这里直接调用即可。
由于本层频繁项集已经比刚在得到的第一层循环项集多了一层,所以在进入count类进行计数的时候,自动生成的布尔类型的判断数组的大小也就比第一层调用时多生成了一个。
同理在经过Count的计数之后,直接传入Cut类进行修剪,不满足最小支持度的直接剪掉即可。
此部分的流程图如图1:

     图 1

在经过这一步之后,得到了二层的频繁项集,接下来要进行的,就是将已经得到的第一层和第二层传入到Apriori算法在本系统的核心体现的类中Listany类。
在第一层和第二层传入之后,下一步应该是迭代生成下一层,直到无法生成下一层为止。
首先声明一个List<List> list类型的链表用来存放得到的不同大小的频繁项集链表。
将得到的第一层平频繁项集和第二层频繁项集依次传入。
在传入之后,将list传入到工具类creat中,用于生成下一层的频繁项集。
在传入之后,为了计算下一层,使用上一层作为基础,首先是一个四层循环,用来循环生成下一层,在这里,只要两个链表中的项在比对时,发现只要有正好比自己的str的长度少一个的数量相同,那么就证明这两项是可以声明出下一项的。
此时声明一个int类型的计数器,在每次比对成功时,都将计数器加一,在一次循环结束的时候,计算计数器的大小来判断是否满足生成条件。
在每次循环结束之后,都要将计数器归零。
此部分的示意图如图2,以前三层迭代为例:

                         图2

经过循环得到链表,本身存在重复性经行,所以要在传入Count和Cut类之前,将重复的项进行剪切,此时,只需要将链表传入本类中声明的delect函数中进行去重。
去重由两层循环构成,方法是依次和自己经行比对,看是否重复,重复代码删去。
在经过去重之后,得到的链表可以与上一层频繁项集比对,如果本层链表含有上一层中已经确定不是频繁项集的子集,那么可以直接确定这一项不是平凡项集,直接删去之后将会提升系统的效率,这以功能的实现依靠的是本类中的delectA方法。
DelectA方法所需要的参数是刚经过去重产生的本层链表和上一层Cut函数已经完整的到的不是频繁项集的项集。
在每次比对的时候,由已经提前声明的计数器count来计数,在循环技术时,如果计数器的大小和lose的每一项的Token的str的大小相等,那么即可证明此项包含之前不是频繁项集。
此部分也就是剪枝,可以由如图3来简单理解:

                 图3

在这里提前修剪,可以省下很多运算效率。
在这里得到最后得到的链表将依次传入Count和Cut类中计数和不满足最小支持度的进行删去操作,其中删去的元素再次保存到Cut的静态链表Listlose中。
最后得到完整的本层频繁项集,得到之后,首先判断链表是否为空,如果不为空的情况下,将本层链表保存到大的List<List> list链表之中,然后作为参数传入到下一次循环,以生成下一层的频繁项集。
本部分的流程图如图4:

                         图4

在迭代生成结束之后,即可得到完整的由每一层频繁项集构成的List链表,也就完成的客户购物推荐系统的基础准备工作。
(3) 用户的读入与分析
用户的读入由前端的Jsp界面获得,给与顾客勾选框选择,如图5

                          图5用户点击之后,点击了几个,就会生成多大的List<String> goods链表返回。用JQuery和AJAX实现异步刷新页面。

本部分的流程图如图6所示:

图6

其中,用户传回的数据传入到RecommendController类中,传入之后,函数在此函数中进行(1)(2)的基础准备工作。
准备工作完成之后,将已经得到的用户选择的商品列表传入Confidence类中进行置信度的剪裁。
Confidence中一共包含7个方法。
第一个方法match1是找到顾客购买的数据在其相应频繁项集列表的次数。
第二个方法match2是为了计算高一层中的所有包含此用户输入的子集的频繁项集的所占次数,并将此频繁项集提取出来放到一个新的集合之中,方便之后计算。
第三个方法match3是为了去除所有相同的频繁项集,保留一项方便计算即可。
第四个方法是BigDecimal类型的Chufa,本方法是为了在最后计算出置信度之后直接经行比对大小使用,方法的传入的参数是两个int类型的变量,传入之后经计算返回一个BigDecimal类型的数据。
第五个方法 calculate是为了计算置信度,本方法由一个循环构成,循环将会依次利用Chufa函数计算出list循环项集的每一项的置信度,并利用Token的setRite函数将其保存。
第六个方法export是为了将不符合最低置信度要求的数据项删除,可以在这里设置最低置信度,置信度的初始值设置为0.03,本方法由一个循环完成,循环的每一次都比对传入的已经计算的输出项集的置信度是否满足要求,其中不满足最低置信度的项直接删除即可,这里得到的数据项传回到主方法confidence中。
第七个方法confidence依次利用以上函数生成出最终满足要求的数据项
最终得到的数据包装并返回给前端,由前端获取之后进行获取显示,显示给顾客。
(4) 前端界面
前端界面主要由两部分组成

  1. 输入界面如图7

                         图7
    

用户只需勾选想要购买的商品最后点击提交即可
2.回显界面如图8

                              图8

在这里我们假设点击了,如图9

           图9

输出的内容如上所示,在这里将会显示出顾客还想要购买哪些东西。
在这里可以继续勾选想要购买的东西,勾选完成之后点击购买完成即可完成购买。
3系统设计方案

3.1 系统相关原理说明

本系统主要使用Java作为后端,Jsp界面作为前端。
主要使用的算法是Apriori算法。
后端使用SpringMVC框架。
设计Jsp使用BootStrap前端框架。
前端和后端的链接用JQuery
示意图如图10:

                     图10

3.2输入模块

本系统有四个地方可以进行输入修改

  1. 第一个可以修改的是传入的数据集
    修改的位置是FRead类中的fread函数
    修改方法是更改fread方法里面文件的绝对路径即可
  2. 第二个可以修改的是支持度的大小
    修改的位置是Support类中的define方法
    修改方法是直接更改support的大小即可
  3. 第三个可以修改的是置信度的大小
    修改的位置是Confidence的export方法
    修改的方法是更改fa的大小
  4. 第四个修改的就是每次的输入
    这一部分由顾客每次进行的点击完成
    点击完成之后将把数据传入后端

4系统测试

4.1 系统测试

(1) 数据集选择bread basket.csv
支持度设置为0.001
置信度设置为0.03
勾选框如图11

                       图11

此时,输出界面如图12

                        图12

(2) 数据集选择bread basket.csv
支持度设置为0.005
置信度设置为0.03
勾选框如图13

                       图13

此时输出界面如图14

                    图14

代码部分

首先是工程截图 方便大家理解结构


接下里是纯代码 如果需要工程的话可以联系我

package controller;
import bean.ListAny;
import bean.ListPerson;
import bean.Support;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import util.Confidence;
import util.Shop;
import util.Show;
import util.Token;
import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.util.ArrayList;
import java.util.List;
@Controller
public class RecommendController {@RequestMapping("recommend")@ResponseBodypublic List<String> recommend(@RequestParam(value = "goods") List<String> goods){System.out.println(goods);StringBuilder str=new StringBuilder();for (int i = 0; i < goods.size(); i++) {str.append(goods.get(i)).append(",");}str.deleteCharAt(str.length()-1);System.out.println(str);Support s=new Support();           //输入支持度最小值s.define();ListPerson lp=new ListPerson();     //建立顾客表lp.creat();ListAny l=new ListAny();            //迭代生成次数链表List<List<Token>> list=l.creat();//Show.show(list);                      //输出Shop.shoping(str.toString());List<Token> listp=new ArrayList<>();Confidence cf=new Confidence();listp=cf.confidence(list);List<String> listpp=new ArrayList<>();for (int i = 0; i < listp.size(); i++) {listpp.add(listp.get(i).getStr().get(0));}return listpp;}
}
package bean;
import util.Creat;
import util.Cut;
import util.Token;import java.util.ArrayList;
import java.util.List;
public class ListAny {void cutnull(List<List<Token>> list){for (int i = 0; i < list.size(); i++) {if (list.get(i).size()==0){list.remove(i);i--;}}}public List<List<Token>> creat(){List<List<Token>> list=new ArrayList<>();List<Token> list1=new ArrayList<>();List<Token> list2=new ArrayList<>();ListOne l1=new ListOne();ListTwo l2=new ListTwo();list1=l1.creat();list.add(list1);               //放入第一层list2=l2.creat(list1);list.add(list2);  //放入第二层Creat c=new Creat();int a=list.size()-1;do {list.add(c.creat(list.get(a)));a++;int z=0;}while (list.get(a).size()>0);cutnull(list);return list;}
}
package bean;
import util.Count;
import util.FRead;
import util.Token;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ListOne {public List<Token> creat(){FRead f=new FRead();         //导入数据BufferedReader reader=f.fread();List<Token> list=null;     //所有元素集合try{list=new ArrayList<>();reader.readLine();String line = null;boolean flag=true;while((line=reader.readLine())!=null){String item[]=line.split(",");String last=item[item.length-4];for (int i = 0; i < list.size(); i++) {if (last.equals(list.get(i).getStr().get(0))){flag=false;break;}}if (flag){list.add(new Token(last));}flag=true;}} catch (IOException e) {e.printStackTrace();}Count c=new Count();list=c.count(list);return list;}
}
package bean;
import util.FRead;
import util.Token;
import javax.imageio.IIOException;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ListPerson {public static List<Token> listPer=new ArrayList<>();public void creat(){FRead f=new FRead();         //导入数据BufferedReader reader=f.fread();try{reader.readLine();String line=null;boolean flag3=true;while((line=reader.readLine())!=null){String item[]=line.split(",");String last=item[item.length-4];int number=Integer.parseInt(item[item.length-5]);if(listPer.size()==0){listPer.add(new Token(last,number,0));}else{for (int i = 0; i < listPer.size(); i++) {if (number==listPer.get(i).getPerNumber()){listPer.get(i).getStr().add(last);flag3=false;}}if (flag3){listPer.add(new Token(last,number,0));}flag3=true;}}} catch (IOException e) {e.printStackTrace();}}
}
package bean;
import util.Count;
import util.Token;
import java.util.ArrayList;
import java.util.List;
public class ListTwo {public List<Token> creat(List<Token> list){List<Token> list2=new ArrayList<>();for(int i=0;i<list.size();i++){for (int j=i+1;j<list.size()-1;j++){list2.add(new Token(list.get(i).getStr().get(0),list.get(j).getStr().get(0)));}}Count c=new Count();list2=c.count(list2);return list2;}
}
package bean;
import java.util.Scanner;
public class Support {static int support;public void define(){support=50;
/*        Scanner sc = new Scanner(System.in);      //输入最小支持度this.support=sc.nextInt();*/}public int getSupport() {return support;}public void setSupport(int support) {this.support = support;}
}
package util;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class Confidence {int match1(List<Token> list ,List<String> lists){    //找到自己本身所占次数int b=lists.size();int c=0;int z=0;boolean flag=false;for (int i = 0; i < list.size(); i++) {for (int j = 0; j < lists.size(); j++) {for (int k = 0; k <b; k++) {for (int l = 0; l < b; l++) {if (list.get(i).getStr().get(k).equals(lists.get(l))){c++;}}}if(c==b){z=list.get(i).getCount();flag=true;break;}c=0;}if (flag){break;}}return z;}List<Token> match2(List<Token> list,List<String> lists) {       //计算高一层包含此集合的次数List<Token> a = new ArrayList<>();int b = lists.size();int c = 0;for (int i = 0; i < list.size(); i++) {for (int j = 0; j < b; j++) {for (int k = 0; k < b + 1; k++) {if (list.get(i).getStr().get(k).equals(lists.get(j))){c++;}}}if (c==b){a.add(new Token(list.get(i).getStr(),list.get(i).getCount()));}c=0;}return a;}void match3(List<Token> list,List<String> str){    //去除相同,保留一项int a=0;for (int i = 0; i < list.size(); i++) {for (int j = 0; j < str.size(); j++) {for (int k = 0; k < list.get(i).getStr().size(); k++) {if (str.get(j).equals(list.get(i).getStr().get(k))){list.get(i).getStr().remove(k);k--;}}}}}public  BigDecimal Chufa(int a,int b){//DecimalFormat dF=new DecimalFormat("0.00000000");BigDecimal a1 = new BigDecimal(a);BigDecimal b1 = new BigDecimal(b);return a1.divide(b1,8,BigDecimal.ROUND_HALF_UP);}void calculate(List<Token> list,int z){for (int i = 0; i <list.size() ; i++) {list.get(i).setRite(Chufa(list.get(i).getCount(),z));}}void export(List<Token> listp){BigDecimal fa=new BigDecimal(0.03);for (int i = 0; i < listp.size(); i++) {if (listp.get(i).getRite().compareTo(fa)==-1){listp.remove(i);i--;}}}public List<Token> confidence(List<List<Token>> list){List<String>  lists=new ArrayList<>();    //存储已经购买的int b=Shop.str.length;int x=list.size();for (int i = 0; i < b; i++) {lists.add(Shop.str[i]);}List<Token> list1=list.get(b-1);int z=match1(list1,lists);List<Token> listp= new ArrayList<>();if (x>b){listp=match2(list.get(b),lists);      //高一层中包含输入商品的集合}match3(listp,lists);calculate(listp,z);export(listp);return listp;}
}
package util;
import bean.ListPerson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Count {public List<Token> count(List<Token> listmatch){List<Token> listperson=ListPerson.listPer;int b=listmatch.get(0).getStr().size();boolean[] flag1=new boolean[b];for (int i = 0; i < b; i++) {                   //定义判断布尔数组flag1[i]=false;}boolean flag2=true;for (int i = 0; i < listperson.size(); i++) {for (int j = 0; j < listmatch.size(); j++) {for (int k = 0; k < b; k++) {for (int l = 0; l < listperson.get(i).getStr().size(); l++)
{ if(listmatch.get(j).getStr().get(k).equals(listperson.get(i).getStr().get(l))){flag1[k]=true;}}}for (int k = 0; k < b; k++) {if (flag1[k]==false){flag2=false;}}if (flag2){listmatch.get(j).setCount(listmatch.get(j).getCount()+1);}for (int k = 0; k < b; k++) {flag1[k]=false;}flag2=true;}}Collections.sort(listmatch);Cut c=new Cut();c.cut(listmatch);return listmatch;}
}
package util;
import java.util.ArrayList;
import java.util.List;
public class Creat {List<Token> delectA(List<Token> list){   //去除子集不是频繁项集的项int b=list.get(0).getStr().size();Boolean[] flag=new Boolean[b-1];int count=0;List<Token> lose=Cut.listlose.get(b-2);  //导入上一层不是平凡项集的集合for (int i = 0; i < list.size(); i++) {for (int j = 0; j < lose.size(); j++) {for (int k = 0; k < list.get(i).getStr().size(); k++) {for (int l = 0; l < lose.get(k).getStr().size(); l++) {if (list.get(i).getStr().get(k).equals(lose.get(j).getStr().get(l))){count++;}}}if (count==b-1){list.remove(i);count=0;i--;break;}count=0;}}return list;}List<Token> delect(List<Token> list){          //去重int b=list.get(0).getStr().size();boolean[] flag1=new boolean[b];for (int i = 0; i < b; i++) {flag1[i]=false;}int x=0;for (int i = 0; i < list.size(); i++) {for (int j = i+1; j < list.size()-1; j++) {for (int k = 0; k < b; k++) {for (int l = 0; l < b; l++) {if (list.get(i).getStr().get(k).equals(list.get(j).getStr().get(l))){flag1[k]=true;break;}}}for (int k = 0; k < b; k++) {if (flag1[k]){x++;}}if (x==b){list.remove(j);j--;}for (int k = 0; k < b; k++) {flag1[k]=false;}x=0;}}return list;}public List<String> compose(List<String> str1,List<String> str2){List<String> str=new ArrayList<>();for (int i = 0; i < str1.size(); i++) {str.add(str1.get(i));}boolean flag=true;for (int i = 0; i < str2.size(); i++) {for (int j = 0; j < str.size(); j++) {if (str2.get(i).equals(str.get(j))){flag=false;break;}}if (flag){str.add(str2.get(i));}flag=true;}return str;}public List<Token> creat(List<Token> list){List<Token> listplus=new ArrayList<>();int b=list.get(0).getStr().size();int count=0;for (int i = 0; i < list.size()-1; i++) {for (int j = i+1; j < list.size(); j++) {for (int k = 0; k < b; k++) {for (int l = 0; l < b; l++) {if (list.get(i).getStr().get(k).equals(list.get(j).getStr().get(l))){count++;}}}if (count==b-1){listplus.add(new Token(compose(list.get(i).getStr(),list.get(j).getStr())));}count=0;}}int z=0;listplus=delect(listplus);int a=0;if (listplus.size()>0){listplus=delectA(listplus);}int a1=0;if(listplus.size()>0){Count c=new Count();c.count(listplus);}int a2=0;return listplus;}
}
package util;
import bean.Support;
import java.util.ArrayList;
import java.util.List;
public class Cut {public static List<List<Token>> listlose =new ArrayList<>();public List<Token> cut(List<Token> list){List<Token> listcentre=new ArrayList<>();int c=list.get(0).getStr().size();Support s=new Support();int support=s.getSupport();for (int i = 0; i < list.size(); i++) {if (list.get(i).getCount()<support){listcentre.add(new Token(list.get(i).getStr()));list.remove(i);i--;}}listlose.add(listcentre);int a=0;return list;}
}package util;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class FRead {public BufferedReader fread(){BufferedReader reader=null;try {reader = new BufferedReader(new FileReader("E:\\Git\\Gitcode\\Apriori\\src\\main\\java\\bread basket.csv"));} catch (FileNotFoundException e) {e.printStackTrace();}return reader;}
}
package util;
import java.util.Scanner;
public class Shop {static public String[] str;static public void shoping (String strc) {String line;
/*        System.out.println("请输入你想要购买的商品,以,分割");*/
/*        Scanner sc = new Scanner(System.in);      //输入字符串line=sc.nextLine();*/str=strc.split(",");}
}
package util;
import java.util.List;
public class Show {static public void show(List<List<Token>> list){for (int i = 0; i < list.size(); i++) {for (int j = 0; j < list.get(i).size(); j++) {System.out.println(list.get(i).get(j));}}}
}
package util;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class Token implements Comparable<Token> {List<String> str = new ArrayList<>();int count;BigDecimal rite;int perNumber;public Token(String str, int count) {this.str.add(str);this.count = count;}public Token(String str) {this.str.add(str);}public Token(List<String> str1, List<String> str2){for (int i = 0; i < str1.size(); i++) {this.str.add(str1.get(i));}for (int i = 0; i < str2.size(); i++) {this.str.add(str2.get(i));}}public Token(List<String> str, int count, BigDecimal rite) {this.str = str;this.count = count;this.rite = rite;
}
public Token(String str1,String str2) {this.str.add(str1);this.str.add(str2);}public Token(String[] str1,int perNumber) {for (int i = 0; i < str1.length; i++) {this.str.add(str1[i]);}this.perNumber=perNumber;}public Token(String str1,int perNumber,int a) {this.str.add(str1);this.perNumber=perNumber;}public Token(List<String> str1){for (int i = 0; i < str1.size(); i++) {this.str.add(str1.get(i));}}public Token(List<String> str1,int count){for (int i = 0; i < str1.size(); i++) {this.str.add(str1.get(i));}this.count=count;}@Overridepublic String toString() {return "Token{" +"str=" + str +", count=" + count +", rite=" + rite +", perNumber=" + perNumber +'}';}public List<String> getStr() {return str;}public void setStr(List<String> str) {this.str = str;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public BigDecimal getRite() {return rite;}public void setRite(BigDecimal rite) {this.rite = rite;}public int getPerNumber() {return perNumber;}public void setPerNumber(int perNumber) {this.perNumber = perNumber;}@Overridepublic int compareTo(Token o) {if (this.getCount()>o.getCount()){return -1;}else if(this.getCount()<o.getCount()){return 1;}else {return 0;}}
}
<%--Created by IntelliJ IDEA.User: wbDate: 2021/6/13Time: 16:56To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/bootstrap.min.css">
<%--    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/style.css">--%>
<%--    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/wbstyle.css">--%><script src="${pageContext.request.contextPath}/assets/js/jquery-3.4.1.min.js"></script><script src="${pageContext.request.contextPath}/assets/js/bootstrap.bundle.min.js"></script>
<%--    <script src="${pageContext.request.contextPath}/assets/js/checklogin.js"></script>--%><title>Title</title><style>*{margin: 0;}body{background-color: #f2f2f2;}.main{margin: 0 20%;padding: 50px 50px;background-color: white;text-align: center;}.title{margin: 50px 0;text-align: center;}</style>
</head>
<body>
<%--<h2>Hello World!</h2>--%>
<div class="main"><div>&nbsp;</div><div class="title"><h1>Apriori  购物推荐系统</h1></div><h3 style="margin-bottom: 30px">请在以下商品中勾选你想要购买的商品</h3><form method="get" id="get"><div class="container"><div class="row" style="margin-top: 20px"><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox1" name="goods" value="Coffee"><label class="form-check-label" for="inlineCheckbox1">Coffee</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox2" name="goods" value="Bread"><label class="form-check-label" for="inlineCheckbox2">Bread</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox3" name="goods" value="Tea"><label class="form-check-label" for="inlineCheckbox3">Tea</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox4" name="goods" value="Cake"><label class="form-check-label" for="inlineCheckbox4">Cake</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox5" name="goods" value="Pastry"><label class="form-check-label" for="inlineCheckbox5">Pastry</label></div></div><div class="row" style="margin-top: 20px"><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox6" name="goods" value="Sandwich"><label class="form-check-label" for="inlineCheckbox6">Sandwich</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox7" name="goods" value="Medialuna"><label class="form-check-label" for="inlineCheckbox7">Medialuna</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox8" name="goods" value="Hot chocolate"><label class="form-check-label" for="inlineCheckbox8">Hot chocolate</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox9" name="goods" value="Cookies"><label class="form-check-label" for="inlineCheckbox9">Cookies</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox10" name="goods" value="Brownie"><label class="form-check-label" for="inlineCheckbox10">Brownie</label></div></div><div class="row" style="margin-top: 20px"><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox11" name="goods" value="Farm House"><label class="form-check-label" for="inlineCheckbox11">Farm House</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox12" name="goods" value="Juice"><label class="form-check-label" for="inlineCheckbox12">Juice</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox13" name="goods" value="Muffin"><label class="form-check-label" for="inlineCheckbox13">Muffin</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox14" name="goods" value="Alfajores"><label class="form-check-label" for="inlineCheckbox14">Alfajores</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox15" name="goods" value="Scone"><label class="form-check-label" for="inlineCheckbox15">Scone</label></div></div><div class="row" style="margin-top: 20px"><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox16" name="goods" value="Soup"><label class="form-check-label" for="inlineCheckbox16">Soup</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox17" name="goods" value="Toast"><label class="form-check-label" for="inlineCheckbox17">Toast</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox18" name="goods" value="Scandinavian"><label class="form-check-label" for="inlineCheckbox18">Scandinavian</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox19" name="goods" value="Truffles"><label class="form-check-label" for="inlineCheckbox19">Truffles</label></div><div class="form-check form-check-inline col"><input class="form-check-input" type="checkbox" id="inlineCheckbox20" name="goods" value="Coke"><label class="form-check-label" for="inlineCheckbox20">Coke</label></div></div></div><button type="button" class="btn btn-primary" id="submit" style="margin: 40px 0">提交</button><h1 id="retitle"></h1><div id="recommend"></div></form><button type="button" class="btn btn-primary" style="margin: 40px 0;display: none" id="done">购买完成</button>
</div>
<script>$(document).ready(function (){$("#submit").click(function (){$.get({url:"${pageContext.request.contextPath}/recommend",data:$("#get").serialize(),success:function (data) {// var jsonData = JSON.parse(data)//alert(data)$("#retitle").text("那么你还有可能购买")var recommendHtml = ""for(goods in data){recommendHtml=recommendHtml+'<div class="form-check">'+'<input class="form-check-input" type="checkbox" id="inlineCheckbox20" name="goods" value="'+data[goods]+'">'+'<label class="form-check-label" for="inlineCheckbox20">'+data[goods]+'</label>'+'</div>'}$("#recommend").html(recommendHtml)$("#done").css("display","inline")}})})})
</script>
</body>
</html>

基于Apriori算法,SpringBoot框架作为前端,java语言编写的购物推荐系统 0.0相关推荐

  1. 基于Apriori算法的网上图书销售ssm java毕业设计

    基于Apriori算法的网络书城,首先系统的主要研究是算法方面,通过算法,进行书籍的关联计算,并且进行图书的精准销售,营销,为客户推荐一些兴趣书籍,扩大用户的选择范围,提高网站的营销量.本系统开发平台 ...

  2. 利用weka进行数据挖掘——基于Apriori算法的关联规则挖掘实例

    文章目录 1. weka安装 2. 先分析一个Apriori算法的关联规则挖掘实例 3. 利用weka进行数据挖掘 3.1 将数据转为ARFF格式 3.2 利用weka进行分析 4. 参考文章 首先, ...

  3. #研发解决方案#基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案

    郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...

  4. DL之RetinaNet:基于RetinaNet算法(keras框架)利用resnet50_coco数据集(.h5文件)实现目标检测

    DL之RetinaNet:基于RetinaNet算法(keras框架)利用resnet50_coco数据集(.h5文件)实现目标检测 相关文章 DL之RetinaNet:RetinaNet算法的简介( ...

  5. 基于Apriori算法的购物网站商品推荐系统

    基于Apriori算法的购物网站商品推荐系统 目 录 一. 算法内容 3 Step 1 收集用户偏好 3 Step 2 对数据进行预处理 3 Step 3 计算相似度 4 Step 4 找邻居 5 S ...

  6. 一种基于DFA算法的敏感词检测JAVA程序片段

    本文章提供一种基于DFA算法的敏感词检测JAVA程序片段,如下: 1.构造多叉树数据结构 import org.jetbrains.annotations.NotNull;/*** 多叉树* @aut ...

  7. 基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案 郑昀 基于杨海波的设计文档(转)...

    郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...

  8. A*算法解决八数码问题 Java语言实现

    A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...

  9. jdbc是java语言编写的类和接口_JDBC——Java语言连接数据库的标准

    JDBC概述 API JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Jav ...

最新文章

  1. 【ElementUI】 table表格尾部的合计行,固定表头却不显示合计行
  2. Guava之Ordering
  3. listbox icon
  4. 缓存使用-4、Redis 持久化机制
  5. python3中map的用法_python3中map()函数用法
  6. 怎么使用小爱同学音响_智能音响购买指南!!!
  7. Selective Search for Object Recognition
  8. 【伙伴故事】一盏智能灯,点亮家庭和工业照明的新未来
  9. 使用 Hyper-v 虚拟化域控制器
  10. Java笔记(十七) 异步任务执行服务
  11. [论文阅读] End-to-End Incremental Learning
  12. 水经注下载的地图版权_怎么下载天地图地方高清影像
  13. delphi oracle 分页,使用原生ADO对数据进行分页显示delphi数据库操作下载
  14. java 中介模式_java设计模式-中介者模式
  15. AtCoder ABC172 E - NEQ(组合数 + 容斥原理)
  16. ffmpeg —— v4l2录制h264视频文件(边采集边转码)
  17. 不一样的解决Non-static method 'xxx' cannot be referenced from a static context
  18. ShardingSphere实践(7)——数据加密
  19. 解决“无任何网络提供程序接受指定的网络路径”问题的几个方法
  20. linux cp目录到指定目录,linux复制指定目录下的全部文件到另一个目录中,linux cp 文件夹...

热门文章

  1. 抖音知识科普号应该怎么运营?应注意哪些方面问题?
  2. 问题 A: 珠心算测验
  3. 京东旗舰店商品详情数据采集接口代码对接教程
  4. 手机信号推流到rtmp服务器,大概是最简单的 rtmp 推流服务器搭建方法
  5. Mybatis 一级缓存,Mybatis 二级缓存,Mybatis 缓存失效
  6. tp报错:致命错误: Call to undefined function captcha_src()的解决方案
  7. Dart开发(一)Windows平台环境搭建
  8. 微信小程序门诊医院体检挂号缴费药品信息管理系统+后台管理系统SSM-JAVA【数据库设计、论文、源码、开题报告】
  9. 计算机应用与修复,计算机硬盘维修与数据恢复
  10. 【python爬虫系列】爬虫+Selenium