Improved recommendations

This commit is contained in:
Eduard Urbach 2018-03-27 10:13:27 +02:00
parent 98c4316c53
commit 996007f84e

View File

@ -1,6 +1,8 @@
package recommended package recommended
import ( import (
"fmt"
"math"
"net/http" "net/http"
"sort" "sort"
@ -11,7 +13,9 @@ import (
) )
const ( const (
maxRecommendations = 10 maxRecommendations = 10
bestGenreCount = 3
genreBonusCompletedAnimeThreshold = 40
) )
// Anime shows a list of recommended anime. // Anime shows a list of recommended anime.
@ -25,6 +29,41 @@ func Anime(ctx *aero.Context) string {
} }
animeList := viewUser.AnimeList() animeList := viewUser.AnimeList()
completed := animeList.FilterStatus(arn.AnimeListStatusCompleted)
// Genre affinity
genreItems := animeList.Genres()
genreAffinity := map[string]float64{}
bestGenres := []string{}
for genre, animeListItems := range genreItems {
affinity := 0.0
for _, item := range animeListItems {
if item.Status != arn.AnimeListStatusCompleted {
continue
}
if item.Rating.Overall != 0 {
affinity += item.Rating.Overall
} else {
affinity += 5.0
}
}
genreAffinity[genre] = affinity
bestGenres = append(bestGenres, genre)
}
sort.Slice(bestGenres, func(i, j int) bool {
return genreAffinity[bestGenres[i]] > genreAffinity[bestGenres[j]]
})
if len(bestGenres) > bestGenreCount {
bestGenres = bestGenres[:bestGenreCount]
}
fmt.Println(bestGenres)
// Get all anime // Get all anime
var tv []*arn.Anime var tv []*arn.Anime
@ -65,18 +104,32 @@ func Anime(ctx *aero.Context) string {
prequels := anime.Prequels() prequels := anime.Prequels()
for _, prequel := range prequels { for _, prequel := range prequels {
item := animeList.Find(prequel.ID) item := completed.Find(prequel.ID)
// Filter out unimportant prequels // Filter out unimportant prequels
if prequel.Score() < anime.Score()/2 { if prequel.Score() < anime.Score()/2 {
continue continue
} }
if item == nil || item.Status != arn.AnimeListStatusCompleted { if item == nil {
animeAffinity -= 20.0 animeAffinity -= 20.0
} }
} }
// Give favorite genre bonus if we have enough completed anime
if len(completed.Items) >= genreBonusCompletedAnimeThreshold {
bestGenreCount := 0
for _, genre := range anime.Genres {
if arn.Contains(bestGenres, genre) {
bestGenreCount++
}
}
// Use square root to dampen the bonus of additional best genres
animeAffinity += math.Sqrt(float64(bestGenreCount)) * 7.0
}
affinity[anime.ID] = animeAffinity affinity[anime.ID] = animeAffinity
} }