Skip to content

Commit

Permalink
fix repeated test
Browse files Browse the repository at this point in the history
  • Loading branch information
brash-ram committed Dec 14, 2023
1 parent 85b97c2 commit cf59dc7
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 52 deletions.
24 changes: 21 additions & 3 deletions src/main/java/com/brash/data/entity/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import lombok.experimental.Accessors;
import org.hibernate.Hibernate;

import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.*;

/**
* Элемент системы совместной фильтрации
Expand Down Expand Up @@ -35,6 +33,26 @@ public class Item implements Comparable<Item>, HavingMarks {
@ToString.Exclude
private SortedSet<Mark> marks = new TreeSet<>();

@Transient
private volatile List<Mark> notGeneratedMarks;

@Transient
private final Object lock = new Object();

public List<Mark> getNotGeneratedMarks() {
if (notGeneratedMarks == null) {
synchronized (lock) {
if (notGeneratedMarks == null) {
notGeneratedMarks = marks.stream()
.filter(mark -> !mark.getIsGenerated())
.toList();
}
}

}
return notGeneratedMarks;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/brash/data/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.experimental.Accessors;
import org.hibernate.Hibernate;

import java.util.List;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
Expand Down Expand Up @@ -34,6 +35,26 @@ public class User implements HavingMarks {
@ToString.Exclude
private SortedSet<Mark> marks = new TreeSet<>();

@Transient
private volatile List<Mark> notGeneratedMarks;

@Transient
private final Object lock = new Object();

public List<Mark> getNotGeneratedMarks() {
if (notGeneratedMarks == null) {
synchronized (lock) {
if (notGeneratedMarks == null) {
notGeneratedMarks = marks.stream()
.filter(mark -> !mark.getIsGenerated())
.toList();
}
}

}
return notGeneratedMarks;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/com/brash/filter/impl/FilterModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.brash.filter.ItemToItemRecommendation;
import com.brash.filter.ItemToItemSimilarity;
import com.brash.filter.data.*;
import com.brash.util.Utils;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -242,15 +243,30 @@ private Map<Item, List<Mark>> getUserAndItemForRecommendationMark(Set<Item> item
Set<Item> allUserItems = user.getMarks().stream()
.map(Mark::getItem).collect(Collectors.toSet());
Set<Item> itemsWithoutUserMark = Sets.difference(items, allUserItems);
Set<Item> userItemsWithGeneratedMark = user.getMarks().stream()

List<Mark> generatedMarks = user.getMarks().stream()
.filter(Mark::getIsGenerated)
.toList();

Set<Item> userItemsWithGeneratedMark = generatedMarks.stream()
.map(Mark::getItem).collect(Collectors.toSet());

userItemsWithGeneratedMark.addAll(itemsWithoutUserMark);
for (Item item : userItemsWithGeneratedMark) {
Mark mark = null;
try {
mark = Utils.getMarkFromUser(generatedMarks, user);
} catch (Exception ignored) {
mark = new Mark().setItem(item).setUser(user).setIsGenerated(true);
}

if (generatingMarksForItem.containsKey(item)) {
generatingMarksForItem.get(item).add(new Mark().setItem(item).setUser(user).setIsGenerated(true));
generatingMarksForItem.get(item).add(mark);
} else {
generatingMarksForItem.put(item, new ArrayList<>(List.of(new Mark().setItem(item).setUser(user).setIsGenerated(true))));
generatingMarksForItem.put(
item,
new ArrayList<>(List.of(mark))
);
}
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.brash.filter.ItemToItemSimilarity;
import com.brash.filter.data.*;
import com.brash.util.ItemUtils;
import com.brash.util.Utils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -178,9 +179,7 @@ private void calculatePreference(List<FuzzySet> fuzzySets) {
private List<FuzzySet> getFuzzySets(List<HavingMarks> items) {
List<FuzzySet> fuzzySet = new ArrayList<>();
for (HavingMarks item : items) {
List<Mark> notGeneratedMarks = item.getMarks().stream()
.filter(mark1 -> !mark1.getIsGenerated())
.toList();
List<Mark> notGeneratedMarks = Utils.getNotGeneratedMarks(item.getMarks());
List<FuzzySetItem> fuzzySetItems = new ArrayList<>();
for (Mark mark : notGeneratedMarks) {
double averageMark = getAverageMarkFromUserOrItem(mark, item);
Expand Down
81 changes: 60 additions & 21 deletions src/main/java/com/brash/filter/impl/RecommendationGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public List<Mark> generateAllRecommendation(
for (Map.Entry<Item, List<SimpleSimilarItems>> entry : itemNeighbours.neighbours().entrySet()) {
Item currentItem = entry.getKey();
List<Mark> marksForGeneratingWithItem = generatingMarks.get(currentItem);

if (marksForGeneratingWithItem == null)
continue;

numberLatch += marksForGeneratingWithItem.size();
}

Expand All @@ -79,7 +83,7 @@ public List<Mark> generateAllRecommendation(
User currentUser = mark.getUser();
List<SimpleSimilarItems> neighboursWithMark = neighbours.stream()
.filter(item ->
getOtherItem(item, currentItem).getMarks().stream()
getOtherItem(item, currentItem).getNotGeneratedMarks().stream()
.map(Mark::getUser)
.toList()
.contains(currentUser)
Expand Down Expand Up @@ -108,7 +112,7 @@ public List<Mark> generateAllRecommendation(
} else {
List<SimpleSimilarItems> neighboursWithoutMark = neighbours.stream()
.filter(item ->
!getOtherItem(item, currentItem).getMarks().stream()
!getOtherItem(item, currentItem).getNotGeneratedMarks().stream()
.map(Mark::getUser)
.toList()
.contains(currentUser)
Expand Down Expand Up @@ -151,18 +155,23 @@ private void generateMarkOnSparseData(
) throws Exception {
Item currentItem = mark.getItem();
User currentUser = mark.getUser();
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getMarks()));
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getNotGeneratedMarks()));
double top = 0.0;
double bottom = 0.0;
for (SimpleSimilarItems item : neighboursWithMark) {
if (Thread.currentThread().isInterrupted()) {
return;
}
Mark neighboringMark = getMarkFromUser(new ArrayList<>(getOtherItem(item, currentItem).getMarks()), currentUser);
Mark userMark = getMarkFromUser(
new ArrayList<>(getOtherItem(item, currentItem).getNotGeneratedMarks()),
currentUser
);

double averageMarkValueNeighboringItem = getAverageMark(new ArrayList<>(neighboringMark.getItem().getMarks()));
double averageMarkValueNeighboringItem = getAverageMark(
new ArrayList<>(userMark.getItem().getNotGeneratedMarks())
);

top += item.similarValue() * (neighboringMark.getMark() - averageMarkValueNeighboringItem);
top += item.similarValue() * (userMark.getMark() - averageMarkValueNeighboringItem);
bottom += Math.abs(item.similarValue());
}

Expand All @@ -173,7 +182,7 @@ private void generateMarkOnSparseData(
Mark neighboringMark;
try {
neighboringMark = getMarkFromSimilarUser(
new ArrayList<>(getOtherItem(item, currentItem).getMarks()),
new ArrayList<>(getOtherItem(item, currentItem).getNotGeneratedMarks()),
similarUsers,
currentUser
);
Expand All @@ -183,11 +192,19 @@ private void generateMarkOnSparseData(
continue;
}

SimpleSimilarUsers similarUser = getSimilarUsers(similarUsers.neighbours().get(currentUser), currentUser, neighboringMark.getUser());
SimpleSimilarUsers similarUser = getSimilarUsers(
similarUsers.neighbours().get(currentUser),
currentUser,
neighboringMark.getUser()
);

double averageMarkValueNeighboringItem = getAverageMark(new ArrayList<>(neighboringMark.getItem().getMarks()));
double averageMarkValueNeighboringItem = getAverageMark(
new ArrayList<>(neighboringMark.getItem().getNotGeneratedMarks())
);

top += similarUser.similarValue() * item.similarValue() *
(neighboringMark.getMark() - averageMarkValueNeighboringItem);

top += similarUser.similarValue() * item.similarValue() * (neighboringMark.getMark() - averageMarkValueNeighboringItem);
bottom += similarUser.similarValue() * item.similarValue();
}

Expand All @@ -208,10 +225,14 @@ private void generateMarkOnSparseData(
* @param similarUsers Соседи пользователей
* @throws Exception Ошибка отсутствия ожидаемой оценки пользователя
*/
private void generateMarkOnVagueSet(Mark mark, List<SimpleSimilarItems> neighbours, UserNeighbours similarUsers) throws Exception {
private void generateMarkOnVagueSet(
Mark mark,
List<SimpleSimilarItems> neighbours,
UserNeighbours similarUsers
) throws Exception {
Item currentItem = mark.getItem();
User currentUser = mark.getUser();
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getMarks()));
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getNotGeneratedMarks()));
double top = 0.0;
double bottom = 0.0;
for (SimpleSimilarItems item : neighbours) {
Expand All @@ -221,7 +242,7 @@ private void generateMarkOnVagueSet(Mark mark, List<SimpleSimilarItems> neighbou
Mark neighboringMark;
try {
neighboringMark = getMarkFromSimilarUser(
new ArrayList<>(getOtherItem(item, currentItem).getMarks()),
new ArrayList<>(getOtherItem(item, currentItem).getNotGeneratedMarks()),
similarUsers,
currentUser
);
Expand All @@ -231,11 +252,19 @@ private void generateMarkOnVagueSet(Mark mark, List<SimpleSimilarItems> neighbou
continue;
}

SimpleSimilarUsers similarUser = getSimilarUsers(similarUsers.neighbours().get(currentUser), currentUser, neighboringMark.getUser());
SimpleSimilarUsers similarUser = getSimilarUsers(
similarUsers.neighbours().get(currentUser),
currentUser,
neighboringMark.getUser()
);

double averageMarkValueNeighboringItem = getAverageMark(
new ArrayList<>(neighboringMark.getItem().getNotGeneratedMarks())
);

double averageMarkValueNeighboringItem = getAverageMark(new ArrayList<>(neighboringMark.getItem().getMarks()));
top += similarUser.similarValue() * item.similarValue() *
(neighboringMark.getMark() - averageMarkValueNeighboringItem);

top += similarUser.similarValue() * item.similarValue() * (neighboringMark.getMark() - averageMarkValueNeighboringItem);
bottom += similarUser.similarValue() * item.similarValue();
}
if (top == 0.0 || bottom == 0.0)
Expand All @@ -254,19 +283,29 @@ private void generateMarkOnVagueSet(Mark mark, List<SimpleSimilarItems> neighbou
* @param neighbours Соседи элемента
* @throws Exception Ошибка отсутствия ожидаемой оценки пользователя
*/
private void generateMarkOnMeanCentering(Mark mark, List<SimpleSimilarItems> neighbours) throws Exception {
private void generateMarkOnMeanCentering(
Mark mark,
List<SimpleSimilarItems> neighbours
) throws Exception {
Item currentItem = mark.getItem();
User currentUser = mark.getUser();
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getMarks()));
double averageMarkValueCurrentItem = getAverageMark(new ArrayList<>(currentItem.getNotGeneratedMarks()));
double top = 0.0;
double bottom = 0.0;
for (SimpleSimilarItems item : neighbours) {
if (Thread.currentThread().isInterrupted()) {
return;
}
Mark neighboringMark = getMarkFromUser(new ArrayList<>(getOtherItem(item, currentItem).getMarks()), currentUser);
double averageMarkValueNeighboringItem = getAverageMark(new ArrayList<>(neighboringMark.getItem().getMarks()));
top += item.similarValue() * (neighboringMark.getMark() - averageMarkValueNeighboringItem);
Mark userMark = getMarkFromUser(
new ArrayList<>(getOtherItem(item, currentItem).getNotGeneratedMarks()),
currentUser
);

double averageMarkValueNeighboringItem = getAverageMark(
new ArrayList<>(userMark.getItem().getNotGeneratedMarks())
);

top += item.similarValue() * (userMark.getMark() - averageMarkValueNeighboringItem);
bottom += Math.abs(item.similarValue());
}
if (top == 0.0 || bottom == 0.0)
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/com/brash/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.SortedSet;

/**
* Класс вспомогательных функций для генерации оценок
Expand Down Expand Up @@ -147,14 +148,36 @@ public static double getAverageMark(List<Mark> markForSameItem) {
public static double getAverageMarkFromUserOrItem(Mark mark, HavingMarks type) {
List<Mark> marks;
if (type instanceof Item) {
marks = new ArrayList<>(mark.getUser().getMarks());
marks = new ArrayList<>(getNotGeneratedMarks(mark.getUser().getMarks()));
} else {
marks = new ArrayList<>(mark.getItem().getMarks());
marks = new ArrayList<>(getNotGeneratedMarks(mark.getItem().getMarks()));
}

return getAverageMark(marks);
}

/**
* Получить только не сгенерированные оценки
* @param marks Оценки
* @return Список не сгенерированных оценок
*/
public static List<Mark> getNotGeneratedMarks(List<Mark> marks) {
return marks.stream()
.filter(mark -> !mark.getIsGenerated())
.toList();
}

/**
* Получить только не сгенерированные оценки
* @param marks Оценки
* @return Список не сгенерированных оценок
*/
public static List<Mark> getNotGeneratedMarks(SortedSet<Mark> marks) {
return marks.stream()
.filter(mark -> !mark.getIsGenerated())
.toList();
}

/**
* Отсортировать список пар сходства пользователей
* @param neighbours Пары сходства пользователей
Expand Down
Loading

0 comments on commit cf59dc7

Please sign in to comment.