테마 1개에 대해서 추천 받기
import pandas as pd
df = pd.read_csv('./방탈출테마정보_서울.csv', encoding='cp949')
# print(df[['지역(대)','지역(소)','매장명','테마명','장르','난이도','시간','오픈일','최소인원','최대인원','메인사진','예약URL','내용']])
# print(df[['내용']])
# df + df 합쳐서 함
'''
<데이터전처리>
- 사용할 컬럼 정리
csv파일에서 필요한것들만 dataframe으로 따로 만들어주자
'''
data = df[['지역(대)','지역(소)','매장명','테마명','장르','난이도','시간','오픈일','최소인원','최대인원','메인사진','예약URL','내용']]
'''
- 평점 전처리
현재 영화평점의 평균평점이 불공정하게 처리되어 있다
그래서 데이터를 제공해준 imdb에서 제안한 weight rating으로 평점을 다시 처리한다
공식을 제공해주고 있어서 새로운 score라는 컬럼을 생성하여 적용한다
m = data['vote_count'].quantile(0.9)
data = data.loc[data['vote_count'] >= m]
c = data['vote_average'].mean()
def weight_rating(x,m=m, c=c):
v = x['vote_count']
r = x['vote_average']
return (v / (v+m) * r) + (m / (v+m) * c)
data['score'] = data.apply(weight_rating, axis=1)
'''
# print(data['장르'][:10])
'''
<콘텐츠 기반 필터링 추천>
- 장르 벡터화
장르를 기준으로 필터링할 경우(즉, 유사한 장르를 추천해주는 경우)
일단 장르들은 띄어쓰기가 구분된 한 문자열로 저장이 되어 있는데 이 문자열을 숫자로 바꿔서 벡터화 시켜야한다
'''
from sklearn.feature_extraction.text import CountVectorizer
counter_vector = CountVectorizer(ngram_range=(1,1))
# counter_vector = CountVectorizer(min_df=0, ngram_range=(1,2))
c_vector_genres = counter_vector.fit_transform(data['장르'])
# 유사도값 추출(코사인 유사도)
# 장르를 기준으로 유사도값을 계산한다
from sklearn.metrics.pairwise import cosine_similarity
# argsort를 이용해서 유사도가 높은 영화들의 index 추출
similarity_genre = cosine_similarity(c_vector_genres,c_vector_genres).argsort()[:,::-1]
# 장르기반의 유사도를 기준으로 테마를 추천해준다
# top=10을 없애는게 맞음. 10개 모두 내가 관심목록으로해서 제외시키면 return이 0개기 때문에 아쉬운 상황을 방지하고자 top을 없애고 나중에 뿌릴 때 몇개 뿌릴지 설정
def recommend_theme_list(df, theme_title):
# 특정 테마정보 뽑아내기
target_theme_index = df[df['테마명'] == theme_title].index.values
# 타켓테마와 비슷한 코사인 유사도값
sim_index = similarity_genre[target_theme_index, :].reshape(-1)
# 본인은 제외시킴
sim_index = sim_index[sim_index != target_theme_index]
# 추천결과 새로운 df생성, 평균평점(score)으로 정렬
# result = df.iloc[sim_index].sort_values('score', ascending=False)[:10]
result = df.iloc[sim_index]
return result
print(recommend_theme_list(data, theme_title='러브 클리닉')[['테마명','장르']])
테마 여러개에 대해서 추천받기
가상으로 테마를 하나 만들어서 가상의 테마를 기준으로 추천하기
만약 공포 스릴러 공포 공포 공포 이렇게 되면 공포에 대한 가중치 적용이 됨
import pandas as pd
df = pd.read_csv('./방탈출테마정보_서울.csv', encoding='cp949')
'''
input
1
551
589
'''
theme = list(int(input()) for _ in range(3))
data = df[['지역(대)','지역(소)','매장명','테마명','장르','난이도','시간','오픈일','최소인원','최대인원','메인사진','예약URL','내용']]
target_theme_genre = []
for i in range(len(theme)):
print(data.loc[theme[i]]['장르'])
target_theme_genre.append(data.loc[theme[i]]['장르'])
select_theme_genre = ' '.join(target_theme_genre)
print(target_theme_genre)
print(' '.join(target_theme_genre))
print(theme)
data.loc[data.shape[0]] = ['','','','standard',select_theme_genre,'','','','','','','','']
from sklearn.feature_extraction.text import CountVectorizer
counter_vector = CountVectorizer(ngram_range=(1,1))
c_vector_genres = counter_vector.fit_transform(data['장르'])
# 유사도값 추출(코사인 유사도)
# 장르를 기준으로 유사도값을 계산한다
from sklearn.metrics.pairwise import cosine_similarity
# argsort를 이용해서 유사도가 높은 영화들의 index 추출
similarity_genre = cosine_similarity(c_vector_genres,c_vector_genres).argsort()[:,::-1]
# 장르기반의 유사도를 기준으로 영화를 추천해준다
# top=10을 없애는게 맞음. 10개 모두 내가 관심목록으로해서 제외시키면 return이 0개기 때문에 아쉬운 상황을 방지하고자 top을 없애고 나중에 뿌릴 때 몇개 뿌릴지 설정
def recommend_theme_list(df, theme_title,top=50):
# 특정 테마정보 뽑아내기
target_theme_index = df[df['테마명'] == theme_title].index.values
# 타켓테마와 비슷한 코사인 유사도값
sim_index = similarity_genre[target_theme_index, :top].reshape(-1)
# 본인은 제외시킴
for seq in theme:
sim_index = sim_index[sim_index != seq]
sim_index = sim_index[sim_index != target_theme_index]
# 추천결과 새로운 df생성, 평균평점(score)으로 정렬
result = df.iloc[sim_index]
return result
print(recommend_theme_list(data, theme_title='standard')[['테마명','장르']])
'Backend' 카테고리의 다른 글
[빅데이터 추천] 협업 필터링 구현해보기(아이템 기반 협업 필터링) (0) | 2023.03.09 |
---|---|
빅데이터 추천 시스템(CBF, CF)에 대해 (0) | 2023.02.20 |