【推薦系統篇】--推薦系統之測試資料

LHBlog發表於2018-03-27

一、前述

線上模型部分根據使用者的行為資料進行推薦,相當於測試資料

二、具體程式碼

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;
    }
}

 

相關文章