사용자가 업로드한 네이버 블로그를 기반으로 책을 추천해주는 웹 서비스
2022년 8월 20일 ~ 2022년 8월 22일
요즘 네이버 주간 블로그 챌린지가 유행이다. 지정된 기간에 꾸준히 블로그를 쓰면 참여자 전원에게 포인트를 지급한다는 파격적인 마케팅 전략 때문일까. 사람들은 자신의 일상을 소박하게 혹은 거창하게 글로 써내리기 시작했다. 나는 이런 현상이 흥미로웠다. 사람들이 자신의 일상을 블로그에 공개한다는 것은 한 개인의 취향과 관심사가 데이터로 고스란히 남는다는 뜻이기 때문이다. 나의 주요 관심사는 책이다. 자의 반 타의 반으로 개발 서적을 많이 읽지만, 내가 가장 좋아하는 분야는 소설이나 에세이다. 그래서 여느 때와 다름없이 동네 도서관에 가서 책을 고르고 있는데 문득 이런 생각이 들었다. “네이버 블로그로 사람들의 취향을 분석해서 그에 맞는 도서를 추천해주면 어떨까?” 그대로 나는 도서관을 뛰쳐나와 노트북을 켰다.
처음엔 온라인 서점 대신 도서관 장서 목록 데이터를 활용하여 사용자에게 도서관에 있는 책을 추천해주고 싶었다. 하지만 도서관의 종류가 너무 많았고, 그렇다고 어느 특정 도서관만 선택하여 도서를 추천해주면 추천이 유용한 사용자의 범위가 좁았다. 그래서 추천 대상이 될 도서는 yes24에서 각 카테고리 별 신간 도서 정보를 크롤링하여 수집했다. 수집한 데이터는 정제 과정을 거친 뒤 저장을 해뒀다.
수집한 데이터는 책 제목, 책 저자, yes24 페이지 링크, 책 카테고리, 책 이미지, 책 소개 (Konlpy Okt로 명사만 추출한 Token 목록)이다. 여기서 책 소개를 명사만 추출한 이유는 네이버 블로그에서 명사로 된 키워드만 추출하여 책 소개와 코사인 유사도를 계산하기 위함이다.
네이버 블로그 데이터는 실시간으로 크롤링되기 때문에 따로 물리적인 저장소에 넣어두지 않았다. 또한 네이버 블로그는 블로그마다 적용된 테마가 달라서 프론트 구조가 매번 달라 크롤링하기 까다로웠다. 그래서 모바일 버전으로 웹 페이지를 전환하여 어느 정도 html 구조를 통일하고 동적 크롤링을 진행했다.
블로그 글을 최신순으로 10개만 크롤링하여 한글만 남기고 innerTexts 라는 리스트에 담아 반환한다.
키워드 추출 알고리즘은 ‘KR-WordRank’ 알고리즘을 사용했다. 실시간으로 크롤링하고 이후 추천이 진행되는 로직이기 때문에 결과 도출 시간을 줄이기 위해선 토크나이저 과정 없이 진행하고 싶었기 때문이다. KR-WordRank는 토크나이저를 사용하지 않고 키워드를 추출할 수 있다.
KR-WordRank, 토크나이저를 이용하지 않는 한국어 키워드 추출기
하지만 네이버 게시글 수가 너무 적으면 키워드가 추출하지 않는 상황이 발생한다. 이럴 땐 블로그에서 명사만 추출해도 어느 정도 키워드를 잡을 수 있을 거라 생각했다. 단, mecab나 khaiii 등과 같은 토크나이저로 명사를 추출하기엔 블로그 데이터 특성상 맞춤법과 띄어쓰기가 지켜지지 않았기 때문에 soynlp와 okt 형태소 분석기를 사용하여 명사만 추출했다.
GitHub - lovit/soynlp: 한국어 자연어처리를 위한 파이썬 라이브러리입니다. 단어 추출/ 토크나이저 / 품사판별/ 전처리의 기능을 제공합니다.
이제 책 소개에서 추출한 명사와 블로그 키워드를 비교하여 유사도를 계산한다. 책 소개는 TF-IDF로 벡터화를 진행했다. 어차피 명사끼리 비교하기 때문에 단어의 빈도만 고려해도 어느 정도 만족스러운 결과가 나올 것 같았다.
tfidf = TfidfVectorizer()
data = [bookinfo[key]["bookToken"] for key in bookinfo.keys()]
data.append(keywords)
tfidf_matrix = tfidf.fit_transform(data)
cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
title_to_index = dict(zip(data, [n for n in range(len(data))]))
result = get_recommendations(keywords, title_to_index, list(bookinfo.keys()), cosine_sim)
우선 각 도서의 책 소개를 data 변수에 넣었다. 이때 책 소개는 앞에서 Okt 형태소 분석기로 명사만 추출된 상태이다. 다음으로 블로그에서 추출한 키워드를 data에 추가해준다. 이때 추출한 키워드는 키워드를 공백 단위로 이어붙인 문자열이다. 처음엔 키워드를 분리하여 data에 추가해줬다. 예를 들어 [소망, 사람, 마음] 이라는 키워드가 블로그에서 추출되었다면, 각 키워드와 유사한 도서를 찾았다. 이렇게 진행했을 때 문제점은 중복된 도서가 많이 추출되었고 이를 처리하기 위한 로직이 별도로 필요했다. 어차피 키워드는 서로 연관성이 있는 단어들이 추출되기 때문에 한 문장으로 묶어서 코사인 유사도를 계산해도 될 것 같았다.