close_btn
조회 수 5469 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files

이번 세미나는 tidy text tool들을 이용하기 위해 텍스트 자료구조들 간 변환하는 방법에 대해 다뤘습니다.

3.3.3 이상의 R 버젼에서 아래 코드가 모두 실행되는 점 참고 바랍니다.


#install.packages("topicmodels")
#install.packages("tm")
library(topicmodels)
library(tm)

data("AssociatedPress", package = "topicmodels")
AssociatedPress # AP라는 미국 통신사에 대한 기사 데이터

terms <- Terms(AssociatedPress)
head(terms)
length(terms)

# 이 데이터를 tidy tool을 이용해 분석하고 싶다면?
# one-token-per-document-per-row 형태의 data frame으로 변환이 필요 (tidy 함수 이용)

#install.packages("dplyr")
#install.packages("tidytext")
library(dplyr)
library(tidytext)

ap_td <- tidy(AssociatedPress)
ap_td
# tidy를 거친 데이터의 특징 : 빈도수가 non-zero인 value들만 포함
# tidy를 거친 데이터는 dplyr, tidytext, ggplot2 등의 패키지를 이용하기 좋다


# 감성 분석을 예로 들어보자!
ap_sentiments <- ap_td %>%
  inner_join(get_sentiments("bing"), by = c(term = "word"))
# get_sentiments : tidytext 패키지에 내장된 감성 사전 호출
# parameter로 "bing", "afinn", "nrc"가 있음
# "bing" : 단어들을 negative <-> positive로 분류
# "afinn" : 단어들에 -5점 ~ 5점 사이의 점수를 매김
# "nrc" : 단어들을 10가지 감정의 범주에 분류
# trust, fear, negative, sadness, anger, surprise, positive, disgust, joy, anticipation

ap_sentiments

#install.packages("ggplot2")
library(ggplot2)

ap_sentiments %>%
  count(sentiment, term, wt = count) %>%
  ungroup() %>%
  filter(n >= 200) %>%
  mutate(n = ifelse(sentiment == "negative", -n, n)) %>%
  mutate(term = reorder(term, n)) %>%
  ggplot(aes(term, n, fill = sentiment)) +
  geom_bar(stat = "identity") +
  ylab("Contribution to sentiment") +
  coord_flip()

Rplot1.png

# 다른 텍스트 마이닝 패키지들에서는 Document-Term Matrix와 유사한 Document-Feature Matrix라는 데이터 형태가 있음
library(methods)

data("data_corpus_inaugural", package = "quanteda")
inaug_dfm <- quanteda::dfm(data_corpus_inaugural, verbose = FALSE)
inaug_dfm

# tidy 함수는 DTM 뿐 아니라 DFM에 대해서도 적용 가능
inaug_td <- tidy(inaug_dfm)
inaug_td # tidy 적용 결과 one-token-per-document-per-row table 형태

# 데이터를 tf-idf 기준 내림차순 정렬
# tf-idf ?
# 특정 단어가 특정 문서에서만 많이 나타날수록 높은 tf-idf 값을 가짐
inaug_tf_idf <- inaug_td %>%
  bind_tf_idf(term, document, count) %>%
  arrange(desc(tf_idf))
inaug_tf_idf

inaug_tf_idf %>%
  count(document, term, tf_idf, wt = count) %>%
  ungroup() %>%
  filter(tf_idf >= 0.002, document %in% c("1861-Lincoln", "1933-Roosevelt", "1961-Kennedy", "2009-Obama")) %>%
  group_by(document) %>%
  top_n(10, tf_idf) %>%
  ungroup() %>%
  mutate(term = reorder(term, tf_idf)) %>%
  ggplot(aes(term, tf_idf, fill = document)) +
  geom_bar(stat = "identity") +
  facet_wrap(~ document, scales = "free") +
  ylab("tf-idf") +
  coord_flip()

Rplot2.png

# 위 연설문 데이터 중 document column의 년도만 뽑아내서
# 시간의 흐름에 따른 단어 사용 빈도수 변화를 알아보자
library(tidyr)

year_term_counts <- inaug_td %>%
  extract(document, "year", "(\\d+)", convert = TRUE) %>%
  complete(year, term, fill = list(count = 0)) %>%
  group_by(year) %>%
  mutate(year_total = sum(count))

year_term_counts %>%
  filter(term %in% c("god", "america", "foreign", "union", "constitution", "freedom")) %>%
  ggplot(aes(year, count / year_total)) +
  geom_point() +
  geom_smooth() +
  facet_wrap(~ term, scales = "free_y") +
  scale_y_continuous(labels = scales::percent_format()) +
  ylab("% frequency of word in inaugural address")

Rplot3.png
# 지금까지는 Document-Term Matrix, Document-Feature Matrix 등의 자료 형태를 tidy tool을 적용할 수 있는 형태인
# one-token-per-document-per-row 형태의 data frame으로 변환했다면 (tidy 함수를 이용)
# 거꾸로 다시 DTM, DFM 등의 자료 구조로 변환하는 것 또한 가능하다!

# 아까 tidy를 거쳤던 AP 통신사 데이터를 다시 Document-Term Matrix 형태로 변환
ap_td %>%
  cast_dtm(document, term, count)

# 유사하게 quanteda 패키지의 Document-Feature Matrix 형태로도 변환 가능
ap_td %>%
  cast_dfm(term, document, count)

library(Matrix)
# Matrix 형태로도 변환 가능
m <- ap_td %>%
  cast_sparse(document, term, count)

class(m)
dim(m)

# 이와 같이 이 책에서 쓰이는 tidy text structure은 서로 형태 변환이 자유롭다!
# 예를 들어 제인 오스틴 데이터를 이용해 DTM 형태를 만들어보자

library(janeaustenr)

austen_dtm <- austen_books() %>%
  unnest_tokens(word, text) %>%
  count(book, word) %>%
  cast_dtm(book, word, n)

austen_dtm
# 위와 같이 DTM 형태로 변환된 데이터는 머신 러닝 기법들의 input으로 이용 가능


# VCorpus 자료 구조에 대해 tidy tool 적용해보기
# tm 패키지 내의 acq 데이터 (로이터 통신사에 대한 50개의 기사 데이터)
data("acq")
acq
acq[[1]]

# 위의 VCorpus object는 list와 비슷한 구조를 가짐
# text와 metadata 모두를 포함하며 flexible한 자료구조이지만 tidy tool을 직접 적용할 수 없음
# 따라서 tidy 함수를 이용해 one row per document 형태로 변환

acq_td <- tidy(acq)
acq_td

# 예를 들어 50개의 기사 데이터 중 가장 많이 쓰인 단어를 찾고 싶거나 각 기사를 가장 대표하는 단어를 찾고 싶다면
# unnest_token() 함수 이용
acq_tokens <- acq_td %>%
  select(-places) %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words, by = "word")

# most common words
acq_tokens %>%
  count(word, sort = TRUE)

# tf-idf
acq_tokens %>%
  count(id, word) %>%
  bind_tf_idf(word, id, n) %>%
  arrange(desc(tf_idf))

############################################################################################
# Example - mining financial articles

#install.packages("tm.plugin.webmining")
library(tm.plugin.webmining)
library(purrr)

# tm.plugin.webmining이라는 패키지는 키워드를 기반으로 온라인과 연동되어 기사 데이터를 수집할 수 있음
# 예를 들어 아래의 코드를 실행하면 Microsoft(MSFT) stock에 관한 최신 20개의 기사를 가져옴
msft <- WebCorpus(GoogleFinanceSource("NASDAQ:MSFT"))
inspect(msft[[1]])

company <- c("Microsoft", "Apple", "Google", "Amazon", "Facebook", "Yahoo", "Netflix")
symbol <- c("MSFT", "AAPL", "GOOG", "AMZN", "FB", "YHOO", "NFLX")
# 왜 twitter랑 yahoo는 연결이 안될까

download_articles <- function(symbol) {
  WebCorpus(GoogleFinanceSource(paste0("NASDAQ:", symbol)))
}

# 여기서 data_frame은 data.frame과 다르게 dplyr 패키지의 데이터 프레임
# map은 apply 함수라 생각하면 됨
stock_articles <- data_frame(company = company,
                             symbol = symbol) %>%
  mutate(corpus = map(symbol, download_articles))

stock_articles

stock_tokens <- stock_articles %>%
  unnest(map(corpus, tidy)) %>% #list-column에 대해 각 원소를 한 줄씩 분리해냄
  unnest_tokens(word, text) %>%
  select(company, datetimestamp, word, id, heading)

stock_tokens


# 위 데이터에 tf-idf 값 결합
library(stringr)

stock_tf_idf <- stock_tokens %>%
  count(company, word) %>%
  filter(!str_detect(word, "\\d+")) %>%
  bind_tf_idf(word, company, n) %>%
  arrange(-tf_idf)


# afinn 감성 사전을 이용해서 (단어의 빈도수 * 감성 점수)가 높은 열두개의 단어 시각화
stock_tokens %>%
  anti_join(stop_words, by = "word") %>%
  count(word, id, sort = TRUE) %>%
  inner_join(get_sentiments("afinn"), by = "word") %>%
  group_by(word) %>%
  summarize(contribution = sum(n * score)) %>%
  top_n(12, abs(contribution)) %>%
  mutate(word = reorder(word, contribution)) %>%
  ggplot(aes(word, contribution)) +
  geom_col() +
  coord_flip() +
  labs(y = "Frequency of word * AFINN score")

Rplot4.png
# loughran이라는 다른 감성 사전을 사용해서 다시 시각화해보자
#install.packages("devtools")
library(devtools)
install_github("juliasilge/tidytext")
library(tidytext)
# get_sentiments("loughran")

stock_tokens %>%
  count(word) %>%
  inner_join(get_sentiments("loughran"), by = "word") %>%
  group_by(sentiment) %>%
  top_n(5, n) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n)) +
  geom_col() +
  coord_flip() +
  facet_wrap(~ sentiment, scales = "free") +
  ylab("Frequency of this word in the recent financial articles")

Rplot5.png

# 감성 범주들을 새로운 column으로 데이터 생성
stock_sentiment_count <- stock_tokens %>%
  inner_join(get_sentiments("loughran"), by = "word") %>%
  count(sentiment, company) %>%
  spread(sentiment, n, fill = 0)

stock_sentiment_count

stock_sentiment_count %>%
  mutate(score = (positive - negative) / (positive + negative)) %>%
  mutate(company = reorder(company, score)) %>%
  ggplot(aes(company, score, fill = score > 0)) +
  geom_col(show.legend = TRUE) +
  coord_flip() +
  labs(x = "Company",
       y = "Positivity score among 20 recent news articles")

Rplot6.png


List of Articles
번호 제목 글쓴이 날짜 조회 수
7 텍스트 마이닝 3장 - Analyzing word and document frequency: tf-idf 곽대훈 2017.05.20 4332
6 텍스트 마이닝 4장 - Relationships between words file 연다인 2017.05.17 4640
» 텍스트 마이닝 5장 - tidying and casting dtm and corpus objects file 유누리 2017.05.14 5469
4 텍스트 마이닝 2장 감성분석 1 file 호잇짜 2017.04.11 14075
3 3/29 텍스트마이닝 - 파이썬 기초1 1 file 2017.04.05 5720
2 3/29 텍스트마이닝 1장 tidy text format 1 file cys109 2017.04.05 4738
1 3/29 텍스트 마이닝 - 파이썬 기초 2 2 file 허능호 2017.04.03 4701
Board Pagination ‹ Prev 1 Next ›
/ 1

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5