[교보문고 베스트셀러 분석 / 추천시스템] 3. 베스트셀러 분석
import pandas as pd
import numpy as np
import nltk
from konlpy.tag import Okt
# 그래프
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
# matplotlib 그래프 한글폰트 깨질 때 대처(Mac & Window)
import matplotlib
from matplotlib import font_manager, rc
import platform
if platform.system() == 'Windows':
# 윈도우인 경우
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/HMFMMUEX.ttc").get_name()
rc('font', family=font_name)
else:
# Mac 인 경우
rc('font', family='AppleGothic')
# 그래프에서 마이너스 기호가 표시되도록 하는 설정
matplotlib.rcParams['axes.unicode_minus'] = False
# 카운터 모듈
from collections import Counter
import warnings
warnings.filterwarnings('ignore')
EDA
카테고리별 리뷰 수
plt.figure(figsize=(35, 10))
bar=sns.barplot(data=df_count,x='category',y='review_num')
bar.set_title('Reviwe number by category', fontsize=18)
bar.set_xlabel('Category', fontdict={'size':16})
bar.set_ylabel('Count', fontdict={'size':16})
for p in bar.patches: # annotation
bar.annotate("%.0f" % p.get_height(), (p.get_x() + p.get_width() / 2., p.get_height()-20), ha = 'center', size = 15)
plt.xticks(fontsize=15, rotation=20) # rotation xticks 기울이기
plt.show()
약 18만 건의 총 리뷰를 도서 카테고리에 따라 분류한 것이다. x축의 카테고리의 경우 길이를 맞추기 위래 rotation 옵션을 넣었다. 지난 번에 언급한 것과 같이 크롤링 과정에서 경제 분야가 빠진 점이 아쉽다.
소설이 가장 많은 27587건의 리뷰수를 기록하였으며 시/에세이, 인문이 뒤를 이었다. 보통 판매량이 많은 베스트셀러의 경우 리뷰 또한 많았다.
어린이(초등), 중고등 참고서 등의 학생을 대상으로 하는 카테고리에서 의외로 리뷰가 많이 나타났다. klover 회원 데이터가 없어 명확히 알 수는 없지만 주로 유아부터 중고등학생까지의 자녀를 둔 학부모가 회원 리뷰를 많이 작성한 것으로 나타났다. 주관적인 판단에 의하면 klover의 회원 분포에도 30대~50대 사이의 여성 회원이 많을 것으로 예상된다. 내부 데이터를 구할 수 있다면 좀 더 유의미한 분석을 할 수 있을 것이다.
리뷰가 가장 많은 도서
plt.figure(figsize=(35, 10))
bar=sns.barplot(data=df_total.head(10),x='total',y='title')
bar.set_title('Reviwe number by category', fontsize=18)
bar.set_xlabel('Category', fontdict={'size':16})
bar.set_ylabel('Count', fontdict={'size':16})
for p in bar.patches:
x, y, width, height = p.get_bbox().bounds
bar.text(width*1.01, y+height/2, "%.0f"%(width), va='center',size=20)
plt.xticks(fontsize=15, rotation=20)
plt.yticks(fontsize=20)
plt.box(False)
plt.show()
전체 도서 중에서 리뷰가 많은 순서로 상위 10개 항목에 대해 시각화한 도표이다. 항목의 길이가 길기 때문에 가로 barplot 형태로 나타내었다.
일본소설인 나미야 잡화점의 기적이 가장 많은 리뷰를 가진 도서로 나타났다. 나미야 잡화점의 기적은 필자가 꽤 오랜 전의 군대에서 읽었을 정도로 출간되지 오래된 책이지만 타겟 데이터가 베스트셀러인 만큼 오래도록 사랑받은 책일수록 많은 수의 리뷰가 축적되어 있었다. 대체로 위의 도서들은 모두 해당 카테고리에서 필독 도서로 추천받는 책인 것을 알 수 있다.
카테고리 별 키워드 분석
다음은 베스트셀러 카테고리 별로 키워드를 시각화한다. 해당 키워드의 경우 자체적으로 태깅한 것이 아니라 교보문고의 '키워드픽'이라는 태그를 그대로 크롤링한 것이며 교보문고 웹 페이지에서 볼 수 있듯 이는 추천시스템에 활용되기도 한다.
df_kc = df[['keyword','category']] # kc : keyword, category
df_kc = df_kc.drop_duplicates().reset_index(drop=True)
df_kc.dropna(inplace=True)
df_kc.value_counts('category')
keyword_list = df_novel.keyword.values.tolist()
## 카테고리 별로 barplot, wc 자동화
df_novel =df_kc[df_kc['category']=='소설'] # 카테고리명만 변경하기
keyword_list = df_novel.keyword.values.tolist()
for i in range(len(keyword_list)):
if type(keyword_list[i]) != str:
keyword_list[i] = str(keyword_list[i])
# 수집한 글들을 한 문장으로 합치기
keyword_text = ''
for each_line in keyword_list[:]:
keyword_text = keyword_text + each_line
keyword_text = keyword_text.split(' ')
keyword_counter =Counter(keyword_text)
keyword_counter.most_common(100)
# 카테고리별로 불용어 사전 별도 지정 (예시 : 소설)
stop_words = ['.',' ', '\n', 'nan','소설','한국','문학','작가','작품','집']
keyword_text = [word for word in keyword_text if not word in stop_words] #불용어 제거
keyword_counter = Counter(keyword_text)
rank=keyword_counter.most_common(15)
data = pd.DataFrame.from_dict(dict(rank),orient='index')
plt.figure(figsize=(35, 10))
bar=sns.barplot(data=data,x=data.index,y=data[0])
bar.set_title('Keyword Pick by category', fontsize=18)
bar.set_xlabel('Category', fontdict={'size':16})
bar.set_ylabel('Keyword', fontdict={'size':16})
plt.xticks(fontsize=30, rotation=20)
plt.show()
# wordcloud
wordcloud = WordCloud(font_path='c:/Windows/Fonts/malgun.ttf', # 윈도우:'c:/Windows/Fonts/malgun.ttf'
relative_scaling = 0.4,
#stopwords=STOPWORDS,
background_color='white',
width=1500, height=500).generate_from_frequencies(dict(keyword_counter))
plt.figure(figsize=(40,40))
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
소설
소설 카테고리의 키워드를 상위 15개로 나타낸 그래프이다.
'사랑'이 가장 많은 키워드로 나타났다. 해당 키워드는 로맨스 소설 뿐만 아니라 감동적인 내용의 소설에 주로 태깅되어 빈출되었다. 다음으로는 영화원작소설이 뒤를 이었다. 대체로 소설의 경우 영화나 드라마화 된 이후에 다시 판매량이 오르는 경우가 많다. 뒤의 SF, 반전 등 하위 장르와 연관되어 주로 대중의 관심이 원작으로 이미 친숙한 작품을 소설로 읽어 보는 경향이 있음을 알 수 있다.
나머지 키워드는 비슷한 갯수를 보였으며 주로 인기있는 하위 장르들로 분석된다. 소설 장르의 경우 코로나 시기의 상관없이 항상 비슷한 형태의 특성을 가지므로 특정 몇몇 도서를 제외하면 트렌드와 상관없이 해당 경향이 유지되는 것으로 판단된다.
다음으로는 좀 더 코로나 시대의 특성을 반영할 수 있는 카테고리로 해보겠다.
여행
여행 카테고리의 키워드 분석이다. 해당 프로젝트는 22년 3월 경의 베스트셀러를 대상으로 하였으므로 코로나가 한참 절정에 다다른 시기의 데이터이다. 따라서 현재의 엔데믹 상황과는 키워드에서 차이를 보일 것이다.
보통 여행 분야에서는 해외의 배낭여행을 위한 가이드북이나 여행에세이가 베스트셀러를 차지한다. 하지만 코로나 세태를 반영한 결과로 주로 국내 여행에 대한 키워드가 빈출되었다. 그나마 국내 여행 중 자유롭던 제주도부터 강원도까지 국내 여행지에 대한 수요가 많아졌음을 알 수있다. 국내 여행의 경우 단순히 블로그에서 후기를 찾는 것을 넘어 가이드 북을 이용해 본격적인 국내 여행을 하는 것으로 트렌드가 바뀐 것을 알 수있다.
요리
코로나 시기에 실내에서 할 수 있는 취미를 찾으면서 홈 베이킹에 대한 관심이 높아졌다. 이전에는 주로 레시피에 관한 것이었다면 최근의 트렌드인 홈 베이킹 및 디저트 만들기가 빈출되었다.
리뷰 분석
앞서 베스트셀러 각각에 대한 리뷰 데이터 또한 수집하였다. klover 독자 리뷰의 경우 아주 짧은 한 문장부터 자세한 리뷰까지 모두 수집하여 약 18만 개의 데이터 셋을 구축하였다.
리뷰 데이터의 경우 raw data의 특성이 중요한데 해당 프로젝트에서 살펴본 바로는 대체로 짧은 서평이 대다수였다. 또한 앞서 언급한 것처럼 자녀를 위한 도서를 구입하거나 유저가 직접 읽고 나서 자녀, 혹은 지인에게 추천할만한 도서인지에 대해 작성한 리뷰가 많았다.
content_list = df.comment.values.tolist()
# 수집한 글들을 한 문장으로 합치기
content_text = ''
for each_line in content_list[:2000]:
content_text = content_text + each_line + '\n'
# 형태소 분석기를 통해 명사만 추출하는 함수
def tokenizer_konlpy(text):
okt=Okt()
return [word for word in okt.nouns(text)]
noun_token = tokenizer_konlpy(content_text)
ko = nltk.Text(tokens_ko)
ko = nltk.Text(noun_token)
ko.vocab().most_common(100) # 가장 많이 나온 단어 100개
stop_words = ['.',' ', '\n','\n ', 'nan','소설','대한','보고','정말','대해','책','것','수','이','내','때','나','요','더','알','꼭','그','저','제','번','위','해','다른','또']
noun_token = [each_word for each_word in noun_token
if each_word not in stop_words]
ko = nltk.Text(noun_token)
ko.vocab().most_common(50)
import matplotlib.pyplot as plt
import seaborn as sns
import graphviz # graphviz 설치 필요
from sklearn.tree import export_graphviz
plt.figure(figsize=(15,6))
ko.plot(30)
plt.show()
주로 '마음', '공감','위로','불안'과 같은 감성적인 키워드가 압도적으로 빈출되었다. 위의 소설 카테고리에 대한 분석에 이어 코로나시대에 정서적인 공감에 대한 욕구와 COVID BLUE를 해소할 수 있는 키워드인 것으로 생각된다.
프로젝트 과정에서 새롭게 알게 된 것은 주로 자녀를 대상으로 하거나 자녀에게 추천할 수 있는 책들에 대한 수요가 높다는 점이었다. 키워드 분석 결과 뿐만 아니라 실제로 리뷰를 직접 살펴보면 대체로 아동과 중고등학생 대상 도서에서 관련 리뷰가 많았다. 코로나 시기에 학생들의 수업 공백으로 인한 학업 부진을 해소하기 위해 직접 자녀 교육을 챙기는 경향이 두드러졌다고 볼 수 있다.
마지막으로는 지인에게 추천할 수 있는 책인지 평가하는 리뷰가 많았다. '선물','구입' 등의 키워드에서 해당 리뷰들을 찾아볼 수 있다. 해당 도서에서 어떤 부분이 좋았고 주변 사람에게 추천할 수 있을 만큼인지에 대한 내용이다. 필자 또한 지인들에게 내가 읽은 책을 추천하는 걸 즐기는 편이다. 책 선물이 좀 까다롭기는 다른 사람에게 추천해줄 수 있는 책들은 대게 직접 재구매해서 새책을 선물하는 편이다. 따라서 리뷰 분석 결과 베스트셀러의 경우에는 해당 도서의 재구매율 또한 높을 것으로 생각된다.