네이버 스포츠 뉴스기사 크롤링 및 카테고리별 분류모델 구현

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]])