“浏览过该商品的用户还浏览了”的商品推荐

 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 BrowseAgain {
 protected Map<String,HashMap<String,Integer>> dataMap;//对应用户及其所购买过的商品和数量
 protected static HashMap<String,ArrayList<String>> proUsersMap;//对应商品及其购买该商品的用户
 protected HashSet<String> productsIdSet;//商品id集
 protected static LinkedHashMap<String,Float> userTreeMap;//基于用户比例,保存对应的结果,--productId_ratio
 protected static LinkedHashMap<String,Float> itemTreeMap;//基于商品比例,保存对应的结果,--productId_ratio
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  String tableName="bi_product_browse_product";
  new BrowseAgain().modelImport(tableName,30);
 
 }
public BrowseAgain(){
 long time1=System.currentTimeMillis();
 this.getDataMap();
 long time2=System.currentTimeMillis();
 System.out.println("读取数据库所需时间"+(time2-time1)+"ms");
 this.getProUsersMap();
 long time3=System.currentTimeMillis();
 System.out.println("固定统计p_users的时间"+(time3-time1)+"ms");
}
//基于用户比例推荐商品
public void browseAgainByUser(String productId,int topN){
 ArrayList<String> userList=this.getUsersByProductId(productId);
 HashMap<String,Float> productsNUserRatioMap=this.getProductsUserRatioMap(userList,productId);
 userTreeMap=this.getTopNProductsMap(productsNUserRatioMap, topN);
 
}
//基于商品比例推荐商品
public void browseAgainByProduct(String productId,int topN){
 ArrayList<String> userList=this.getUsersByProductId(productId);
 HashMap<String,Integer> productNumMap=this.getProductsMap(userList,productId);
 HashMap<String,Float> productsNumRatioMap=this.getProductsNumRatioMap(productNumMap);
 itemTreeMap=this.getTopNProductsMap(productsNumRatioMap, topN);
 
}
 
 
 //从数据库中获取数据,存入Map中
public void getDataMap(){
 dataMap=new HashMap<String,HashMap<String,Integer>>();
    productsIdSet=new HashSet<String>();
 JDBCConnection jc=new  JDBCConnection();
 jc.startMySQLConn();
      String sql = "select * from bi_persona_product"; 
              try {            
               ResultSet rs=  jc.selectSQL(sql);
     while (rs.next()){
      HashMap<String,Integer> productsMap=new HashMap<String,Integer>();
      String userId=rs.getString(2); //获取用户id
      String productsTemp=rs.getString(3);//获取用户id对应的Json
      JSONObject jsonObj = JSONObject.fromObject(productsTemp);
      Iterator<String> keys = jsonObj.keys();
      String key = null;
         String value = null; 
            while (keys.hasNext()) {                         
                key = (String) keys.next();
                //System.out.println("key="+key);
                value = jsonObj.getString(key);
                int num=Integer.parseInt(value);
                if(num!=0){
                   productsMap.put(key, num);
                   productsIdSet.add(key);                 
                }            
            }
            if( productsMap!=null){
              dataMap.put(userId,  productsMap);
            }
                 }
     System.out.println("从数据库获取的数据条数是:"+dataMap.size());
     System.out.println("从数据库获取的商品种类数是:"+productsIdSet.size());
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
        jc.closeMySQLConn();  
    
  }

//获取product_users Map,key=productId-商品id,value=usersList-浏览过该商品的用户
public void getProUsersMap(){
    proUsersMap=new HashMap<String,ArrayList<String>>();
 Iterator<String> iterSet=productsIdSet.iterator();
 while(iterSet.hasNext()){//遍历商品productsIdSet
  String proId=iterSet.next();
  ArrayList<String> userList=new ArrayList<String>();//对应的Users集
  Iterator<Entry<String, HashMap<String,Integer>>> iter1= dataMap.entrySet().iterator();//重新遍历dataMap,获取用户集的id
  Entry<String, HashMap<String,Integer>> entry1;
  while(iter1.hasNext()){
   entry1=iter1.next();
   String userId=entry1.getKey();
   Iterator<Entry<String,Integer>> productIter2=entry1.getValue().entrySet().iterator();
   Entry<String,Integer> productEntry2 ;
   while(productIter2.hasNext()){
     productEntry2=productIter2.next();
     String pid= productEntry2.getKey();
     Integer num= productEntry2.getValue();
     if( proId.equals(pid)&&num!=0){
      userList.add(userId);
      break;
     }   
   } 
  }
  proUsersMap.put(proId, userList);
 }
 
}
//将模型导入数据库,导入前,先清空表中的数据
public void  modelImport(String tableName,int topN){
 
 JDBCConnection jc=new JDBCConnection();
 jc.startMySQLConn();
 //导入前先清空表中的数据
  String sql="truncate table "+tableName;
 jc.deleteSQL(sql);
 //按用户比例导入
 Iterator<String> iterIdSet=this.productsIdSet.iterator(); 
 while(iterIdSet.hasNext()){
  String pId=iterIdSet.next();
  //System.out.println("基于用户的Id="+pId);
  this.browseAgainByUser(pId,topN);
  Iterator<Entry<String,Float>> iterUser=this.userTreeMap.entrySet().iterator();
  Entry<String,Float> entryUser;
  JSONObject jsonObject1 = new JSONObject();
  JSONArray jsonArray1 = new JSONArray();
  while(iterUser.hasNext()){
   entryUser=iterUser.next();
   jsonArray1.put(entryUser.getKey());  
  }
   jsonObject1.put("pro_id", jsonArray1);
   long proId=Long.parseLong(pId.trim()); 
   String sql1="insert into "+tableName+"(product_id,by_user) values"+"("+proId+",'" +jsonObject1.get("pro_id").toString()+"')";
   jc.insertSQL(sql1);
  
 }
 //按商品比例导入
 Iterator<String> iterIdSet2=this.productsIdSet.iterator();
 while(iterIdSet2.hasNext()){
  String proId=iterIdSet2.next();
  //System.out.println("基于Item的Id="+proId);
  this.browseAgainByProduct(proId,topN);
  Iterator<Entry<String,Float>> iterItem=this.itemTreeMap.entrySet().iterator();
  Entry<String,Float> entryItem;
  JSONObject jsonObject2 = new JSONObject();
  JSONArray jsonArray2 = new JSONArray();
  while(iterItem.hasNext()){
   entryItem=iterItem.next();
   //System.out.println(entryItem.getKey()+" "+entryItem.getValue());
   jsonArray2.put(entryItem.getKey());
  }
  jsonObject2.put("pro_id", jsonArray2); 
  String sql2="update "+tableName+" set by_item="+"( '" +jsonObject2.get("pro_id").toString()+"') where product_id="+Long.parseLong(proId);
  jc.insertSQL(sql2);  
 }
  jc.closeMySQLConn();
}
//根据商品id,获取浏览过该商品的用户集
public ArrayList<String> getUsersByProductId(String  productId){
 if(productsIdSet.contains(productId)){
  ArrayList<String> usersList=new ArrayList<String>();
  Iterator<Entry<String,ArrayList<String>>> iter=proUsersMap.entrySet().iterator();
  Entry<String,ArrayList<String>> entry;
  while(iter.hasNext()){
   entry=iter.next();
   if(productId.equals(entry.getKey())){
    usersList=entry.getValue();
    break;
   }
  }
  //System.out.println("浏览该商品的用户有"+usersList.size()+"个用户");
     return usersList;
 }else{
  System.out.println("该商品id="+productId+"不在浏览商品集中!");
  return null;
 }
 
}
//根据用户集,得到产品集合及其对应数量(除去正在浏览的商品id)。
public HashMap<String,Integer> getProductsMap(ArrayList<String> usersList,String pId){
 HashMap<String,Integer> productsNumMap=new HashMap<String,Integer>();
    if(usersList!=null){
     for(int i=0;i<usersList.size();i++){//遍历用户集
      String userId=usersList.get(i);//获取用户id
      Iterator<Entry<String, HashMap<String,Integer>>> iter3= dataMap.entrySet().iterator();//重新遍历dataMap,获取用户集的id
      Entry<String, HashMap<String,Integer>> entry3;
      while(iter3.hasNext()){
       entry3=iter3.next();
       String userid=entry3.getKey();
       if(userId.equals(userid)){
        Iterator<Entry<String,Integer>> productIter3=entry3.getValue().entrySet().iterator();
        Entry<String,Integer> productEntry3 ;
        while(productIter3.hasNext()){
          productEntry3=productIter3.next();
          String pid= productEntry3.getKey();
           int   pnum= productEntry3.getValue();
          if(!productsNumMap.containsKey(pid)){
           productsNumMap.put(pid, pnum) ;
          }else{
          int numTemp=productsNumMap.get(pid);
          int num=pnum+numTemp;
          productsNumMap.put(pid, num);      
          }
        }
        break;
       }   
      }  
     }
    }
    productsNumMap.remove(pId);
   return  productsNumMap;
}
//根据用户集,得到商品集合及其对应浏览商品的用户数量
public HashMap<String,Float> getProductsUserRatioMap(ArrayList<String> usersList,String pId){
 HashMap<String,Float> productsNUserRatioMap=new HashMap<String,Float>();
 HashSet<String> productSet=new HashSet<String>(); //购买指定商品的所有用户购买的其他商品集
 for(int i=0;i<usersList.size();i++){
  String userId=usersList.get(i);
  Iterator<Entry<String,ArrayList<String>>> iter= proUsersMap.entrySet().iterator(); 
  Entry<String,ArrayList<String>> entry;
  while(iter.hasNext()){
   entry=iter.next();
   String productId=entry.getKey();
   ArrayList<String> users=entry.getValue();
   if(users.contains(userId)){
    productSet.add(productId);
   }
  }
 }
   
 Iterator<String> iter=productSet.iterator();
 while(iter.hasNext()){
  String pid=iter.next();
  int userNo=0;
     ArrayList<String> userAllList=proUsersMap.get(pid);
     for(int j=0;j<userAllList.size();j++){
      String user=userAllList.get(j);
      if(usersList.contains(user)){
       userNo++;
      }
     }  
 float ratioTemp=userNo/(float)usersList.size();
    float ratio= (float)(Math.round(ratioTemp*10000))/10000;
    productsNUserRatioMap.put(pid, ratio);
 }
 productsNUserRatioMap.remove(pId);
   return  productsNUserRatioMap;
}
//根据productsNumMap 商品—数量Map  获取商品——比例Map
public HashMap<String,Float> getProductsNumRatioMap(HashMap<String,Integer>  productsNumMap){
 HashMap<String,Float> productsNumRatioMap=new HashMap<String,Float>();
 Iterator<Entry<String,Integer>> iter1= productsNumMap.entrySet().iterator();
 Entry<String,Integer> entry1;
 int sum=0;//统计总共的商品数
 while(iter1.hasNext()){
  entry1=iter1.next();
  sum+=entry1.getValue();
 }
 //System.out.println("用户集中看了又看的商品总数:"+sum);
 Iterator<Entry<String,Integer>> iter2= productsNumMap.entrySet().iterator();
 Entry<String,Integer> entry2;
 while(iter2.hasNext()){
  entry2=iter2.next();
  String productId=entry2.getKey();
  float ratioTemp=entry2.getValue()/(float)sum;
  float ratio = (float)(Math.round(ratioTemp*10000))/10000;//浮点型保留4位小数
  //System.out.println("ratioTemp="+ratioTemp+" "+"ratio"+ratio);
  productsNumRatioMap.put(productId, ratio);
 }
 return productsNumRatioMap;
}
public  ArrayList<String> getTopNProducts(HashMap<String,Float> productNumMap,int topN){
  ArrayList<String> productTopNIds=new ArrayList<String>();
  ByValueComparator bvc = new ByValueComparator(productNumMap);
  List<String> keys = new ArrayList<String>(productNumMap.keySet());
  int i=0;
     Collections.sort(keys, bvc);
     for(String key : keys) {
      if(i<topN){
       productTopNIds.add(key); 
      // System.out.println("topN的商品id"+key);
       i++;
      }else{
       break;
      }
        //System.out.printf("%s -> %d\n", key, productNumMap.get(key));
     }
     return productTopNIds;
}
public LinkedHashMap<String,Float> getTopNProductsMap(HashMap<String,Float> productNumMap,int topN){
 LinkedHashMap<String,Float> resultTreeMap=new LinkedHashMap<String,Float>();
  System.out.println("用户集中看了还看商品数是:"+productNumMap.size());
  ByValueComparator bvc = new ByValueComparator(productNumMap);
  List<String> keys = new ArrayList<String>(productNumMap.keySet());
  int i=0;
  System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
    Collections.sort(keys, bvc);
    for(String key : keys) {
     if(i<topN){
      float num=productNumMap.get(key);
     // System.out.println("排名前"+(i+1)+"名的是"+key+" "+ productNumMap.get(key));
      resultTreeMap.put(key, num) ;
      i++;
     }else{
      break;
     }
    }
    return resultTreeMap;
}
//内部类,用来将hashMap根据value进行排序
static class ByValueComparator implements Comparator<String> {
   HashMap<String, Float> base_map;
   public ByValueComparator(HashMap<String, Float> base_map) {
       this.base_map = base_map;
   }
   public int compare(String arg0, String arg1) {
       if (!base_map.containsKey(arg0) || !base_map.containsKey(arg1)) {
           return 0;
       }
       if (base_map.get(arg0) < base_map.get(arg1)) {
           return 1;
       } else if (base_map.get(arg0) == base_map.get(arg1)) {
           return 0;
       } else {
           return -1;
       }
   }
 }
}

你可能感兴趣的:(数据挖掘,模型,看了还看,商品推荐)