본문 바로가기
Restful API

[Restful API] 실시간으로 추천하는 API 만들기

by coding_su 2023. 1. 10.

📝실시간으로 추천하는 API 만들기

전에 DB에 저장된 정보를 가져와서 작업한 후에 추천하는 API를 만들었는데(https://coding-jisu.tistory.com/194)

이번에는 실시간으로 추천하는 API 만들기를 해보았다

 

구글 코랩에서 작업에서 작업하는 과정을 비주얼 스튜디오 코드에서 진행해주면 된다

커넥션을 열고 전체 영화 별점에 대한 상관계수를 구한 변수와 추천받을 유저의 리뷰정보를 담은 변수를 만들어 추천기능을 만든다

class MovieRecommendRealTimeResource(Resource) :

    @jwt_required()
    def get(self) :

        user_id = get_jwt_identity()

        count = request.args.get('count')
        count = int(count)

        try :
            connection = get_connection()

            # 전체 영화 별점 가져와서 상관계수 구하기
            query = '''select m.title, r.user_id, r.rating
                    from movie m 
                    left join rating r
                    on m.id = r.movie_id;'''

            cursor = connection.cursor(dictionary= True)

            cursor.execute(query, )

            result_list = cursor.fetchall()

            df = pd.DataFrame(data= result_list)
            df = df.pivot_table(index='user_id', columns='title', values='rating')
            movie_correlations = df.corr(min_periods=50)

            # 내 별점 정보를 가져와야 내 맞춤형 추천 가능
            query = '''select m.title, r.rating
                    from rating r
                    join movie m 
                    on r.movie_id = m.id
                    where r.user_id = %s ;'''

            record = (user_id, )

            cursor = connection.cursor(dictionary= True)

            cursor.execute(query, record)

            result_list = cursor.fetchall()

            cursor.close()
            connection.close()

        except Error as e :
            print(e)
            cursor.close()
            connection.close()

            return {"error" : str(e)}, 500

        # 4. DB로부터 가져온 내 별점 정보를 데이터프레임으로 만든다
        my_rating = pd.DataFrame(data= result_list)
        # print(my_rating)

        # 5. 내 별점 정보 기반으로 추천영화 목록을 만든다
        similar_movies_list = pd.DataFrame()

        for i in range( my_rating.shape[0] ) :
            movie_title = my_rating['title'][i]
            similar_movie = movie_correlations[movie_title].dropna().sort_values(ascending= False).to_frame()
            similar_movie.columns = ['correlation']
            similar_movie['weight'] = similar_movie['correlation'] * my_rating['rating'][i]
            similar_movies_list = similar_movies_list.append( similar_movie )
        # print(similar_movies_list)

        # 6. 중복 영화는 제거한다(내가 본 영화 제거)
        drop_index_list = my_rating['title'].to_list()

        for name in drop_index_list :
            if name in similar_movies_list.index :
                similar_movies_list.drop(name, axis=0, inplace= True)

        # 7. 중복 추천된 영화는 weight가 가장 큰 값으로만 남기고 중복 제거한다
        recomm_movie_list = similar_movies_list.groupby('title')['weight'].max().sort_values(ascending= False).head(count)
        # print(recomm_movie_list)

        # 8. 제이슨(json)으로 클라이언트에게 보낸다
        recomm_movie_list = recomm_movie_list.to_frame().reset_index()
        recomm_movie_list = recomm_movie_list.to_dict('records')
        # print(recomm_movie_list)

        return {"result" : "success", "items" : recomm_movie_list, "count" : len(recomm_movie_list)}, 200

댓글