땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • ㅗ
  • D
  • I
  • 이것이 리눅스다 with Rocky Linux9
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

Backend

[빅데이터 추천] 컨텐츠 기반 필터링 구현해보기

2023. 3. 9. 15:46

테마 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
    'Backend' 카테고리의 다른 글
    • [빅데이터 추천] 협업 필터링 구현해보기(아이템 기반 협업 필터링)
    • 빅데이터 추천 시스템(CBF, CF)에 대해
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바