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