这周做了一个“浏览过该商品的用户最终购买”的商品推荐,很多网站上比如京东等都有此功能,先讲一下自己的实现方法:
方法是基于数据库中的三个表实现的,这三个表分别是persona_order、persona_browse、以及product_similarity,分别是用户购买的商品(uid_proIds)、用户浏览的商品、以及商品的相似度表。
基本思路:根据正在浏览的商品id获取浏览过该商品的用户集,然后根据用户集得到他们购买的商品集以及对应的用户购买比例,由于此时得出的商品集不一定与浏览的商品属于
同类产品,所以将这个商品集与正在浏览的商品进行相似度的计算,根据用户购买比例和与浏览商品的相似度,对这些商品进行排序,然后给出排名靠前的商品,最后将结果保存到数据库表中,这样前端页面展示时候,只要去查结果就可以了。当然这个方法纯属于统计,不知道还有没有更高效的方法,欢迎大家分享!
最终的结果存的是一个map(String pId,float value),其中value=ratio=userRatio*factor+sim(pid,pId)*(1-factor)。factor是用户比例和相似度的权重因子。
另外,在商品展示时,可以按商品标签类别展示,标签分为三级、二级、一级,这样看起来顺眼一点。
package bubugao.com.productRecommendation;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
/*
* function:创建“浏览该商品的用户最终购买”的模型,并将模型导入数据库
* author:shiwei
*/
public class BrowseAndBuy {
protected Map<String,HashMap<String,Integer>> buyDataMap;//order表对应用户及其所购买过的商品和数量
protected static HashMap<String,ArrayList<String>> buyProUsersMap;//order表对应商品及其购买该商品的用户
protected HashMap<String,String> buyProducts;//order表中的商品id_name
protected HashSet<String> buyProIdSet;//order表中的商品id集
protected Map<String,HashMap<String,Integer>> browseDataMap;//browse表对应用户及其所购买过的商品和数量
protected static HashMap<String,ArrayList<String>> browseProUsersMap;//browse表对应商品及其购买该商品的用户
protected HashSet<String> browseProIdSet;//商品id集
private JDBCConnection jc ;
protected static LinkedHashMap<String,Float> userTreeMap;//保存对应的结果,--productId_ratio
public static void main(String[] args) {
// TODO Auto-generated method stub
String tableName="bi_product_browse_order";
new BrowseAndBuy().modelImport(tableName,30);
}
public BrowseAndBuy(){
long time1=System.currentTimeMillis();
this.getOrderDataMap();
this.getBuyProUsersMap();
this.getBrowseDataMap();
this.getBrowseProUsersMap();
long time2=System.currentTimeMillis();
System.out.println("统计时间="+(time2-time1));
jc=new JDBCConnection();
jc.startMySQLConn();
}
//基于用户比例推荐商品
public void browseAndBuyByUser(String productId,int topN){
ArrayList<String> userList=this.getBrowseUsers(productId);
HashMap<String,Float> product