1. 코사인 유사도 분석
class MovieListSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = ('pk', 'words',)
@api_view(['GET'])
def similar_movie(request, movie_pk):
movies = get_list_or_404(Movie)
serializer = MovieListSerializer(movies, many=True)
idx = []
for i in range(len(serializer.data)):
if movie_pk == serializer.data[i]['pk']:
idx.append(i)
break
xMovie = [data.get('words') for data in serializer.data]
result = recommend_movies_names(xMovie, idx, serializer)
final_movie = [get_object_or_404(Movie, pk=i) for i in result]
final_serializer = UserChoiceSimilarMovieSerializer(final_movie, many=True)
return Response(final_serializer.data)
# 추천 알고리즘
def recommend_movies_names(xMovie, idx, movies):
# 불용어 제거
countVec = CountVectorizer(max_features=10000, stop_words='english')
# 영화 키워드 벡터라이징
dataVectors = countVec.fit_transform(xMovie).toarray()
# 코사인 유사도
similarity = cosine_similarity(dataVectors)
# 유사도 내림차순 5개 영화의 인덱스
idx_collection = []
for i in idx:
distances = similarity[i]
listofMovies = sorted(list(enumerate(distances)), reverse=True, key=lambda x:x[1])[1:7]
idx_collection.extend(listofMovies)
# 인덱스를 pk로 바꾸기
pk_collection = []
for idx in idx_collection:
pk_collection.append(movies.data[idx[0]]['pk'])
return pk_collection
2. 편집거리 알고리즘
편집 거리 알고리즘이란, 두 문자열의 유사도를 판단하는 알고리즘이다. 유사도를 판단하는 기준은, 어떠한 문자열을 삽입,삭제,변경을 몇 번이나 해서 바꿀수 있는지를 계산하여 그 최소값을 구해, 그 값을 유사도 판단의 척도로 다룬다.
프로젝트 무플리에서 편집거리 알고리즘은 어떤 영화를 검색했을 때, 그 영화와 제목을 비교하여 가장 가까운 상위 5개의 영화를 출력해주는 데 쓰였다.
from jellyfish import jaro_winkler_similarity
@api_view(['GET'])
def search_movie(request, movie_name):
movies = get_list_or_404(Movie)
serializer = MovieSearchSerializer(movies, many=True)
serializer = serach(serializer.data, movie_name)
return Response(serializer[:5])
# 편집거리 알고리즘
def serach(lst, keyword):
fetch_data = []
for data in lst:
tmp = {'pk': 0, 'title': '', 'poster_path':'', 'similarity':''}
tmp['pk'] = data['pk']; tmp['title'] = data['title']; tmp['poster_path'] = data['poster_path']
tmp['similarity'] = jaro_winkler_similarity(keyword, data['title'])
fetch_data.append(tmp)
fetch_data.sort(key=lambda x : -x['similarity'])
return fetch_data
search 함수에는 영화들의 리스트와 유저가 검색한 영화 한 개가 인자로 들어간다. 그리고 영화의 pk, 제목, 포스터 정보, 유사도를 tmp 딕셔너리에 담는다. 그리고 각 영화 데이터를 담아주고 similiary의 경우 import해 놓은 편집거리 알고리즘 함수에 담에 계산한 후 담는다. lamda함수를 사용해 similarity가 '높은' 순으로 담고, 유저에게 최종적으로 index 0~4까지 다섯 개의 영화를 return해준다.
'Programming > Projects' 카테고리의 다른 글
[회고]SSAFY 7기 특화 프로젝트(빅데이터-추천)를 마치며 (0) | 2022.10.14 |
---|
댓글