네이버 검색에 “데이터 사이언스”를 검색어로 넣어 관련 뉴스를 100개 가져오는 뉴스 크롤러를 작성한다. 그리고 나서 purrr
팩키지 map2_df
함수로 데이터프레임으로 깔끔하게 가져온다.
# 0. 환경설정 -----
library(tidyverse)
library(rvest)
library(glue)
# 1. 데이터 긁어오기 -----
## 네이버 뉴스 함수 작성
get_naver_news <- function(keyword, page){
url <- glue("https://search.naver.com/search.naver?&where=news&query=",keyword,"&sm=tab_pge&sort=0&photo=0&field=0&reporter_article=&pd=1&ds=2018.02.25&de=2018.03.04&docid=&nso=so:r,p:1w,a:all&mynews=0&cluster_rank=38&start=", page,"&refresh_start=0")
news_html <- read_html(url, handle = curl::new_handle("useragent" = "Mozilla/5.0"))
title <- html_nodes(news_html, xpath='//*[@class="type01"]/li/dl/dt/a') %>% html_text
source <- html_nodes(news_html, xpath='//*[@class="type01"]/li/dl/dd[1]/span[1]') %>% html_text
text <- html_nodes(news_html, xpath='//*[@class="type01"]/li/dl/dd[2]') %>% html_text
news_df <- data.frame(title, source, text)
return(news_df)
}
page_list <- 1:10
keyword_list <- rep("데이터%20사이언스", 10)
news_df <- map2_df(keyword_list, page_list, get_naver_news)
DT::datatable(news_df)
뉴스 본문에 나와 있는 contents
필드에 대해서 전처리 작업을 수행한다. 대표적인 한글관련 전처리 작업은 형태소 분석을 바탕으로 띄어쓰기, 특수문자 및 숫자 제거, 불용어 제거 등을 들 수 있다.
자바 기반 [KoNLP
팩키지]는 2016-12-15일 이후 업데이트가 2년 넘게 진행이 되고 있지 않고 있으며 KoSpacing
팩키지도 딥러닝 기반으로 개발은 되었으나 원할히 사용하기 까지 다수 복잡한 과정을 거쳐야 되고 개발된지 얼마되지 않아 활용사례가 극히 제한적이다.
NLP4kec는 한글은 은전한닢 형태소 분석기를 사용하고, 영어, 중국어는 Stanford core NLP 사용하여 한글, 영어, 중국어 텍스트 데이터 파일을 입력받아 형태소 분석 후 R tm package에서 사용할 수 있도록 해주는 팩키지로 개발되어 Kevin Seongho Na를 비롯하여 사용자층을 넓혀가고 있다.
library(NLP4kec)
news_df$bow <- r_parser_r(news_df$text, language = "ko", useEn = TRUE)
news_tidy_df <- news_df %>%
mutate(bow = map(bow, str_split, pattern=" ") ) %>%
select(title, source, bow) %>%
unnest(bow) %>%
unnest(bow)
news_tidy_df %>% head
title
1 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
2 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
3 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
4 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
5 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
6 엔코아 김옥기 상무, 와이즈유서 ‘AI시대의 데이터 과학과 대학’ 특강
source bow
1 브릿지경제 기업
2 브릿지경제 데이터
3 브릿지경제 사이언스
4 브릿지경제 주목
5 브릿지경제 시작
6 브릿지경제 설명
NLP4kec 팩키지에서 형태소 분석을 이미 수행했기 때문에 별도 작업은 필요없다. 사용자 정의 사전(dictionary.txt
)을 통해서 “데이터사이언스”, “데이터과학”과 같이 두 명사로 구성된 경우 나눠지는 사례가 있어 이에 대해 사용자 정의사전을 통해서 유의미하게 만든다.
news_df
에서 관련도순으로 상위 100개 기사를 추출하였다. “데이터 사이언스” 용어와 관련된 기사를 가장 많이 출고한 언론사 두곳을 찾아 비교분석해 보자.
tidy
방식 아님전통적인 방식으로 quanteda
팩키지를 동원해서 데이터 사이언스 관련 출고 기사가 많은 두 언론사(“한국경제TV”, “ZDNet Korea”)를 추출하여 dfm()
행렬을 만들어 빈도수를 계산하고 이를 ggplot
에 넣어 각각 시각화 산출물을 만들고 cowplot
으로 시각화하는 코드는 다음과 같다.
library(quanteda)
library(extrafont)
loadfonts()
## 상위 언론사 추출
news_df %>%
count(source, sort = TRUE)
# A tibble: 19 x 2
source n
<chr> <int>
1 한국경제TV 18
2 ZDNet Korea 11
3 이슈메이커 9
4 MTN 8
5 중앙일보 8
6 대학저널 7
7 대한금융신문 6
8 파퓰러사이언스 6
9 기자협회보 5
10 디지털데일리 4
11 플래텀 4
12 노컷뉴스 3
13 비지니스코리아 3
14 서울경제 2
15 아이티비즈 2
16 브릿지경제 1
17 아시아투데이 1
18 조선비즈 1
19 한국경제 1
ds_eda_df <- news_tidy_df %>%
filter(source %in% c("한국경제TV", "ZDNet Korea"))
ds_ke_df <- ds_eda_df %>% filter(source == "한국경제TV")
ds_ke_m <- dfm(ds_ke_df$bow) %>% as.matrix
ds_zdnet_df <- ds_eda_df %>% filter(source == "ZDNet Korea")
ds_zdnet_m <- dfm(ds_zdnet_df$bow) %>% as.matrix
ds_ke_freq <- colSums(ds_ke_m)
ds_zdnet_freq <- colSums(ds_zdnet_m)
ke_g <- ds_ke_freq %>%
as.data.frame() %>%
rownames_to_column(var="word") %>%
rename(frequency = '.') %>%
arrange(desc(frequency)) %>%
top_n(15, frequency) %>%
ggplot(aes(x=fct_reorder(word, frequency), y=frequency, fill=word)) +
geom_col() +
coord_flip() +
labs(x="", y="단어 빈도", title="한국경제 데이터 사이언스 단어 빈도") +
theme_minimal(base_family = "NanumGothic") +
theme(legend.position = "none")
zdnet_g <- ds_zdnet_freq %>%
as.data.frame() %>%
rownames_to_column(var="word") %>%
rename(frequency = '.') %>%
arrange(desc(frequency)) %>%
top_n(15, frequency) %>%
ggplot(aes(x=fct_reorder(word, frequency), y=frequency, fill=word)) +
geom_col() +
coord_flip() +
labs(x="", y="단어 빈도", title="ZDnet 데이터 사이언스 단어 빈도") +
theme_minimal(base_family = "NanumGothic") +
theme(legend.position = "none")
cowplot::plot_grid(ke_g, zdnet_g)
tidy
방식tidy
방식으로 코드를 작성하게 되면 dplyr
동사를 사용해서 각 언론사별로 15개 단어를 추출하여 시각화를 한다. 이번 경우 단어길이가 1인 것은 제외시킨다. 그리고 나서 ggplot
으로 시각화한다.
news_tidy_df %>%
count(source, bow, sort=TRUE) %>%
mutate(word_length = str_length(bow)) %>%
filter(word_length > 1) %>%
filter(source %in% c("한국경제TV", "ZDNet Korea")) %>%
group_by(source) %>%
top_n(15, wt=n) %>%
ungroup() %>%
ggplot(aes(x=fct_reorder(bow,n), y=n, fill=bow)) +
geom_col() +
facet_wrap(~source, scales = "free") +
coord_flip() +
labs(x="", y="단어 빈도", title="ZDnet 데이터 사이언스 단어 빈도") +
theme_minimal(base_family = "NanumGothic") +
theme(legend.position = "none")