코사인 유사도 이용 영화 추천 프로그램¶
from bs4 import BeautifulSoup
import pandas as pd
from tqdm import tqdm_notebook
import nltk
import re
from urllib.request import urlopen
영화 추천 프로그램을 만들기 위해 먼저, 네이버영화를 통해 영화정보를 크롤링 합니다. 그러기위해 필요한 도구들을 불러오고 크롤링를 진행합니다. import해오는 도구들은 크롤링을 익히신 분들이라면 익히 아실거라 생각하고 진행하겠습니다. :)
domain='https://movie.naver.com'
story=[]
title=[]
genre=[]
for i in tqdm_notebook(range (1,11)):
url="https://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20191201&page="+str(i)
html = urlopen(url)
soup = BeautifulSoup(html,"html.parser")
titles=soup.find_all('div',class_='tit5')
hype=[]
href=[]
try:
for each in titles:
hype=each.find_all('a')
for link in hype:
href.append(link['href'])
for j in tqdm_notebook(range(len(href))):
domain='https://movie.naver.com'
domain=domain+href[j]
html=urlopen(domain)
soup=BeautifulSoup(html,"html.parser")
story.append(soup.find('p',class_="con_tx").get_text())
title_tag=soup.find('h3',class_='h_movie')
title.append(title_tag.find('a').get_text())
genre_tag=soup.find('p')
genre.append(genre_tag.find('a').get_text())
except:
pass
#스토리 정규화 처리
import re
for i in tqdm_notebook(range(len(story))):
story[i] = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》“”’]','',story[i] )
story[i] = re.sub('\r\xa0','',story[i] )
저는 네이버 영화 평 랭킹을 평점순으로 10페이지까지만 불러오도록 하겠습니다. 하고나서 스토리에 의미없이 들어간 문자들 또한 빼주었습니다. tqdm_notebook으로 진행상황을 확인 하였을 때 중간중간 원활히 크롤링이 되지 않는 것이 보이는데 크롤링 파트가 아니니 그냥 넘어가겠습니다.나중에 이유 찾아서 글 추가로 올리도록 하겠습니다. :)
title[0]
크롤링이 잘 된 것을 확인합니다.(여러분은 그냥 title 전체를 출력해서 확인하세요~)
Nmovie=pd.DataFrame(data={'제목':title,'줄거리':story,'장르':genre})
크롤링해온 정보들을 하나의 데이터프레임 형태로 만들어 둡니다. 사실 꼭 해야하는 작업은 아니지만 보기 좋잖아요..
Nmovie.head()
데이터 프레임 확인을 한 번 해줍니다. 그리고 나서 코사인 유사도를 이용하기 위해 모두 합쳐 줍니다! 그렇게 되면 장르와 제목도 줄거리 외에 들어가기 때문에 조금 더 유사도를 판단하기 좋겠죠. 또한 장르, 혹은 스토리 등에 곱하기로 비중을 높일 수도 있습니다. 그렇게 하면 같은 장르의 영화들의 유사도가 더 높게 나오겠죠.
Nmovie['합침'] = (Nmovie['제목']) + Nmovie['줄거리'] + (Nmovie['장르'])
Nmovie['합침'][0]
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(stop_words='english')
Nmovie['합침'] = Nmovie['합침'].fillna('')
이제 sklearn을 이용하여 TF-IDF 방식으로 단어의 가중치를 조정한 벡터를 만들어 줍니다.
tfidf_matrix = tfidf.fit_transform(movie)
# overview에 대해서 tf-idf 수행
print(tfidf_matrix.shape)
#코사인유사도
from sklearn.metrics.pairwise import linear_kernel
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
마찬가지로 sklearn을 이용하여 코사인 유사도를 구해줍니다. 코사인 유사도는 내적공간의 두 벡터간 각도의 코사인값을 이용하여 측정된 벡터간의 유사한 정도를 의미합니다. 그렇게 하기 위해 벡터를 만들어 준 것이죠.
indices = pd.Series(Nmovie.index, index=Nmovie['제목']).drop_duplicates()
print(indices.head())
#영화의 타이틀과 인덱스를 가진 테이블을 만듬
#영화 타이틀을 입력하면 인덱스를 리턴하려고 만듬
영화의 타이틀을 입력하면 인덱스를 리턴하는 영화의 타이틀과 인덱스를 가진 테이블을 만듭니다.
def get_recomm(title, cosine_sim=cosine_sim):
choice = []
# 선택한 영화의 타이틀로부터 해당되는 인덱스를 받아옵니다. 이제 선택한 영화를 가지고 연산할 수 있습니다.
idx = indices[title]
# 모든 영화에 대해서 해당 영화와의 유사도를 구합니다.
sim_scores = list(enumerate(cosine_sim[idx]))
# 유사도에 따라 영화들을 정렬합니다.
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
# 가장 유사한 10개의 영화를 받아옵니다.
sim_scores = sim_scores[1:11]
# 가장 유사한 10개의 영화의 인덱스를 받아옵니다.
movie_indices = [i[0] for i in sim_scores]
for i in range(10):
choice.append(Nmovie['제목'][movie_indices[i]])
# 가장 유사한 10개의 영화의 제목을 리턴합니다.
print('***영화 추천 순위***')
for i in range(10):
print(str(i+1) + '순위 : ' + choice[i])
마지막으로 함수를 구성하여 원하는 값이 출력되도록 하겠습니다.
get_recomm('토이 스토리')
결과가 나왔습니다. ㅎㅎ 스토리의 줄거리로 문자만 가지고 유사도를 측정하여 추천한 것이니 신뢰도가 그리 높은 프로그램은 아니지만, 결과를 보면 나름? 의미있는 값을 가지는 듯 합니다!! :)
'데이터분석 및 프로젝트' 카테고리의 다른 글
수열을 통해 마코프 체인의 단서를 얻어보자 :) (0) | 2020.01.15 |
---|---|
머신러닝을 이용해 데이터분석에 필요한 기초지식을 습득해보자 :) (0) | 2020.01.15 |
위도 경도 값을 이용하여 거리를 구하고 그래프를 그려보자 :) (0) | 2020.01.15 |
LZW 알고리즘과 허프만 부호화 방법을 서로 비교하여 분석해보자. (0) | 2020.01.08 |
기사를 크롤링하여 워드클라우드를 만들어보자. (0) | 2020.01.08 |