어제 작업에 이어서 오늘은 모델서빙/ 그리고 무한스크롤 기능을 계속해서 다듬었다.
일단 어제 무한스크롤 을 백엔드에서 보내주는 작업은 성공하였으나, 어떻게 보내줄까 였는데 고민끝에 로직을 완성하였다!
@login_required
@csrf_exempt
def ajax_method(request):
if request.method == 'POST':
category = request.POST.get('category')
print(category)
global count
count += 1
for i in str(count):
if i == i:
food_data = Food.objects.all().order_by('-staravg')
test = food_data[count*10:count*10+10]
test = serializers.serialize('json',test)
return HttpResponse(test,content_type="text/json-comment-filtered")
return HttpResponse(test, content_type="text/json-comment-filtered")
우선 현재 카테고리 부분은 구현진행중이다. count 를 전역변수로 두고 요청이 들어올때마다 count +1 씩한다. 첫번째는 기본적으로 1:10까지 게시물이 있으니, 스크롤을 감지하면 post 요청을 보내고, count 변수가 +1 되고 for 문을 통해 카운트가 1이면 10~20, 2면 20~30 까지의 게시물을 가지고오게 로직을 구현하였다. 우선 성공이긴 한데 아주 조금씩 에러가 있는 부분이 있어 수정이 필요할 것 같다.
또한 이렇게하면 하나의 페이지에서만 기능이 작동하는데 이것을 html 에서 value 값을 조정해 js에서 받아온 value 값으로 백엔드에서 다시 값을 조정해서 리턴시켜주는 방식으로 내일 작업을 이어서 할 예정이다!
def recommand(request):
userid = request.user.id
print(userid)
rating = pd.read_csv('user_rating.csv')
store = pd.read_csv('store_info.csv')
# movieId를 기준으로 ratings 와 movies 를 결합함
store_ratings = pd.merge(rating, store, on='store')
# user별로 영화에 부여한 rating 값을 볼 수 있도록 pivot table 사용
title_user = store_ratings.pivot_table('rating', index='userid', columns='store')
# 평점을 부여안한 영화는 그냥 0이라고 부여
title_user = title_user.fillna(0)
# 유저 1~610 번과 유저 1~610 번 간의 코사인 유사도를 구함
user_based_collab = cosine_similarity(title_user, title_user)
# 위는 그냥 numpy 행렬이니까, 이를 데이터프레임으로 변환
user_based_collab = pd.DataFrame(user_based_collab, index=title_user.index, columns=title_user.index)
# 1번 유저와 가장 비슷한 266번 유저를 뽑고,
user = user_based_collab[userid].sort_values(ascending=False)[:10].index[1]
# 266번 유저가 좋아했던 영화를 평점 내림차순으로 출력
recommand_store = title_user.query(f"userid == {user}").sort_values(ascending=False, by=user, axis=1)
recommand_list = recommand_store.columns.tolist()[:10]
store_list = []
for i in recommand_list:
store = Food.objects.get(store=i)
store_list.append(store)
# pandas table to list
# 만약 해당 유저가 아직 보지 않은 영화에 대해서, 평점을 예측하고자 한다면?
# (어떤 유저와 비슷한 정도 * 그 유저가 영화에 대해 부여한 평점) 을 더해서 (유저와 비슷한 정도의 합)으로 나눠보면 됨!
# index_list 는 비슷한 유저의 id 값 리스트 / weight_list 는 비슷한 유저와의 유사도 리스트
user_index_list = user_based_collab[userid].sort_values(ascending=False)[:10].index.tolist()
user_weight_list = user_based_collab[userid].sort_values(ascending=False)[:10].tolist()
# 1번 유저가 다크나이트를 보고 어떤 평점을 부여할지 예측
store = '남양수산'
weighted_sum = []
weighted_user = []
for i in range(1, 10):
# 해당 영화를 보고 평점을 부여한 사람들의 유사도와 평점만 추가 (즉, 0이 아닌 경우에만 계산에 활용)
if int(title_user[store][user_index_list[i]]) is not 0:
# 평점 * 유사도 추가
weighted_sum.append(title_user[store][user_index_list[i]] * user_weight_list[i])
# 유사도 추가
weighted_user.append(user_weight_list[i])
# 총 평점*유사도 / 총 유사도를 토대로 평점 예측
result = sum(weighted_sum)/sum(weighted_user)
모델을 서빙하는 코드이다. 데이터는 팀원들이 직접 코드를 통해서 만들었다.
데이터 프레임을 출력하는 부분에서 조금 어렵긴 했었지만, tolist() 를 통해서 잘 출력할 수 있었다.
오늘도 사이트의 많은 부분이 완성된 것 같다. 내일 그리고 월요일까지 시간이 있지만, 이번에는 완벽하게 작업을 완료하고 싶어서 아직 갈길이 먼 것 같다!
내일도 화이팅.