네이버 스포츠 뉴스기사 크롤링 및 카테고리별 분류모델 구현
2019-01-28
.
- 네이버 스포츠 뉴스기사 제목 웹크롤링 및 수집한 데이터를 기반으로 스포츠 종목을 분류하는 ‘MultinomialNB’ 모델 구현
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
%matplotlib inline
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import scipy as sp
import pickle
import time
from selenium import webdriver
def making_date(start, end):
"""
[입력형식]
ㅇ start, end = '년도-월-일'
ex)
'2018-11-01'
'2018-12-14'
[return 값]
ㅇ date : start ~ end까지 날짜리스트
"""
date_list = []
if start > end :
print("error(start > end) try again")
return None
elif (start or end) is (int or float):
print("error try again")
return None
elif start == end:
making_date = start
temp = str(making_date)[:4] + str(making_date)[5:7] + str(making_date)[8:10]
date_list.append(temp)
return date_list
else :
making_date = pd.date_range(start, end)
for count in range(len(making_date)):
temp = str(making_date[count])[:4] + str(making_date[count])[5:7] + str(making_date[count])[8:10]
date_list.append(temp)
return date_list
date_list = making_date("2018-11-01","2018-12-02")
len(date_list)
32
def crawler(date_list,headless=False):
'''
[category]
1 : 축구
2 : 야구
3 : 농구
4 : 배구
5 : 골프
'''
result = []
category_list = ["kfootball","wfootball","kbaseball","wbaseball","basketball","volleyball","golf"]
count = 0
category_count = 0
for category_data in category_list:
if category_data == "wfootball" :
pass
elif category_data == "wbaseball" :
pass
else :
category_count += 1
for date in date_list:
for page_number in range(1,3):
url = "https://sports.news.naver.com/{}/news/index.nhn?date={}&page={}&isphoto=N".format(category_data,date,page_number)
if headless:
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(options=options)
else :
driver = webdriver.Chrome()
driver.get(url)
articles = driver.find_elements_by_css_selector("#_newsList ul li")
for article in articles:
title = article.find_element_by_css_selector('div .title span').text
count += 1
data = {
"ID" : count,
"category" : category_count,
"title" : title,
}
result.append(data)
driver.quit()
df = pd.DataFrame(result)
return df
df = crawler(date_list,headless=False)
df
ID | category | title | |
---|---|---|---|
0 | 1 | 1 | 병역특례 서류조작으로 국가대표 자격 영구 박탈된 장현수, 연봉은 얼마? |
1 | 2 | 1 | 장현수의 파란만장 넉 달 '월드컵 실망→빌드업 중심→영구 박탈' |
2 | 3 | 1 | ‘병역 서류조작’으로 국대 퇴출..장현수, 공식 사과에도 비난 봇물 |
3 | 4 | 1 | 한국, 일본 꺾은 사우디와 26년 만에 결승전 [AFC U-19 챔피언십] |
4 | 5 | 1 | '전세진 멀티골' U-19 축구대표팀, AFC 챔피언십 결승 진출(종합) |
5 | 6 | 1 | 한국, 사우디와 26년만의 결승전...U-19 챔피언십 13번째 우승 도전 |
6 | 7 | 1 | [U-19 REVIEW] 정정용호 결승 상대는 사우디로 확정!… 일본 2-0 격파 |
7 | 8 | 1 | [U-19 리뷰] 일본, 준결승전서 사우디에 0-2 패...'결승 한일전' 무산 |
8 | 9 | 1 | [U-19 챔피언십] ‘골키퍼 자책골’ 일본, 사우디에 0-2 완패...결승 진출 실패 |
9 | 10 | 1 | 장현수 영구제명→공식 사과 “병역특례 혜택 받았음에도…정말 죄송” |
10 | 11 | 1 | '병역특례 조작' 장현수에 철퇴...국가대표 영구 퇴출 |
11 | 12 | 1 | '전세진 멀티골' U-19 축구대표팀, AFC 챔피언십 결승 진출 |
12 | 13 | 1 | U-19 축구, AFC 챔피언십 6년만에 결승행 |
13 | 14 | 1 | '봉사활동 허위기재' 장현수, 축구대표팀 영구 퇴출 |
14 | 15 | 1 | 日 女 U-17팀 감독, 성추행으로 사퇴 “경솔했다” |
15 | 16 | 1 | 장현수 “국가대표 자격 영구박탈, 겸허히 받아들이겠다” |
16 | 17 | 1 | 봉사활동 서류조작 장현수, 국가대표 자격 '영구 박탈' |
17 | 18 | 1 | '봉사활동 조작' 장현수에 '대표자격 박탈' 초강력 징계 |
18 | 19 | 1 | 중국축구서 국가제창 때 움직였다고 징계 |
19 | 20 | 1 | 日 언론, '봉사활동 서류조작' 장현수 중징계 소식 타전 |
20 | 21 | 1 | K리그 최고의 득점 공식은? 6골 합작한 '아길라르→문선민' |
21 | 22 | 1 | 장현수, 국가대표 자격 영구 박탈…축구협회 “국대 선발엔 사면 내용 없다” |
22 | 23 | 1 | ‘봉사활동 조작’ 장현수, 태극마크 영원히 못 단다 |
23 | 24 | 1 | “韓수비 주축 장현수, 국가대표 자격 영구 박탈”…日언론도 ‘관심 집중’ |
24 | 25 | 1 | ‘병역 서류조작’ 장현수, 국가대표 자격 영구박탈..중징계, 왜? |
25 | 26 | 1 | '전세진 멀티골' 한국 U-19, 카타르 잡고 결승 진출 |
26 | 27 | 1 | 울산현대 선수이 경기 후 피로를 푸는 방법은??!! |
27 | 28 | 1 | '전세진 멀티골' 한국, AFC U-19 챔피언십 결승 진출 |
28 | 29 | 1 | `봉사활동 조작` 장현수, 대표팀 자격 영구 박탈 |
29 | 30 | 1 | ‘봉사활동 조작’ 장현수 대표팀 영구제명 |
... | ... | ... | ... |
8904 | 8905 | 5 | 황중곤, 일본투어 최종전서 연장 접전 끝 준우승 |
8905 | 8906 | 5 | 아버지 부시 타계에 골프계도 추모 분위기 |
8906 | 8907 | 5 | '30대 언니들' 日 두 자릿수 승수 이끌다…男은 '올드맨' 덕에 체면치레 |
8907 | 8908 | 5 | 행복한 골퍼 신지애 "골프가 재미있어 졌어요" |
8908 | 8909 | 5 | 3일째 선두 달리던 양용은, 4R서 '와르르' |
8909 | 8910 | 5 | "공 위치가 안좋을 땐 우드도 아이언처럼 찍어쳐야" |
8910 | 8911 | 5 | 제주 테디밸리 골프앤리조트, 국내 10대 골프장에 선정 |
8911 | 8912 | 5 | 우즈 "부시 前 미국 대통령 타계 매우 안타깝다…150분 만에 라운드 끝낸 속전속결... |
8912 | 8913 | 5 | 황중곤, JGTO 최종전서 연장 끝 준우승 |
8913 | 8914 | 5 | 황중곤, JGTO 최종전서 연장 끝에 아쉽게 준우승 |
8914 | 8915 | 5 | 황중곤, JGTO 최종전서 연장 끝 준우승…양용은 14위 |
8915 | 8916 | 5 | "18홀 도는 데 2시간 반이 안 걸렸다" |
8916 | 8917 | 5 | JT컵 연장 끝에...황중곤 아쉬운 준우승 |
8917 | 8918 | 5 | 박세리·박지은과 영광의 순간 함께했던 골프 애호가 ‘아버지 부시’ 대통령 |
8918 | 8919 | 5 | "정은이도 가고, 선우도 가고"..시즌 상금 순위 2위 배선우, 내년 일본시드 획득 |
8919 | 8920 | 5 | [민학수의 All That Golf]사흘 연속 ‘트리플-더블-더블’…타이거, 결국 ... |
8920 | 8921 | 5 | 우즈 “‘아버지 부시’는 골프와 동의어···18홀 라운드에 2시간 반이면 충분” |
8921 | 8922 | 5 | 배선우 활짝, 안신애·유현주 눈물…JLPGA 시드전서 엇갈린 희비(종합) |
8922 | 8923 | 5 | ‘보이스캐디’ 만든 김준오 대표 “스포츠와 기술의 결합, 한국이 세계무대에 던질 승부수” |
8923 | 8924 | 5 | 한국청소년골프연맹(KYGF) 회장단 이·취임식 갖고 본격 출범. |
8924 | 8925 | 5 | 세계 골프계, 골프 명예의 전당 회원 부시 타계 애도 |
8925 | 8926 | 5 | "골프계의 친구를 잃었다" 부시 전 대통령 타계에 골프계 추모 |
8926 | 8927 | 5 | 타이거 우즈, 자신이 주최한 대회서 맨꼴찌 |
8927 | 8928 | 5 | 배선우, JLPGA 투어 풀시드 획득…안신애·유현주 탈락 |
8928 | 8929 | 5 | '골프황제' 우즈, 자신이 주최한 대회서 최하위 추락 |
8929 | 8930 | 5 | 될성부른 떡잎, 임성재 |
8930 | 8931 | 5 | 배선우도 일본진출...상금랭킹 1,2위 모두 잃은 KLPGA 투어 |
8931 | 8932 | 5 | 우즈 "골프계, 친구 잃었다"…부시 전 대통령 타계 추모 |
8932 | 8933 | 5 | 우즈 최하위 "발목이 아파서?" |
8933 | 8934 | 5 | 장이근 공동 21위…하딩 선두 |
8934 rows × 3 columns
df.to_csv("naver.csv", mode='w')
df = pd.read_csv("naver.csv")
df[:10]
Unnamed: 0 | ID | category | title | |
---|---|---|---|---|
0 | 0 | 1 | 1 | 병역특례 서류조작으로 국가대표 자격 영구 박탈된 장현수, 연봉은 얼마? |
1 | 1 | 2 | 1 | 장현수의 파란만장 넉 달 '월드컵 실망→빌드업 중심→영구 박탈' |
2 | 2 | 3 | 1 | ‘병역 서류조작’으로 국대 퇴출..장현수, 공식 사과에도 비난 봇물 |
3 | 3 | 4 | 1 | 한국, 일본 꺾은 사우디와 26년 만에 결승전 [AFC U-19 챔피언십] |
4 | 4 | 5 | 1 | '전세진 멀티골' U-19 축구대표팀, AFC 챔피언십 결승 진출(종합) |
5 | 5 | 6 | 1 | 한국, 사우디와 26년만의 결승전...U-19 챔피언십 13번째 우승 도전 |
6 | 6 | 7 | 1 | [U-19 REVIEW] 정정용호 결승 상대는 사우디로 확정!… 일본 2-0 격파 |
7 | 7 | 8 | 1 | [U-19 리뷰] 일본, 준결승전서 사우디에 0-2 패...'결승 한일전' 무산 |
8 | 8 | 9 | 1 | [U-19 챔피언십] ‘골키퍼 자책골’ 일본, 사우디에 0-2 완패...결승 진출 실패 |
9 | 9 | 10 | 1 | 장현수 영구제명→공식 사과 “병역특례 혜택 받았음에도…정말 죄송” |
카테고리 분류모델 구현
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
x_train, x_test, y_train, y_test = train_test_split(df.title, df.category,
test_size = 0.1, random_state = 1)
len(x_train),len(x_test), len(y_train), len(y_test)
(8040, 894, 8040, 894)
clf = Pipeline([
('vect',TfidfVectorizer()),
('clf',MultinomialNB(alpha = 0.01))
])
model = clf.fit(x_train, y_train)
y_pred = model.predict(x_test)
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
confusion_matrix(y_test, y_pred)
array([[238, 8, 3, 0, 3],
[ 7, 256, 4, 0, 2],
[ 2, 5, 112, 4, 1],
[ 1, 4, 2, 109, 1],
[ 3, 6, 1, 1, 121]], dtype=int64)
print(classification_report(y_test, y_pred))
precision recall f1-score support
1 0.95 0.94 0.95 252
2 0.92 0.95 0.93 269
3 0.92 0.90 0.91 124
4 0.96 0.93 0.94 117
5 0.95 0.92 0.93 132
micro avg 0.94 0.94 0.94 894
macro avg 0.94 0.93 0.93 894
weighted avg 0.94 0.94 0.94 894
test_str = "‘정지석 22득점’ 대한항공, 한국전력 꺾고 2연승 질주"
model.predict_proba([test_str])
array([[2.25374484e-06, 4.32075338e-07, 1.38432689e-04, 9.99858455e-01,
4.26138274e-07]])
test_str2 = "두산베어스 한국시리즈 준우승"
model.predict_proba([test_str2])
array([[3.42020834e-03, 9.91975169e-01, 2.26965790e-04, 2.44048299e-04,
4.13360874e-03]])