一、前述
线上模型部分根据用户的行为数据进行推荐,相当于测试数据
二、具体代码
package com.alibaba.dubbo.demo.impl;
import com.alibaba.dubbo.demo.RcmdService;
import redis.clients.jedis.Jedis;
import java.util.*;
public class RcmdServiceImpl implements RcmdService {
@Override
public List<String> getRcmdList(String uid) {
// 获得数据库连接
Jedis jedis = new Jedis("node05", 6379);
jedis.select(2);
// 从用户历史下载表来获取最近下载
String downloadListString = jedis.hget("rcmd_user_history", uid);
String[] downloadList = downloadListString.split(",");
// 获取所有应用ID列表
Set<String> appList = jedis.hkeys("rcmd_item_list"); //获取的是所有的app keys
// 存储总的特征分值
Map<String, Double> scores = new HashMap<String, Double>();
// 分别计算所有应用的总权重
for (String appId : appList) {
// 计算关联权重
double relativeFeatureScore = this.getRelativeFeatureScore(appId, downloadList, jedis);
updateScoresMap(scores, appId, relativeFeatureScore);
// 计算基本权重
double basicFeatureScore = this.getBasicFeatureScore(appId, jedis);
updateScoresMap(scores, appId, basicFeatureScore);
}
//这里将map.entrySet()转换成list
List<Map.Entry<String, Double>> list = new ArrayList<Map.Entry<String, Double>>(scores.entrySet());
//然后通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
//升序排序
public int compare(Map.Entry<String, Double> o1,
Map.Entry<String, Double> o2) {
return -o1.getValue().compareTo(o2.getValue());//自定义排序,降序排序
}
});
// 打印分值
// for (Map.Entry<String, Double> mapping : list) {
// System.out.println(mapping.getKey() + ":" + mapping.getValue());
// }
// 取前10个appID返回
List<String> result = new ArrayList<>();
int count = 0;
for (Map.Entry<String, Double> mapping : list) {
count++;
result.add(mapping.getKey());
if(count==10){
break;
}
}
jedis.close();
return result;
}
private void updateScoresMap(Map<String, Double> scores, String appName, double score) {
if (scores.get(appName) == null) {
scores.put(appName, score);
} else {
scores.put(appName, scores.get(appName) + score);
}
}
/**
* 获取关联特征权重!!!
* @param appId
* @param downloadList
* @param jedis
* @return
*/
private double getRelativeFeatureScore(String appId, String[] downloadList, Jedis jedis) {
double score = 0.0;
for (String downloadAppId : downloadList) {
// Item.id*Item.id@70*193
// 构成关联特征
String feature = "Item.id*Item.id@" + appId + "*" + downloadAppId;
String rcmd_features_score = jedis.hget("rcmd_features_score", feature);//拿到模型中的权重
if(rcmd_features_score!=null){
score += Double.valueOf(rcmd_features_score);
}
String featurex = "Item.id*Item.id@" + downloadAppId + "*" + appId;//将模型中的特征翻转 appid100*app1或者app1*app100
String rcmd_features_scorex = jedis.hget("rcmd_features_score", featurex);
if(rcmd_features_scorex!=null) {
score += Double.valueOf(rcmd_features_scorex);
}
}
return score;
}
/**
* 获取app的基本特征权重!!!
* @param appId
* @param jedis
* @return
*/
private double getBasicFeatureScore(String appId, Jedis jedis) {
// 存储基本特征分值
double basicScore = 0.0;
// 从商品词表取基本特征
/*
Item.id@146 软件ID
Item.name@183 名字
Item.author@zhouming 作者
Item.sversion@1.3.2 版本号
Item.ischarge@1 是否收费
Item.dgner@husheng 设计者
Item.font@Consolos 字体
Item.icount@4 图片数量
Item.icount_dscrt@4
Item.stars@5 星级
Item.price 价格
Item.fsize@6 文件大小
Item.fsize_dscrt@6
Item.comNum@0 评论数量
Item.comNum_dscrt@0
Item.screen@FHD 屏幕类型
Item.downNum@200 下载数
Item.downNum_dscrt@200
*/
String[] basicFeatureNames = {"Item.id", "Item.name", "Item.author", "Item.sversion", "Item.ischarge"
, "Item.dgner", "Item.font", "Item.icount", "Item.icount_dscrt", "Item.stars", "Item.price"
, "Item.fsize", "Item.fsize_dscrt", "Item.comNum", "Item.comNum_dscrt", "Item.screen", "Item.downNum"
, "Item.downNum_dscrt"};
String rcmd_item_list = jedis.hget("rcmd_item_list", appId);//基本特征中的值
String[] basicFeatures = rcmd_item_list.split("\t");
for (int i = 0; i < basicFeatureNames.length; i++) {//遍历前缀集合
String rcmd_features_score = jedis.hget("rcmd_features_score", basicFeatureNames[i] + "@" + basicFeatures[i]);
if (rcmd_features_score != null) {
basicScore += Double.valueOf(rcmd_features_score);
}
}
return basicScore;
}
}