ssm 프레임워크 기반 도서 추천 시스템 (하)
43782 단어 연습하다
public interface UserDao {
List listAllUsers();
}
인터페이스 구현 방법: dao층은 @Repository 주석을 사용합니다
@Repository(value = "userDao")
public class UserDaoImpl extends CommonDao implements UserDao {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDaoImpl.class);
@Override
public List listAllUsers() {
LoggerUtil.info(LOGGER,"enter in UserDaoImpl[listAllUsers]");
return getSqlSession().selectList("hahaha.listAllUsers");
}
}
서비스 계층 작성
public interface UserService {
List listAllUsers();
}
인터페이스 구현 방법:
@Service(value = "UserService")
public class UserServiceImpl implements UserService {
@Resource(name = "userDao")
private UserDao userDao;
private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
@Override
public List listAllUsers() {
LoggerUtil.info(LOGGER,"enter in UserServiceImpl[listAllUsers]");
List userDOList=userDao.listAllUsers();
return convertDOSToDTOS(userDOList);
}
/**
* UserDO UserDTO
* @param userDO
* @return
*/
private UserDTO convertToDTO(UserDO userDO)
{
UserDTO userDTO=new UserDTO();
userDTO.setUserId(userDO.getUserId());
userDTO.setUsername(userDO.getUsername());
userDTO.setPassword(userDO.getPassword());
userDTO.setEmail(userDO.getEmail());
userDTO.setGmtCreate(DateUtils.format(userDO.getGmtCreate()));
userDTO.setGmtModified(DateUtils.format(userDO.getGmtModified()));
userDTO.setModifier(userDO.getModifier());
userDTO.setPhoneNumber(userDO.getPhoneNumber());
userDTO.setAge(userDO.getAge());
userDTO.setSex(userDO.getSex());
userDTO.setProfession(userDO.getProfession());
return userDTO;
}
/**
* UserDTO UserDO
* @param userDOList
* @return
*/
private List convertDOSToDTOS(List userDOList)
{
List userDTOList= Lists.newArrayList();
if (!CollectionUtils.isEmpty(userDOList)) {
for (UserDO userDO : userDOList) {
UserDTO userDTO = convertToDTO(userDO);
userDTOList.add(userDTO);
}
}
return userDTOList;
}
}
마지막으로 controller층입니다. urlpattern이/admin/user일 때 이 방법을 실행하고 모델을 전단에 되돌려줍니다.
@Controller
public class AdminController {
private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
@Resource(name = "UserService")
private UserService userService;
/**
*
* @param httpSession
* @param model
* @return
*/
@RequestMapping(value = "/admin/user")
public String listAllUsers(HttpSession httpSession,Model model)
{
BaseResult result=new BaseResult();
try {
LoggerUtil.info(LOGGER, "enter in AdminController[listAllUsers]");
UserDTO userDTO = (UserDTO) httpSession.getAttribute("isLogin");
if (userDTO == null) {
return "redirect:/login";
}
List userDTOList= userService.listAllUsers();
model.addAttribute("userList",userDTOList);
result.setSuccess(true);
return "admin_user";
}catch(BusinessException be){
ExceptionHandler.handleBusinessException(LOGGER,result,be," ");
}catch(Exception e){
ExceptionHandler.handleSystemException(LOGGER,result,e," ");
}
return "error";
}
2. 사용자의 협동 필터 알고리즘 추천 알고리즘 사고방식을 바탕으로 1. borrow표를 훑어보고 각 책과 그에 대응하는 대출된 횟수를 맵에 저장한다.2. 데이터 세척: 한 사용자가 같은 책을 여러 번 빌릴 수 있고 여러 번 점수를 매길 수 있기 때문에 가장 최근의 점수를 선택하여 사용자가 이 책에 대한 최종 점수로 한다.3. 사용자가 자신이 보지 못한 책에 대한 예측 평점을 계산한다. (1) 먼저 이 책을 본 사용자를 찾아낸다.(2) 그리고 현재 사용자와 이들 사용자 간의 유사도(필슨 상관계수를 채택)를 계산하고 유사도와 대응하는 사용자가 이 책에 대한 평점 가중권을 통해 예측 평점을 얻는다.(3) 예측 평점을 최대 무더기에 저장하고 순서대로 세 권을 선택하여 사용자에게 추천한다.4、추천 목록이 3권이 부족하면 단계 1의 맵에서 순서대로 아래로 가져옵니다.구체적인 코드는 다음과 같습니다.
package book.task;
import book.dao.BookDao;
import book.dao.BorrowDao;
import book.dao.RecommendDao;
import book.dao.UserDao;
import book.domain.dataobject.*;
import book.domain.exception.BusinessException;
import book.util.LoggerUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.sf.jsqlparser.statement.select.Join;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
/**
* @author hui zhang
* @date 2018/3/22
*/
@Component
public class MyRecommendation {
private static final Logger LOGGER = LoggerFactory.getLogger(MyRecommendation.class);
@Resource(name = "bookDao")
private BookDao bookDao;
@Resource(name = "userDao")
private UserDao userDao;
@Resource(name = "borrowDao")
private BorrowDao borrowDao;
@Resource(name = "recommendDao")
private RecommendDao recommendDao;
@Resource(name = "transactionTemplate")
private TransactionTemplate transactionTemplate;
/**
*
* 1, ( )
* 2,
* 3,
* 4, ( , )
* 5,
* 6,
*/
public void recommend() {
LoggerUtil.info(LOGGER, "enter in MyRecommendation");
List userDOList = userDao.listAllUsers();
List bookDOList = bookDao.listAllBooks();
List borrowDOList = borrowDao.listAllBorrows();
List recommendDOList = Lists.newArrayList();
//
Map bookCountMap = Maps.newHashMap();
// , .
//
Map hasSeenTheBook=Maps.newHashMap();
recommendDao.deleteBefore(0);
/**
* ,
*/
for (BorrowDO borrowDO : borrowDOList) {
BookDO bookDO = bookDao.queryBookByBookId(borrowDO.getBookId());
UserDO userDO = userDao.queryByUserId(borrowDO.getUserId());
//
if (bookDO == null || userDO == null) {
continue;
}
//TODO - bug
// , “bookName-author”
String key = Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor());
if (bookCountMap.get(key) == null) {
//
bookCountMap.put(key, 1);
// , “userId-bookName-author”,
hasSeenTheBook.put(Joiner.on("-").skipNulls().join(userDO.getUserId(),key),recommendDOList.size());
} else {
//
int count = bookCountMap.get(key);
bookCountMap.put(key, count + 1);
//
if (hasSeenTheBook.get(Joiner.on("-").skipNulls().join(userDO.getUserId(),key))!=null) {
int index=hasSeenTheBook.get(Joiner.on("-").skipNulls().join(userDO.getUserId(),key));
System.out.println("index:"+index);
recommendDOList.get(index).setRate(borrowDO.getGoal());
}
}
RecommendDO recommendDO = new RecommendDO();
recommendDO.setUserId(borrowDO.getUserId());
recommendDO.setBookId(key);
recommendDO.setRate(borrowDO.getGoal());
recommendDOList.add(recommendDO);
}
System.out.println("recommendDOList:"+recommendDOList);
System.out.println("map:" + bookCountMap);
//
Queue> priorityQueue=new PriorityQueue<>((a,b)->(b.getValue().compareTo(a.getValue())));
priorityQueue.addAll(bookCountMap.entrySet());
System.out.println("priorityQueue:"+priorityQueue);
//
Queue<Map.Entry<String,Double>>bookDOQueue=new PriorityQueue<>((a,b)->((b.getValue().compareTo(a.getValue()))));
for (UserDO userDO : userDOList) {
// , ,
priorityQueue.clear();
// , ,
priorityQueue.addAll(bookCountMap.entrySet());
Map<String, Double> bookCompare = Maps.newHashMap();
for (BookDO bookDO : bookDOList) {
//TODO ,
if (neednot(userDO,bookDO,recommendDOList)){
continue;
}
//
List<RecommendDO> SeenTheBook = find(bookDO, recommendDOList);
System.out.println("SeenTheBook:" + SeenTheBook+"bookName:"+bookDO.getBookName());
if (CollectionUtils.isEmpty(SeenTheBook)) {
continue;
}
//recommend
double rate = 0;
double weightSum = 0;
for (RecommendDO recommendDO : SeenTheBook) {
//
double weight = 0;
try {
weight = calUserSimilarity(userDO, recommendDO, recommendDOList);
} catch (BusinessException be) {
continue;
}
System.out.println("weight:" + weight);
//
rate = rate + weight * recommendDO.getRate();
System.out.println(" "+userDO.getUserId()+" "+bookDO.getBookName()+"rate:"+rate);
weightSum = weightSum + weight;
}
if (weightSum!=0) {
//
double score = rate / weightSum;
System.out.println(" " + userDO.getUserId() + " " + bookDO.getBookName() + score);
//
bookCompare.put(Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor()), score);
}
}
bookDOQueue.clear();
bookDOQueue.addAll(bookCompare.entrySet());
System.out.println(" :,userId"+userDO.getUserId()+","+"bookDOQueue:" + bookDOQueue);
//
int count = 0;
//
List<String>recommendList=Lists.newArrayList();
while (!bookDOQueue.isEmpty() && count < 3) {
//
String mix = bookDOQueue.poll().getKey();
// bookName,author
Iterator<String> iterator = Splitter.on("-").split(mix).iterator();
List<String> stringList = Lists.newArrayList();
while (iterator.hasNext()) {
stringList.add(iterator.next());
}
//
pushToDataBase(stringList.get(0), stringList.get(1), userDO.getUserId());
recommendList.add(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)));
count++;
}
System.out.println("the rest:"+count);
//
while (count < 3&&!priorityQueue.isEmpty()) {
Map.Entry<String, Integer> entry = priorityQueue.poll();
System.out.println(entry);
String mix = entry.getKey();
System.out.println(mix);
Iterator<String> iterator = Splitter.on("-").split(mix).iterator();
List<String> stringList = Lists.newArrayList();
while (iterator.hasNext()) {
stringList.add(iterator.next());
}
// ,
if (hotFilter(userDO,stringList.get(0),stringList.get(1),recommendDOList)){
continue;
}
// ,
if (recommendList.contains(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)))){
continue;
}
recommendList.add(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)));
pushToDataBase(stringList.get(0), stringList.get(1), userDO.getUserId());
count++;
}
}
}
/**
*
* @param userDO
* @param s
* @param s1
* @param recommendDOListBase
* @return
*/
private boolean hotFilter(UserDO userDO, String s, String s1, List recommendDOListBase) {
for (RecommendDO recommendDO : recommendDOListBase) {
if (recommendDO.getUserId() == userDO.getUserId() && Joiner.on("-").skipNulls().join(s,s1).equals(recommendDO.getBookId())) {
return true;
}
}
return false;
}
/**
*
* @param userDO
* @param bookDO
* @param recommendDOListBase
* @return
*/
private boolean neednot(UserDO userDO, BookDO bookDO, List recommendDOListBase) {
for (RecommendDO recommendDO : recommendDOListBase) {
if (recommendDO.getUserId() == userDO.getUserId() && Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor()).equals(recommendDO.getBookId())) {
return true;
}
}
return false;
}
/**
*
*
* @param bookName
* @param author
* @param userId
*/
private void pushToDataBase(String bookName, String author, long userId) {
RecommendationDO recommendationDO = new RecommendationDO();
recommendationDO.setUserId(userId);
recommendationDO.setBookName(bookName);
recommendationDO.setAuthor(author);
recommendationDO.setRecommendType(0);
recommendDao.addRecommendation(recommendationDO);
}
/**
* ,
*
* @param bookDO
* @param borrowDOList
* @return
*/
private List<RecommendDO> find(BookDO bookDO, List borrowDOList) {
List<RecommendDO> recommendDOList = Lists.newArrayList();
for (RecommendDO recommendDO : borrowDOList) {
if (recommendDO.getBookId().equals((Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor())))) {
recommendDOList.add(recommendDO);
}
}
return recommendDOList;
}
/**
*
* (a -a )*(b -b ) /(a -a ) (b -b )
* UserDO ,recommendDO
*
* @param userA
* @param userB
* @return
*/
private double calUserSimilarity (UserDO userA, RecommendDO userB, List < RecommendDO > recommendDOListBase){
Map<String, RecommendDO> recommendDORecommendDOMapA = Maps.newHashMap();
Map<String, RecommendDO> recommendDORecommendDOMapB = Maps.newHashMap();
//1, a,b
for (RecommendDO recommendDO : recommendDOListBase) {
if (recommendDO.getUserId() == userA.getUserId()) {
recommendDORecommendDOMapA.put(recommendDO.getBookId(), recommendDO);
} else if (recommendDO.getUserId() == userB.getUserId()) {
recommendDORecommendDOMapB.put(recommendDO.getBookId(), recommendDO);
}
}
System.out.println("recommendA:" + recommendDORecommendDOMapA);
System.out.println("recommendB:"+recommendDORecommendDOMapB);
// a b
if ((recommendDORecommendDOMapA.size() == 0) || (recommendDORecommendDOMapB.size() == 0)) {
throw new BusinessException("a,b ");
}
// a,b
Set<String> recommendDOSet = Sets.intersection(recommendDORecommendDOMapA.keySet(), recommendDORecommendDOMapB.keySet());
if (recommendDOSet.size() == 0) {
throw new BusinessException("a,b ");
}
System.out.println("recommendSet:"+recommendDOSet);
// ab
Iterator<String> iterator = recommendDOSet.iterator();
double averageA = 0;
double averageB = 0;
while (iterator.hasNext()) {
String bookId = iterator.next();
averageA = averageA + recommendDORecommendDOMapA.get(bookId).getRate();
averageB = averageB + recommendDORecommendDOMapB.get(bookId).getRate();
}
averageA = averageA / recommendDOSet.size();
averageB = averageB /recommendDOSet.size();
System.out.println("averageA:"+averageA+"averageB:"+averageB);
iterator = recommendDOSet.iterator();
double molecule = 0;
//
while (iterator.hasNext()) {
String bookId = iterator.next();
molecule = molecule + (recommendDORecommendDOMapA.get(bookId).getRate() - averageA) * (recommendDORecommendDOMapB.get(bookId).getRate() - averageB);
}
// denominator
double denominatorLeft = 0;
iterator = recommendDOSet.iterator();
while (iterator.hasNext()) {
String bookId = iterator.next();
denominatorLeft = denominatorLeft + (recommendDORecommendDOMapA.get(bookId).getRate() - averageA) * (recommendDORecommendDOMapA.get(bookId).getRate() - averageA);
}
double denominatorRight = 0;
iterator = recommendDOSet.iterator();
while (iterator.hasNext()) {
String bookId= iterator.next();
denominatorRight = denominatorRight + (recommendDORecommendDOMapB.get(bookId).getRate() - averageB) * (recommendDORecommendDOMapB.get(bookId).getRate() - averageB);
}
System.out.println("molecule:"+molecule);
return molecule /Math.sqrt( denominatorLeft * denominatorRight);
}
public static void main(String[] args) {
new MyRecommendation().recommend();
}
}
전체 코드는https://github.com/sandman13/book_recommend살펴보다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
브라우저를 통해서만 Apple Music 재생(해당 1)Apple Music의 JavaScript 라이브러리 "Music Kit JS"를 사용하여 브라우저에서 Apple Music을 재생합니다.화면을 완성하는 게 이런 느낌이야.예술 작품과 노래에 대한 정보를 표시할 수도...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.