군침이 싹 도는 코딩

리얼 타임 추천 시스템 API 본문

Python/Flask

리얼 타임 추천 시스템 API

mugoori 2023. 1. 10. 13:18
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)

            # 내 별점정보를 가져와야 나의 맞춤형 추천 가능
            qurey = '''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(qurey,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

# 리얼 타임으로 추천 시스템을 바꿀때에는 쿼리문을 하나 더 추가해줘야한다

이때 주의할점은 커넥션은 한번만 해줘야한다

배치형 추천 시스템에서는 파일을 불어와서 상관계수를 비교했다면

리얼타임 추천 시스템에서는 상관계수를 비교할 데이터를 DB에서 가져와야한다

따라서 상관계수를 뽑을 데이터를 DB에서 가져오는 쿼리문을 작성한 뒤에

그것을 데이터 프레임으로 바꿔주고 피봇테이블을 통해 상관계수를 비교할 수 있게 바꿔줘야한다

그리고 그것을 만들어 두었던 함수안에 변수와 같은 이름으로 저장한다 (movie_correlations)

 

나머지 부분은 배치형 추천 시스템과 동일하므로 이 글을 참고한다

 

추천 시스템 API

class MovieRecommendResource(Resource) : @jwt_required() def get(self) : # 영화 추천 # 1. 클라이언트로부터 데이터를 받아온다 user_id = get_jwt_identity() # 쿼리스트링으로 받아온 데이터는 모두 문자열로 받아온다 co

mugoori.tistory.com