栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

个性化音乐推荐系统

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

个性化音乐推荐系统

package com.example.musicSystem.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.musicSystem.entity.*;
import com.example.musicSystem.service.ICollectService;
import com.example.musicSystem.service.IRecommend;
import com.example.musicSystem.service.IScoreService;
import com.example.musicSystem.service.ISongListService;
import com.example.musicSystem.util.MapSortUtil;
import com.example.musicSystem.util.QJ;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("/recommend")
public class RecommendController {

    @Autowired
    IRecommend recommend;
    @Autowired
    private ICollectService collectService;
    @Autowired
    private ISongListService songListService;
    @Autowired
    private IScoreService scoreService;

    final static int NEIGHBORHOOD_NUM = 4;          //用户邻居数量
    final static int RECOMMENDER_NUM_USER = 4;      //基于用户推荐结果个数
    final static int RECOMMENDER_NUM_ITEM = 4;      //基于歌单推荐结果个数

    @RequestMapping("/recommendList")
    public ModelAndView recommendList(HttpServletRequest request) throws TasteException, IOException {

        //离线推荐:
        List hotSongList = new ArrayList<>();
        List goodSongList = new ArrayList<>();
        hotSongList = recommend.selectHotList();
        goodSongList = recommend.selectGoodList();

        Consumer consumer = (Consumer) request.getSession().getAttribute("consumer");
        ModelAndView modelAndView1 = new ModelAndView();
        modelAndView1.setViewName("recommend/toLogin");
        if (consumer == null) {
            return modelAndView1;
        }
        Integer userId = consumer.getId();

        //个性化推荐之基于内容的推荐:
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.like("user_id", userId);
        List collectList = collectService.list(wrapper);

        Integer[] ints = new Integer[collectList.size()];
        UserSong userSong = new UserSong();
        System.out.println("个人的:");


        for (int i = 0; i < collectList.size(); ++i) {
            ints[i] = (collectList.get(i)).getSongListId();
            System.out.println((collectList.get(i)).toString());
        }

        userSong.setUserId(collectList.get(0).getUserId());
        userSong.setSongListIds(ints);

        List collects = collectService.list();
        List userRS = new ArrayList();
        Map map = new HashMap();
        System.out.println("所有人的:");


        for (int i = 0; i < collects.size(); ++i) {
            System.out.println((collects.get(i)).toString());
            map.put((collects.get(i)).getUserId(), map.containsKey((collects.get(i)).getUserId()) ?
                    map.get((collects.get(i)).getUserId()) + "," + (collects.get(i)).getSongListId() :
                    (collects.get(i)).getSongListId() + "");
        }

        Iterator var15 = map.keySet().iterator();

        while (var15.hasNext()) {
            Integer key = (Integer) var15.next();
            UserSong userR2 = new UserSong();
            String[] split = (map.get(key)).split(",");
            Integer[] ints1 = new Integer[split.length];

            for (int i = 0; i < split.length; ++i) {
                ints1[i] = Integer.valueOf(split[i]);
            }

            userR2.setUserId(key);
            userR2.setSongListIds(ints1);
            userRS.add(userR2);
        }

        List userRList = this.jisuan(userSong, userRS);
        System.out.println("得出的结果:");

        for (int i = 0; i < userRList.size(); ++i) {
            System.out.println((userRList.get(i)).toString());
        }

        System.out.println("过滤处理数据之后:");
        String sqlId = this.chuli(userRList, userSong);
        String[] arr = sqlId.split(",");
        String str = "";
        for (int i = 0; i < arr.length; i++) {
            str += arr[i];
        }
        int[] a = new int[4];

        for (int i = 0; i < str.length(); i++) {
            a[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
        }

        System.out.println("推荐的歌单:");
        List s = songListService.getRecommendSongList(a[0], a[1], a[2], a[3]);

        for (int i = 0; i < s.size(); ++i) {
            System.out.println((s.get(i)));
        }

        //基于用户和歌单的协同过滤推荐:

        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:/1.txt"));
        List songList = new ArrayList<>();

        List scoreArrayList = new ArrayList<>();
        scoreArrayList = scoreService.list();

        System.out.println(scoreArrayList);
        for (int i = 0; i < scoreArrayList.size(); i++) {
            String str2 = "";

            str2 = scoreArrayList.get(i).getConsumerId() + "," + scoreArrayList.get(i).getSongListId() + "," + scoreArrayList.get(i).getScore();

            System.out.println(str2);
            bufferedWriter.write(str2);
            bufferedWriter.newLine();
        }
        bufferedWriter.close();
        String file = "D:/1.txt";
        DataModel model = new FileDataModel(new File(file));  //基于文件的model,通过文件形式来读入,且此类型所需要读入的数据的格式要求很低,只需要满足每一行是用户id,物品id,用户偏好,且之间用tab或者是逗号隔开即可

        //基于用户的协同过滤算法
        List list2 = new ArrayList<>();
        int[] arr2 = new int[4];

        UserSimilarity user = new EuclideanDistanceSimilarity(model);  //计算欧式距离,欧式距离来定义相似性,用s=1/(1+d)来表示,范围在[0,1]之间,值越大,表明d越小,距离越近,则表示相似性越大
        NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model);
        //指定用户邻居数量

        //构建基于用户的推荐系统
        Recommender r = new GenericUserBasedRecommender(model, neighbor, user);

        //得到所有用户的id集合
        LongPrimitiveIterator iter = model.getUserIDs();

        while (iter.hasNext()) {
            long uid = iter.nextLong();
            List list = r.recommend(uid, RECOMMENDER_NUM_USER);  //获取推荐结果
            //遍历推荐结果
            for (RecommendedItem ritem : list) {
                if (uid == userId) {
                    list2.add((int) ritem.getItemId());
                    System.out.println("歌单"+ritem.getItemId()+"相似度加权:"+ ritem.getValue());
                }
            }
            for (int i = 0; i < list2.size(); i++) {
                arr2[i] = list2.get(i);
            }
        }
        songList = songListService.getRecommendSongList(arr2[0], arr2[1], arr2[2], arr2[3]);

        //基于物品的协同过滤
        ItemSimilarity item = new EuclideanDistanceSimilarity(model);
        List songList2 = new ArrayList<>();
        List list3 = new ArrayList<>();
        int[] arr3 = new int[4];

        Recommender r2 = new GenericItemBasedRecommender(model, item);

        LongPrimitiveIterator iter2 = model.getUserIDs();

        while (iter2.hasNext()) {
            long uid = iter2.nextLong();
            List list = r2.recommend(uid, RECOMMENDER_NUM_ITEM);  //获取推荐结果
            //遍历推荐结果
            for (RecommendedItem ritem : list) {
                if (uid == userId) {
                    list3.add((int) ritem.getItemId());
                    System.out.println("相似度加权:" + ritem.getValue());
                }
            }
        }

        for (int i = 0; i < list3.size(); i++) {
            arr3[i] = list3.get(i);
        }
        songList2 = songListService.getRecommendSongList(arr3[0], arr3[1], arr3[2], arr3[3]);

        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject("hotSongList", hotSongList);//热门歌单
        modelAndView.addObject("goodSongList", goodSongList);//优质歌单
        modelAndView.addObject("songList", songList);//基于用户的协同过滤推荐
        modelAndView.addObject("songList2", songList2);//基于物品的协同过滤推荐

        modelAndView.addObject("s", s);//基于内容的推荐
        modelAndView.setViewName("recommend/recommendShow");

        return modelAndView;
    }
    @RequestMapping("/touristsRecommendList")
    public ModelAndView touristsRecommendList(HttpServletRequest request) throws TasteException, IOException {

        //离线推荐:
        List hotSongList = new ArrayList<>();
        List goodSongList = new ArrayList<>();
        hotSongList = recommend.selectHotList();
        goodSongList = recommend.selectGoodList();

        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject("hotSongList", hotSongList);//热门歌单
        modelAndView.addObject("goodSongList", goodSongList);//优质歌单

        modelAndView.setViewName("recommend/touristsRecommendList");

        return modelAndView;
    }

    private String chuli(List userRList, UserSong userR) {
        Map map1 = new HashMap();

        for (int i = 0; i < userR.getSongListIds().length; ++i) {
            map1.put(userR.getSongListIds()[i], userR.getSongListIds()[i]);
        }

        Map map = new HashMap();

        for (int i = 0; i < userRList.size(); ++i) {
            if ((userRList.get(i)).getCos_th() > 0.0D && (userRList.get(i)).getUserId() != userR.getUserId()) {
                Integer[] j = QJ.getC((userRList.get(i)).getSongListIds(), userR.getSongListIds());

                for (int i1 = 0; i1 < j.length; ++i1) {
                    if (!map1.containsKey(j[i1])) {
                        map.put(j[i1], map.containsKey(j[i1]) ? (Integer) map.get(j[i1]) + 1 : 1);
                    }
                }
            }
        }

        System.out.println("处理之后的map:");
        Iterator var10 = map.keySet().iterator();

        while (var10.hasNext()) {
            Integer key = (Integer) var10.next();
            System.out.println("歌单id=" + key + "--用户所收藏数量=" + map.get(key));
        }

        Map map2 = MapSortUtil.sortByKeyDesc(map);
        System.out.println("按降序" + map2);
        String sqlId = "";

        Integer key;
        for (Iterator var14 = map2.keySet().iterator(); var14.hasNext(); sqlId = sqlId + key + ",") {
            key = (Integer) var14.next();
        }

        sqlId = sqlId.substring(0, sqlId.length() - 1);
        System.out.println("最终拿到的被推荐给当前用户的歌单id--->" + sqlId);
        return sqlId;
    }

    private List jisuan(UserSong userR, List userRS) {
        int[] userErzhihua = new int[10];

        for (int i = 0; i < userR.getSongListIds().length; ++i) {
            userErzhihua[userR.getSongListIds()[i]] = 1;
        }

        int[] erzhihua = new int[10];

        for (int i = 0; i < userRS.size(); ++i) {
            UserSong songlist = userRS.get(i);

            for (int j = 0; j < songlist.getSongListIds().length; ++j) {
                erzhihua[songlist.getSongListIds()[j]] = 1;
            }

            Double compare = compare(erzhihua, userErzhihua);
            songlist.setCos_th(compare);
            userRS.set(i, songlist);
            erzhihua = new int[10];
        }

        return userRS;
    }

    private static Double compare(int[] o1, int[] o2) {
        Double fenzi = 0.0D;

        for (int i = 0; i < o1.length; ++i) {
            fenzi = fenzi + (double) (o1[i] * o2[i]);
        }

        Double fenmu1 = 0.0D;

        for (int i = 0; i < o1.length; ++i) {
            fenmu1 = fenmu1 + (double) (o1[i] * o1[i]);
        }

        fenmu1 = Math.sqrt(fenmu1);
        Double fenmu2 = 0.0D;

        for (int i = 0; i < o2.length; ++i) {
            fenmu2 = fenmu2 + (double) (o2[i] * o2[i]);
        }

        fenmu2 = Math.sqrt(fenmu2);
        return fenzi / (fenmu1 * fenmu2);
    }

}


如有问题联系qq:2818814775

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/969534.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号