컨텐츠기반 추천시스템
우리가 유튜브로 영상을 클릭하면 해당 영상과 비슷한 영상들이 오른쪽에 쭉나열된다.
이 알고리즘을 사용한 건 아니지만 TF-IDF를 통해 제목만가지고 비슷하게 한번 흉내내보자.
먼저 필요한 패키지를 불러옵니다.
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
- TF-IDF를 사용해야하기떄문에 sklearn 안에 있는 패키지를 불러오고
- TF-IDF 값을 기준으로 코사인 유사도를 통해 가장 유사한 제목을 찾아주기떄문에 cosine_similarity를 사용합니다.
그 다음 db 파일에 접근해서 데이터프레임으로 만듭니다.
전에 했던 거 연습해볼겸..
2021/01/04 - [Data Science/SQL] - [SQL] Python 에서 SQL을 다루는 방법.
import sqlite3
dbpath = "thumbnail.db"
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
썸네일 데이터 베이스는 제가 실제로 크롤링해서 채워넣은 데이터이고 썸네일 프로젝트를 할 떄 사용했던 데이터입니다.
아무튼 이 데이터 베이스에 접근해서 데이터프레임으로 바꿔줍니다.
df = pd.read_sql_query("SELECT * FROM thumbnail", conn)
data = df[["title"]]
그리고 지금은 제목만 사용할 것 이기 떄문에 제목열만 따로 데이터프레임으로 만들어줍니다.
TF-IDF를 여기서 간략하게 설명하지면
원래는 문장의 빈도수를 측정하여 중요도를 판단했다
그러나 { 오늘 , 내일 , 어떻게 , 했다 } 등 중요하진 않지만
자주쓰이는 단어들이 빈도수를 기반으로 측정하면 중요단어로 인식한다.
그래서 위와 같이 전체문서에 많이 포함되는 단어들에게 일종에 패널티를 줘서
진짜 중요한 단어들을 뽑아내는 알고리즘 이라고 보면 된다.
어려워 보이지만 사용방법은 아주 간단하다.
tfidf = TfidfVectorizer(stop_words='english')
객체를 만들고 stop_words를 통해 불용어를 제거한다.
'korean'도 될지 모르겠지만 아마 안될것 같다 ㅋㅋ.
그래서 영어 불용어를 제거하고 데이터를 집어넣기만하면 된다.
tfidf_matrix = tfidf.fit_transform(data['title'])
print(tfidf_matrix.shape)
shpae 을 찍어보면
(1752, 8095) 이다.
8095가 어디서 나온것인가!!
8095는 1752개의 모든 제목을 각각 띄어쓰기로 단어를 분리했을 떄 나오는 총 단어(중복포함)가 8095개 라는 것이다.
쉽게 생각하면 8095개의 단어들이 모여 1752개의 문장이 된거라고 보면 된다.
이렇게 쭉늘어진 행렬이라고 보면된다.
cosine_matrix = cosine_similarity(tfidf_matrix, tfidf_matrix)
cosine_matrix.shape
여기서 코사인유사도로 행렬과 행렬을 넣어주어 서로의 유사도를 계산한다.
* 코사인 유사도는 얼마나 유사한 방향의 벡터를 가지는지의 정도라고 보면됩니다.
여기서 하양대각선은 같은 데이터이기 떄문에 코사인 유사도가 1로 동일한 것을 볼 수 있다.
이제 유사도 까지 계산이 끝났다. 이걸 이제 사용자가 볼 수 있도록 매핑하고 상위10개만 뽑아보자.
# movie title와 id를 매핑할 dictionary를 생성해줍니다.
title2idx = {}
for i, c in enumerate(data['title']):
title2idx[i] = c
# id와 movie title를 매핑할 dictionary를 생성해줍니다.
idx2title = {}
for i, c in title2idx.items():
idx2title[c] = i
첫 번째는
제목을 key로 인덱스를 value 로 받는 dict를 만들고
두 번째는
인덱스를 key로 제목을 value 로 받는 dict를 만드는 코드이다.
dx = idx2title['김경재 박근혜 구하기 삼성 출연금 8천억 노무현이 해먹었다']
sim_scores = [(i, c) for i, c in enumerate(cosine_matrix[idx]) if i != idx] # 자기 자신을 제외한 영화들의 유사도 및 인덱스를 추출
sim_scores = sorted(sim_scores, key = lambda x: x[1], reverse=True) # 유사도가 높은 순서대로 정렬
sim_scores[0:10] # 상위 10개의 인덱스와 유사도를 추출
여기서 제목을 넣어주게 되면 해당 값에 대한 유사도를 가지는 상위10개의 인덱스를 추출한다.
(정치와는 무관합니다. 그냥 1번째 행일뿐)
sim_scores = [(title2idx[i], score) for i, score in sim_scores[0:10]]
sim_scores
이제 인덱스를 다시 제목으로 바꿔주게되면 가장 유사한 상위10개의 제목들을 볼 수 있다.
끝
'Machine learning > NLP' 카테고리의 다른 글
[NLP]. Transformer : Structure - part1 (0) | 2021.08.19 |
---|---|
[NLP] Sequence to Sequence(시퀀스 투 시퀀스) 코드 (0) | 2021.08.19 |
[NLP] Sequence to Sequence (시퀀스 투 시퀀스), Attention(어텐션) 개념 (0) | 2021.08.18 |
[NLP] 수능 영어지문을 풀어주는 인공지능 (WMD) (0) | 2021.01.30 |
[NLP] Word Encoding & Embedding (0) | 2021.01.13 |