본문 바로가기

빅데이터/추천시스템

Content-based-filtering(컨텐츠기반 필터링) - 추천시스템(4)

앞선 포스팅에서 말했듯이 content-base-Filtering 은 쉽고 정확도가 높은 반면 뻔한 것들이 추천된다는 단점이 있습니다.

 

import pandas as pd
import numpy as np
pd.options.display.max_columns=100
pd.options.display.max_rows=1003
book=pd.read_csv('thelast_final_bool.csv')
book.shape
book

저는 우선 TF-IDF 로구현해보았습니다. TF-IDF란 무엇이냐. 또 TF-IDF 를 이해하기 위해서는 DTM/TDM 을 이해할 필요가 있습니다

 


DTM/TDM (Document Term Matrix)

  • 단어들이 각 문서에 몇번 나왔는지 행렬로 구성

  • 문서 단어 행렬(Document Term Matrix)

    • 행이 document , 열이 term 으로 구성된 matrix

    • 문서별로 각 단어가 나타난 횟수를 정리한 표

    • 컬럼(Feature): 전체 문서에 나오는 모든 단어

    • 행 : 문서

    • 값(value) : 각 단어가 문서에 나온 횟수

  • 단어 문서 행렬(Term Document Matrix)

    • DTM을 전치 시킨 것

    • 컬럼(Feature): 문서

    • 행: 전체 문서에 나오는 모든 단어

    • 값(value) : 각 단어가 문서에 나온 횟수


TF-IDF(Term Frequency - Inverse Document Frequency) 란?

  • TF(단어 빈도, term frequency)는 특정한 단어가 문서 내에 얼마나 자주 등장하는지를 나타내는 값.

    • 이 값이 높을수록 문서에서 중요하다고 생각할 수 있다.

    • 해당 단어가 해당 문서에 몇번 나오는지를 나타내는 지표

    • 하지만 하나의 문서에서 많이 나오지 않고 다른 문서에서 자주 등장하면 단어의 중요도는 낮아진다.

  • DF(문서 빈도, document frequency)

    • 이 값의 역수를 IDF(역문서 빈도, inverse document frequency)라고 한다.

    • 행당 단어가 해당 문서에 몇번 나오는지를 나타내는 지표

  • TF-IDF는 TF와 IDF를 곱한 값

    • 점수가 높은 단어일수록 다른 문서에는 많지 않고 해당 문서에서 자주 등장하는 단어를 의미한다

 

from sklearn.feature_extraction.text import TfidfVectorizer

TfidfVectorizer

【특정 단어가 여러 문서에 동일하게 여러번 노출되면 패널티를 주고 , 그 단어가 한 문서에만 유일하게 노출되면 가산점을 준다】 라는 개념으로 이해하시면 됩니다

 

하이퍼파라미터

  • stop_word :stopword 지정

    • str: "english" - 영문 불용어는 제공됨

    • list: stopword 리스트

  • max_df: 특정 횟수 이상나오는 것은 무시하도록 설정(무시할 횟수/비율 지정)

    • int(횟수), float(비율)

  • min_df: 특정 횟수 이하로 나오는 것은 무시하도록 설정(무시할 횟수/비율 지정)

  • max_features: 최대 token 수

    • 빈도수가 높은 순서대로 정렬 후 지정한 max_features 개수만큼만 사용한다.

  • ngram_range: n_gram 범위 지정

    • n_gram:

    • 튜플 (범위 최소값, 범위 최대값)

    • (1, 2) : 토큰화된 단어를 1개씩 그리고 순서대로 2개씩 묶어서 Feature를 추출

메소드

  • fit(X)

    • 학습

    • 매개변수: 문장을 가진 1차원 배열형태(list, ndarray)

    • Train(훈련) 데이터셋 으로 학습한다. Test 데이터셋은 Train 셋으로 학습한 CountVectorizer를 이용해 변환만 한다.

  • transform(X)

    • DTM 변환

  • fit_transform(X)

    • 학습/변환 한번에 처리


우선 info()를 살펴보겠습니다

TfidfVectorizer 학습을 위해 전처리를 해줍니다. 우리가 사용할 컬럼은 이 알고리즘에서 유효하게 사용되어질 컬럼들을 더해서 만든 'feature' 입니다

book['제목']=book['제목'].str.replace(' ','')

# 컬럼간 더하기 연산을 할 때 값중에 한 개라도 nan 값이 있으면 더해진 값은 무조건 nan으로 반환되는 걸 방지하기 위함
book['tag_sum']=book['tag_sum'].fillna('0') 
book['feature']=book['저자']+' '+book['category_sum']+' '+book['tag_sum']+' '+book['keyword']
book['feature']=book['feature'].str.replace('0',' ')
book

따로 뽑아내면 이런 느낌입니다. 작가, 카테고리들, 키워드들이 들어가 있습니다

book[['feature']]

자 이제 TfidfVectorizer 를 import 하겠습니다

from sklearn.feature_extraction.text import TfidfVectorizer

# min_df를 1로 설정해줌으로써 한번이라도 노출이 된 정보도 다 고려함
# ngram_range : n_gram 범위 지정 연속으로 나오는 단어들의 순서도 고려함
tf=TfidfVectorizer(min_df=1,ngram_range=(1,5))
tfidf_matrix=tf.fit_transform(book['feature'])
tfidf_matrix

다음으로 유사도(관계도)를 살펴보기위해 linear_kernel로 나타내보겠습니다

from sklearn.metrics.pairwise import linear_kernel

cosine_sim = linear_kernel(tfidf_matrix,tfidf_matrix)
cosine_sim

함수로 유사도 순으로 정렬해서 책제목을 반환하게 하기 위해서

책제목을 index로 한 Series를 생성하였습니다

 

함수를 제작해보겠습니다. 

결과를 보겠습니다. 먼저 유명한 추리소설 '용의자X의헌신' 을 input 으로 넣어봤습니다

 

유명 동화 ' 아낌없이주는나무' 를 input 으로 넣어봤습니다 . 비슷한 동화들이 return 되었네요

 

단어들을 살펴보면 동일한 단어들이 많이 눈에 띄네요

 

다음 결과들입니다. 비슷하게들 나온 것 같습니다

우리나라 '김진명' 작가님의 '천년의금서'를 입력하니 대부분 김진명작가님의 다른 소설이 추천되었네요

그 밑에 프랑스 유명작가 '기욤뮈소'님의 '종이여자'를 input 으로 넣으니 그래도 같은작가의 소설 반과 비슷한 느낌의 다른 소설이 추천되었네요

'종이여자' 종이여자에 대한 return 값들을 비교해 보겠습니다

프랑스 소설이 공통 카테고리인 걸 확인할 수 있었습니다

다음에는 CF 중에서도 item-based CF 를 해보겠습니다