Compare commits

...

3 commits

View file

@ -54,14 +54,15 @@ class Engine:
} }
if 'gridChange' not in self.state: if 'gridChange' not in self.state:
self.state['gridChange'] = { self.state['gridChange'] = {
'nextClip': {'locked': True, 'value': 4}, 'nextClip': {'locked': False, 'value': 5},
'nextPlaylist': {'locked': False, 'value': 4}, 'nextPlaylist': {'locked': False, 'value': 8},
'staySame': {'locked': False, 'value': 8} 'staySame': {'locked': True, 'value': 3}
} }
if 'userKeywordsWeights' not in self.state: if 'userKeywordsWeights' not in self.state:
self.state['userKeywordsWeights'] = { self.state['userKeywordsWeights'] = {
'themeTags': {'locked': False, 'value': 0.3}, 'themeTags': {'locked': False, 'value': 0.3},
'characterTags': {'locked': False, 'value': 0.7} 'characterTags': {'locked': False, 'value': 0.7},
'random' : {'locked': False, 'value': True}
} }
self.update_keywords() self.update_keywords()
@ -101,12 +102,14 @@ class Engine:
# Update self_playlists to reflect user log history # Update self_playlists to reflect user log history
playlists = self.update_user_playlists(user) playlists = self.update_user_playlists(user)
# Get the user keyword scores for debug view # Get the user keyword scores for debug view
user_keywords = copy.deepcopy(user.get('keywords', {})) user_keywords = copy.deepcopy(user.get('keywords', {}))
theme_tags = {k.lower():v for k,v in user_keywords.items() if not k.isupper()} theme_tags = {k.lower():v for k,v in user_keywords.items() if not k.isupper()}
character_tags = {k:v for k,v in user_keywords.items() if k.isupper()} character_tags = {k:v for k,v in user_keywords.items() if k.isupper()}
top_user_keywords = sorted([(k,v) for (k,v) in theme_tags.items()], key=lambda kv: kv[1])[-5:] top_user_keywords = sorted([(k,v) for (k,v) in theme_tags.items()], key=lambda kv: kv[1])[-10:]
top_user_characters = sorted([(k,v) for (k,v) in character_tags.items()], key=lambda kv: kv[1])[-5:] top_user_characters = sorted([(k,v) for (k,v) in character_tags.items()], key=lambda kv: kv[1])[-10:]
debug_index_output = defaultdict(list)
# If the most recent event is "login," initialize grid videos. # If the most recent event is "login," initialize grid videos.
if user.get('events', [{}])[0].get("event")=="login": if user.get('events', [{}])[0].get("event")=="login":
@ -200,7 +203,6 @@ class Engine:
else: else:
playlist_pos = next_unwatched_indx[0] playlist_pos = next_unwatched_indx[0]
rec_list.append((i, { rec_list.append((i, {
'clips': playlist['clips'], 'clips': playlist['clips'],
'position': playlist_pos, 'position': playlist_pos,
@ -208,6 +210,8 @@ class Engine:
'tags': playlist['tags'] 'tags': playlist['tags']
})) }))
debug_index_output["next_clip"].append((i,playlist['name']))
#staySame pool #staySame pool
for i in stay_same_index: for i in stay_same_index:
@ -216,6 +220,7 @@ class Engine:
next_playlist_index.append(i) next_playlist_index.append(i)
else: else:
rec_list.append((i,{})) rec_list.append((i,{}))
debug_index_output["stay_same"].append(i)
# nextPlaylist pool: randomly select playlists (excluding the playlists from the current grid). # nextPlaylist pool: randomly select playlists (excluding the playlists from the current grid).
vids_exclude = [e.get("playlist") for e in prev_grid_list] vids_exclude = [e.get("playlist") for e in prev_grid_list]
@ -223,6 +228,7 @@ class Engine:
vids_exclude.remove(None) vids_exclude.remove(None)
rec = self.get_recommendations(playlists, user, vids_exclude) rec = self.get_recommendations(playlists, user, vids_exclude)
rec_list += [(i, rec['videos'][i]) for i in next_playlist_index] rec_list += [(i, rec['videos'][i]) for i in next_playlist_index]
debug_index_output["new_playlist"] = [(i, rec['videos'][i]["name"]) for i in next_playlist_index]
rec_list = sorted(rec_list, key=lambda k:k[0]) rec_list = sorted(rec_list, key=lambda k:k[0])
@ -233,10 +239,13 @@ class Engine:
}, },
'videos': videos_, 'videos': videos_,
"_debug": { "_debug": {
"top_user_keywords": top_user_keywords, "top_user_keywords": top_user_keywords, # list of (keyword, score)
"top_user_characters": top_user_characters, "top_user_characters": top_user_characters, # list of (keyword, score)
"top_user_playlists": rec["top_user_playlists"], "top_user_playlists": rec["top_user_playlists"], # list of (playlist name, score)
"top_global_playlists": rec["top_global_playlists"] "top_global_playlists": rec["top_global_playlists"], # list of (playlist name, score)
"stay_same_index": debug_index_output["stay_same"], # list of integers
"next_clip_index": debug_index_output["next_clip"], # list of (integer, playlist name)
"new_playlist_index": debug_index_output["new_playlist"] # list of (integer, playlist name)
} }
} }
@ -253,6 +262,14 @@ class Engine:
if playlist["name"] in vids_exclude: if playlist["name"] in vids_exclude:
playlists.remove(playlist) playlists.remove(playlist)
# Generate random weights if random option is chosen in the dashboard:
if userKeywordsWeights['random']:
themeWeights = random.random()
charWeights = 1-themeWeights
else:
themeWeights = userKeywordsWeights['themeTags']
charWeights = userKeywordsWeights['characterTags']
# For each playlist, compute user keyword score by theme and character tags # For each playlist, compute user keyword score by theme and character tags
user_keywords = copy.deepcopy(user.get('keywords', {})) user_keywords = copy.deepcopy(user.get('keywords', {}))
theme_tags = {k.lower():v for k,v in user_keywords.items() if not k.isupper()} theme_tags = {k.lower():v for k,v in user_keywords.items() if not k.isupper()}
@ -266,23 +283,24 @@ class Engine:
character_tags["VICTORIA OLEGOVNA SKITSKAYA"] = character_tags.get("VIKTORIA OLEGOVNA SKITSKAYA",0) character_tags["VICTORIA OLEGOVNA SKITSKAYA"] = character_tags.get("VIKTORIA OLEGOVNA SKITSKAYA",0)
score = {} score = {}
for playlist in playlists: for playlist in playlists:
score[playlist['name']] = random.random() * 0.001 score[playlist['name']] = random.random() * 0.1
for tag in playlist['tags']: for tag in playlist['tags']:
if tag in theme_tags: if tag in theme_tags:
score[playlist['name']] += theme_tags[tag] * userKeywordsWeights["themeTags"] score[playlist['name']] += theme_tags[tag] * themeWeights
elif tag in character_tags: elif tag in character_tags:
score[playlist['name']] += character_tags[tag] * userKeywordsWeights["characterTags"] score[playlist['name']] += character_tags[tag] * charWeights
# Select highest scoring playlists # Select highest scoring playlists
playlists = sorted( playlists = sorted(
playlists, playlists,
key=lambda playlist: -score[playlist['name']] key=lambda playlist: -score[playlist['name']]
) )
# Record the following for debug view input # Record the following for debug view input
top_user_playlists = [{ top_user_playlists = [(playlist['name'], score[playlist['name']]) for playlist in playlists[:channels['userKeywords']]]
'name': playlist['name'], # top_user_playlists = [{
'tags': playlist['tags'], # 'name': playlist['name'],
'score': score[playlist['name']], # 'tags': playlist['tags'],
} for playlist in playlists[:channels['userKeywords']]] # 'score': score[playlist['name']],
# } for playlist in playlists[:channels['userKeywords']]]
videos = playlists[:channels['userKeywords']] videos = playlists[:channels['userKeywords']]
playlists = playlists[channels['userKeywords']:] playlists = playlists[channels['userKeywords']:]
@ -298,11 +316,12 @@ class Engine:
key=lambda playlist: -score[playlist['name']] key=lambda playlist: -score[playlist['name']]
) )
# Record the following for debug view input # Record the following for debug view input
top_global_playlists = [{ top_global_playlists = [(playlist['name'], score[playlist['name']]) for playlist in playlists[:channels['globalKeywords']]]
'name': playlist['name'], # top_global_playlists = [{
'tags': playlist['tags'], # 'name': playlist['name'],
'score': score[playlist['name']], # 'tags': playlist['tags'],
} for playlist in playlists[:channels['globalKeywords']]] # 'score': score[playlist['name']],
# } for playlist in playlists[:channels['globalKeywords']]]
videos += playlists[:16 - channels['userKeywords']] videos += playlists[:16 - channels['userKeywords']]
# Shuffle playlists (randomize layout) and shift clips (randomize start) # Shuffle playlists (randomize layout) and shift clips (randomize start)