import numpy as np
import pandas as pd
books = pd.read_csv('./data/book/books.csv', encoding='ISO-8859-1')
ratings = pd.read_csv('./data/book/ratings.csv', encoding='ISO-8859-1')
book_tags = pd.read_csv('./data/book/book_tags.csv', encoding='ISO-8859-1')
tags = pd.read_csv('./data/book/tags.csv', encoding='ISO-8859-1')
to_read = pd.read_csv('./data/book/to_read.csv')
tags_join_df = pd.merge(book_tags, tags, left_on='tag_id', right_on='tag_id', how='inner')
1) Tfidf
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix = tf.fit_transform(books['authors'])
1) 코사인 유사도
2) 책 제목으로 인덱스 구하기
3) 유사도 값 호출
4) 유사도 결과를 인덱스를 가진 list 형으로 만들기
5) 가장 유사한 책의 인덱스 찾기
6) 작가로 본 유사 책 검색
from sklearn.metrics.pairwise import linear_kernel
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
# 2
title = books['title']
indices = pd.Series(books.index, index=books['title'])
# 3
cosine_sim[indices['The Hobbit']]
# 4
list(enumerate(cosine_sim[indices['The Hobbit']]))
# 5
sim_scores = list(enumerate(cosine_sim[indices['The Hobbit']]))
sim_scores = sorted(sim_scores, key=lambda x : x[1], reverse=True)
# 6
sim_scores = sim_scores[1:11]
book_indices = [i[0] for i in sim_scores]
title.iloc[book_indices]
1) book에 tag 포함
2) tag로 Tfidf
3) 코사인 유사도
4) 책 제목으로 인덱스 구하기
5) 태그 추천시스템 함수
-> 작가보다 조금 더 맞는 결과
# 1
books_with_tags = pd.merge(books, tags_join_df, left_on='book_id', right_on='goodreads_book_id', how='inner')
# 2
tf1 = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix1 = tf1.fit_transform(books_with_tags['tag_name'].head(10000))
# 3
cosine_sim1 = linear_kernel(tfidf_matrix1, tfidf_matrix1)
# 4
titles1 = books['title']
indices1 = pd.Series(books.index, index=books['title'])
# 5
def tags_recommendations(title):
idx = indices1[title]
sim_scores = list(enumerate(cosine_sim1[idx]))
sim_scores = sorted(sim_scores, key=lambda x : x[1], reverse=True)
sim_scores = sim_scores[1:11]
book_indices = [i[0] for i in sim_scores]
return titles1.iloc[book_indices]
1) 임시로 book id 마다 tag를 붙이기
2) books에 합치기
3) 저자이름과 태그를 합치기
4) Tfidf, linear_kernel 수행
5) 책 제목 인덱스
6) 추천 함수
# 1
tmp_df = books_with_tags.groupby('book_id')['tag_name'].apply(' '.join).reset_index()
# 2
books = pd.merge(books, tmp_df, left_on='book_id', right_on='book_id', how='inner')
# 3 authors & tag_name 리스트로 합친 결과를 str로 바꾸는데 ','를 ' '으로 join
books['corpus'] = (pd.Series(books[['authors', 'tag_name']].fillna('').values.tolist()).str.join(' '))
# 4
tf_corpus = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix_corpus = tf_corpus.fit_transform(books['corpus'])
cosine_sim_corpus = linear_kernel(tfidf_matrix_corpus, tfidf_matrix_corpus)
# 5
titles = books['title']
indices = pd.Series(books.index, index=books['title'])
# 6
def corpus_reco(title):
idx = indices[title]
sim_scores = list(enumerate(cosine_sim_corpus[idx]))
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
sim_scores = sim_scores[1:11]
book_indices = [i[0] for i in sim_scores]
return titles.iloc[book_indices]
corpus_reco('Romeo and Juliet')
'''
352 Othello
769 Julius Caesar
124 Hamlet
153 Macbeth
247 A Midsummer Night's Dream
838 The Merchant of Venice
854 Twelfth Night
529 Much Ado About Nothing
713 King Lear
772 The Taming of the Shrew
Name: title, dtype: object
'''
Reference
1) 제로베이스 데이터스쿨 강의자료