군침이 싹 도는 코딩

추천 시스템 API 본문

Python/Flask

추천 시스템 API

mugoori 2023. 1. 10. 13:13
class MovieRecommendResource(Resource) :

    @jwt_required()
    def get(self) : # 영화 추천



        # 1. 클라이언트로부터 데이터를 받아온다
        user_id = get_jwt_identity()

        # 쿼리스트링으로 받아온 데이터는 모두 문자열로 받아온다
        count = request.args.get('count')
        count = int(count) 

        # 2. 추천을 위한 상관계수 데이터프레임을 읽어온다
        movie_correlations = pd.read_csv('data/movie_correlations.csv', index_col= 'title')

        # 3. 이 유저의 별점 정보를 가져온다
        try :
            connection = get_connection()

            query = '''select m.title, r.rating 
                    from rating r
                    join movie m  
                    on r.movie_id = m.id
                    where 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)

        # 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'] = my_rating['rating'][i] * similar_movie['correlation']
            similar_movies_list = similar_movies_list.append( similar_movie )

        # 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) 

        # 8. JSON 으로 클라이언트에 보내야 한다
        recomm_movie_list = recomm_movie_list.to_frame()
        recomm_movie_list = recomm_movie_list[recomm_movie_list['weight'] > 0]
        recomm_movie_list = recomm_movie_list.reset_index()
        recomm_movie_list = recomm_movie_list.to_dict('records')




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