-
뉴스데이터를 이용한 문서유사도 확인Data Analysis 2021. 3. 5. 23:46반응형
오늘 날짜부터 -n일차 까지 다음뉴스의 데이터를 긁어 오는 작업으로 시작합니다.
날짜를 거꾸로 수집을 합니다.
오늘로부터 며칠 전까지 이런식으로
다음 랭킹뉴스에서 50개까지 url을 긁어온 뒤
다시 for문을 이용해서 url을 접속해서 content를 긁어서 저장합니다.
이 함수의 역할은 여기까지입니다.
import requests from bs4 import BeautifulSoup import time import pandas as pd from datetime import datetime def daum(dates): # 다음뉴스 헤드라인 긁어오기 files = pd.DataFrame() for date in dates: http=[] print(date,'', 'Daum 접속 중') httz = 'https://media.daum.net/ranking/popular/?regDate={}'.format(date) res = requests.get(httz) soup = BeautifulSoup(res.content, 'html.parser') body = soup.select('#mArticle > div.rank_news > ul.list_news2') body = body[0].find_all('a') for i in range(len(body)): t = body[i].get('href') http.append(t) # 중복제거 http = list(set(http)) for i in range(len(http)): res = requests.get(http[i]) soup = BeautifulSoup(res.content, 'html.parser') body = soup.select('.article_view')[0] files = files.append(pd.DataFrame({ 'date':date, 'title': soup.find('div', attrs={'class': 'head_view'}).h3.text, 'content': " ".join(p.get_text() for p in body.find_all('p')), 'link': http[i] }, index=[i])) time.sleep(15) # 텍스트파일에 댓글 저장하기 files.to_csv('다음뉴스종합.csv',index=False,encoding='utf-8') print('파일 저장 완료!')
# 현재로 부터 며칠 전까지 수집할 것인지 확인 days = 1 dates = [int(datetime.today().strftime('%Y%m%d')) - i for i in range(days)] daum(dates)
데이터 수집 끝
뉴스 content의 내용을 tfidf를 이용하여 유사도를 분석합니다.
tfidf를 모르시면 한번 확인하시길 바랍니다.
이후 코드입니다.
원래는 뉴스데이터 원본을 바로 Tf-idf를 이용하고, 바로 코사인유사도를 이용하여 분석하였습니다.
하지만 조금 변경해서 명사추출로 먼저 데이터를 정제한 후에 모델에 입력합니다.
그 이후에 Tf-idf -> 코사인유사도로 문서간의 유사도를 분석합니다.
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import linear_kernel from ckonlpy.tag import Twitter #dataframe에 null값이 있는 경우 공백을 넣어 null값 제거 class TFIDF: def __init__(self,okky_data,word_dictionary): self.okky_data = okky_data self.word_dictionary = word_dictionary self.okky_data['noun_content'] = self.noun_extraction(self.okky_data['content'], self.word_dictionary) # 전처리작업 (명사추출) def noun_extraction(self,text2,word_dictionary): t = Twitter() t.add_dictionary(word_dictionary, 'Noun') tokens = [] for i in range(len(text2)): tokens_ko = '' noun = t.nouns(text2[i]) for n in noun: tokens_ko = tokens_ko + ' ' + n # 공백삭제 tokens_ko = tokens_ko[1:] tokens.append(tokens_ko) return tokens # Null 제거 함수 def avoid_null(self,data, header): data[header] = data[header].fillna('') return data[header] # Content의 tf-idf를 이용하여 유사도 확인 def fit_tfidf(self): #content 데이터의 내용을 null 없이 가져옴 self.okky_data['noun_content'] = self.avoid_null(self.okky_data, 'noun_content') #tf-idf계산 후 출력 tfidfVectorizer = TfidfVectorizer() self.tfidf_metrix_of_tit = tfidfVectorizer.fit_transform(self.okky_data['noun_content']) return self.tfidf_metrix_of_tit #입력되는 train의 질문과 질문 데이터셋의 코사인유사도 값 중 상위 50개 질문목록을 가져오는 함수 def top10_indices(self,data, q_num): #입력된 데이터의 코사인유사도 계산 cos_sim = linear_kernel(data, data) cos_sim_score = list(enumerate(cos_sim[q_num])) cos_sim_score = sorted(cos_sim_score, key = lambda x : x[1], reverse = True) #상위 10개 항목을 가져옴 score = cos_sim_score[1:11] tag_indices = [i[0] for i in score] return tag_indices
word_dictionary는 명사추출에 앞서서 원하는 명사를 추출하기 위해서 사전 역할을 합니다.
위에서 긁어온 데이터를 다시 불러서 진행합니다.
word_dictionary = ['전세집'] okky_data = pd.read_csv(r'다음뉴스종합.csv', encoding = "utf-8", low_memory = False)
데이터를 입력하면 명사 추출까지는 자동으로 입력하고
그 이후 fit_tfidf 메서드를 불러서 유사도 metrix를 저장합니다.
TFIDF = TFIDF(okky_data,word_dictionary) data_tit = TFIDF.fit_tfidf()
마지막으로 코사인유사도로 순위가 나타난 문서들을 출력할 차례입니다.
# 50개까지만 출력합니다. count = 50 for i in range(len(okky_data[:count])): print(i, '/', len(okky_data)) #질문 제목과 데이터셋의 유사도를 10위까지 가져옴 tit_10_q = okky_data['content'].iloc[TFIDF.top10_indices(data_tit, i)] print(str(i),"번 뉴스와 유사한 내용을 가진 뉴스목록\n", tit_10_q)
정리
1.데이터를 크롤링한다.
2.명사만 따로 추출해서 저장한다.
3.Tf-idf를 이용해서 문서유사도를 구한다.(핵심 단어만 찾아낸다.)
4.구한 값을 이용해서 코사인유사도로 비슷한 문서를 찾는다.
반응형'Data Analysis' 카테고리의 다른 글
P-Value, T-Test, Z-Test 설명 (0) 2023.06.27 기상데이터와 GS25 판매량 데이터를 이용한 분석 리포트 - 2 (0) 2021.03.08 기상데이터와 GS25 판매량 데이터를 이용한 분석 리포트 - 1 (0) 2021.03.08