一、前述
線上模型部分根據使用者的行為資料進行推薦,相當於測試資料
二、具體程式碼
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; } }