본문 바로가기
NLP

코사인 유사도를 활용한 유사 문서 검색

by 볼록티 2019. 11. 22.
728x90
반응형

저번에 크롤링한 데이터를 그대로 사용하여 코사인 유사도를 구해보도록 하겠습니다.

우선 저번에 사용한 코드 그대로 사용하여 데이터를 수집해와서 전처리까지 동일하게 진행해주었습니다.(전처리에 기자이름을 제거하는 것을 추가하였습니다. 기자 이름때문에 유사성이 전체적으로 높게 측정되기 때문입니다.)

import requests
import re
from bs4 import BeautifulSoup

url="https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1="
category=[100,101,102,103,104] #정치, 경제, 사회, 생활/문화
news_url_list=[]

headline=[]

for i in category:
    home = url+str(i)
    soup = BeautifulSoup(requests.get(home).content, 'html.parser')
    x=len(soup.body.find_all("ul", class_="cluster_list")) # "ul"의 원소는 8개가 있음을 알 수 있습니다.
    ul= soup.body.find_all("ul", class_="cluster_list")
    for j in range(x):
        y=len(ul[j].find_all("li"))
        for k in range(y):
            headline.append((ul[j].find_all("li")[k].a["href"], i)) #(url, i)튜플 형태로 하여 후에 i를 label로 활용합니다.
            
            
contents=[]

for i in headline:
    soup = BeautifulSoup(requests.get(i[0]).content, 'html.parser')
    content=soup.body.find_all("div", class_="_article_body_contents")[0].text
    contents.append((content)) 



from konlpy.tag import Okt
pos_tagger = Okt()

news = [i for i in contents]
pos=[]
for content in contents:
	content = re.sub('.* 기자', "", content)
    tmp = [i[0] for i in pos_tagger.pos(content) if ((i[1]=="Noun")and(len(i[0])>1))]
    pos.append(" ".join(tmp))

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(pos)

-> tfidf matrix까지 구하였습니다.

 

이제 뉴스간의 유사성을 알아보기 위해 코사인유사도를 구해보도록 하겠습니다.

코사인 유사도를 구할 라이브러리를 불러옵니다.

from sklearn.metrics.pairwise import cosine_similarity

 

다음을 사용하여 모든 뉴스 간의 코사인유사도를 구한 행렬을 얻을 수 있습니다.

cosine_similarity(tfidf_matrix, tfidf_matrix)

 

 

하나의 뉴스를 선정하여 이와 가장 유사한 뉴스를 찾는 함수를 작성해 봅니다.

위의 함수를 통해서 특정 뉴스와의 유사도를 출력할 수 있습니다.

consice_similarity(tfidf_matrix[0], tfidf_matrix)

 

numpy의 ndarray형식에서 argsort()함수는 원소를 오름차순으로 인덱스를 리턴해줍니다.

cosine_similarity(tfidf_matrix[0], tfidf_matrix).argsort()

-> 가장 먼저 나오는 인덱스는 자기 자신입니다. 그러므로 나열된 인덱스 중 두번째 원소가 가장 유사한 뉴스라고 생각해볼 수 있습니다. 이 아이디어를 가지고 함수를 만들게 됩니다.

 

def most_similar(idx, matrix, corpus):
    index=(-cosine_similarity(matrix[idx], matrix)[0]).argsort()[1]
    return corpus[index], corpus[idx]

-> idx: 지정하고 싶은 뉴스, matrix: spars매트릭스, corpus: 원본 데이터

 지정한 뉴스, 지정한 뉴스와 가장 유사하다고 평가된 뉴스 두 개가 출력이 됩니다.

 

 

 

 

 

 

 

728x90
반응형

'NLP' 카테고리의 다른 글

구글 검색 뉴스 감성분석  (0) 2019.11.29
IMDB 영화 댓글 크롤링 코드  (2) 2019.11.28
뉴스 기사 분류  (0) 2019.11.22
크롤링 4  (0) 2019.11.21
크롤링 3  (0) 2019.11.21

댓글