728x90
genre_most_popular.py 실행순서에 따른 코드 분석
(1) import module
from collections import Counter
import fire
from tqdm import tqdm
from arena_util import load_json
from arena_util import write_json
from arena_util import remove_seen
from arena_util import most_popular
(2) main 실행
if __name__ == "__main__":
fire.Fire(GenreMostPopular)
Fire를 통해 GenreMostPopular class를 하나의 객체로 인식해서 사용 가능
(3) run 함수 실행
def run(self, song_meta_fname, train_fname, question_fname):
print("Loading song meta...")
song_meta_json = load_json(song_meta_fname)
print("Loading train file...")
train_data = load_json(train_fname)
print("Loading question file...")
questions = load_json(question_fname)
print("Writing answers...")
answers = self._generate_answers(song_meta_json, train_data, questions) # -> (4)
write_json(answers, "results/results.json") # -> (8)
song_meta, train, question data를 로드하는 load_json함수는 전에서 설명을 했기 때문에 생략
(4) generate_answers 함수
def _generate_answers(self, song_meta_json, train, questions):
song_meta = {int(song["id"]): song for song in song_meta_json}
song_mp_counter, song_mp = most_popular(train, "songs", 200) # -> (5)
tag_mp_counter, tag_mp = most_popular(train, "tags", 100) # -> (5)
song_mp_per_genre = self._song_mp_per_genre(song_meta, song_mp_counter) # -> (6)
# ....뒷부분 (7)
answers = []
return answers
song_meta : key를 song_id value를 해당 song_id에대한 정보로 dictionary생성
song_mp : 상위 200개 songs
tag_mp : 상위 100개 tags
(5) most_popular 함수 실행
def most_popular(playlists, col, topk_count):
c = Counter()
for doc in playlists:
c.update(doc[col])
topk = c.most_common(topk_count)
return c, [k for k, v in topk]
Counter를 통해 playlist를 counter에 update해서 개수를 계속 세어주고 topk_count만큼 상위개수를 뽑아온다
반환은 해당 col마다 개수를 담고있는 counter(c)와 상위 topk_count만큼의 col list[k for k, v in topk]
(6) _song_mp_per_genre 함수 실행
def _song_mp_per_genre(self, song_meta, global_mp):
res = {}
# key는 song_meta에있던 genre, value는 해당 genre에 속한 song_id
# ex) 'GN0900': [0, 2, 16, 22, 26, 28, 56, 88, 98]
for sid, song in song_meta.items():
for genre in song['song_gn_gnr_basket']:
res.setdefault(genre, []).append(sid)
for genre, sids in res.items():
# Before: res {genre : song_id}
# After: res {genre : Counter(song_id : 개수)}
res[genre] = Counter({k: global_mp.get(int(k), 0) for k in sids})
# 가장 많은 상위 200개 song_id만 추출
res[genre] = [k for k, v in res[genre].most_common(200)]
return res
해당 장르에 가장 많이 등장한 song_id 200개 추출
(7) generate_answers 함수 중간부분
for q in tqdm(questions):
genre_counter = Counter()
# question data에서 속한 songs
for sid in q["songs"]:
# 해당 song에대한 장르를 song_meta를 통해서 구하고 counter를 통해서 개수를 세준다
for genre in song_meta[sid]["song_gn_gnr_basket"]:
genre_counter.update({genre: 1})
# 가장 인기있는 장르 1가지
top_genre = genre_counter.most_common(1)
# 가장 인기있는 장르가 존재하는 경우
if len(top_genre) != 0:
# 해당장르에서 가장 많이 등장한 song 추천
cur_songs = song_mp_per_genre[top_genre[0][0]]
# 가장 인기있는 장르가 존재하지 않는 경우
else:
# 가장 많이 등장한 노래 추천
cur_songs = song_mp
answers.append({
"id": q["id"],
# 안본 것 song, tag 추천
"songs": remove_seen(q["songs"], cur_songs)[:100],
"tags": remove_seen(q["tags"], tag_mp)[:10]
})
(8) write.json
write_json(answers, "results/results.json")
결과 작성
출처
728x90
'추천 시스템 이론' 카테고리의 다른 글
Pytorch Recommend system github 작동 순서 (0) | 2021.04.23 |
---|---|
ALS 알고리즘 (1) | 2021.03.07 |
SGD를 사용한 Matrix Factorization 알고리즘 (1) | 2021.01.13 |
카카오 아레나 Melon Playlist Continuation baseline github 분석 - (2) (0) | 2020.10.20 |
카카오 아레나 Melon Playlist Continuation baseline github 분석 - (1) (0) | 2020.10.19 |
댓글