close_btn
조회 수 4738 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
# 본격적인 텍스트마이닝에 앞서
# 데이터프레임을 쉽게 조작하는 함수 몇가지를 알아보겠습니다.
# 참조 : http://wsyang.com/2014/02/introduction-to-dplyr/

install.packages(c("dplyr", "hflights"))
library(dplyr)

# 함수명    내용                              유사함수
# filter() 행의 추출                            subset()
# select() 열의 추출                     data[, c(“Year”, “Month”)]
# mutate() 열 추가                              transform()
# arrange() 정렬                              order(), sort()
# summarise() 집계                              aggregate()

# 미국 휴스턴에서 출발하는 비행기의 이착륙 기록이 수록된 데이터
library(hflights)
# 227,496건 이착륙 기록에 대한 21개의 데이터
dim(hflights)      
hflights_df <- tbl_df(hflights)
# 간편하게 볼 수 있다! 
hflights_df

# filter() 조건에 따른 행을 추출
# filter(데이터, 추출하고 싶은 조건 행)
filter(hflights_df, Month == 1) # 1월인 경우 추출
filter(hflights_df, Month == 1, DayofMonth == 1) # 1월 1일인 경우 추출
filter(hflights_df, Month == 1 | Month == 2) # 1월 혹은 2월인 경우 추출

# select() 조건에 따른 열을 추출
# select(데이터, 추출하고 싶은 조건 열)
select(hflights_df, Year, Month, DayOfWeek)
  select(hflights_df, -(Year:DayOfWeek)) #  Year부터 DayOfWeek를 제외한 나머지 열을 추출

# mutate()는 열을 추가하고 싶을 때 사용
hflights_df_gain <- mutate(hflights_df, gain = ArrDelay - DepDelay, gain_per_hour = gain/(AirTime/60))
select(hflights_df_gain, ArrDelay, DepDelay, gain, gain_per_hour)

# arrange() 지정한 열을 정렬하는 식, 작은 값부터 큰 값으로 정렬한다
hflights_df_arr <-arrange(hflights_df, AirTime, ArrDelay, DepDelay)
select(hflights_df_arr, AirTime, ArrDelay, DepDelay,Month)
# 역순으로 정렬하고 싶을 때는 변수에 desc() 를 사용한다
hflights_df_desc <-arrange(hflights_df, desc(AirTime), ArrDelay, DepDelay)
select(hflights_df_desc, AirTime, ArrDelay, DepDelay,Month)

# 요약함수 summarise()
summarise(hflights_df, delay = sd(DepDelay+ArrDelay, na.rm = TRUE))
summarise(hflights_df, delay = mean(DepDelay+ArrDelay, na.rm = TRUE))

# group_by를 이용한 그룹화
planes <- group_by(hflights_df,TailNum)
unique(hflights_df$TailNum)
delay <- summarise(planes, count = n(), dist = mean(Distance, na.rm = TRUE), 
                     delay = mean(ArrDelay, na.rm = TRUE))
# 그룹화 한 것에서 20번 이상, 평균 거리는 2000마일 미만인 비행기별 평균 연착시간을 
delay <- filter(delay, count > 20, dist < 2000)

library(ggplot2)

# 그래프로 나타내 봅니다. 
# geom_point에서 alpha는 투명도, geom_smooth는 평활선 그리기, scale_size_area는 
# 배경의 크기(max_size=6)
ggplot(delay, aes(dist, delay)) + geom_point(aes(size = count), alpha = 1/2) + 
       geom_smooth() + scale_size_area()

dlrj.png
      
# %>% 연산자의 활용
# dplyr package에서는 %>%를 사용해서 임시의 데이터 프레임을 만들지 않고 각 함수를 연결할 수 있습니다.
# 먼저 데이터프레임을 설정하면 그다음부터는 인수를 생략할 수 있게 됩니다.

hflights_df %>% group_by(Year, Month, DayofMonth) %>% summarise(arr = mean(ArrDelay, na.rm = TRUE),
  dep = mean(DepDelay, na.rm = TRUE)) %>% filter(arr > 30| dep>30)


###################################################################################################

# 출처 : http://tidytextmining.com/
# 본격적으로 텍스트마이닝의 기본이 되는 tidytext의 형태로의 단어 추출과
# 빈도수 조사, 비교 등을 해보겠습니다.
# tidy text 의 사용
# one-token-per-row 의 형식, token은 의미가 있는 어절, 주로 단어의 단위로 생각하시면 됩니다.
# tidy text는 하나의 행에 하나의 token을 넣은 것을 뜻합니다.

library(tm)
library(KoNLP)

text <- c("Because I was so hungry -",
          "I started to eat insects -",
          "Suprisingly, the taste of insects -",
          "chocolate")

# corpus를 이용한 textmining
text_corpus <- Corpus(VectorSource(text))
inspect(text_corpus)
nouns <- unlist(extractNoun(text_corpus))
table(nouns)

# character vector 인 text를 tidy text의 형태로 바꿔 보겠습니다.
str(text)

# 데이터프레임 형태로 바꿔주어야 합니다
# 이 때 줄의 길이가 보전되는 형태의 데이터프레임으로 바꿔지는데,
# 이를 tibble 이라고 합니다.
# 변환 할 때 주의 할 점은 기존 text의 줄과 line의 수를 맞춰 줘야 한다는 것입니다.
text_df <- data_frame(line = 1:4, text =text)

# tibble은 dataframe의 한 종류로, dplyr과 tibble package에서 사용하는 출력 방식입니다
# string변수를 factor 변수로 변하지 않으며 행의 이름을 사용하지 않고 번호로 출력 됩니다.
# 각 line에 들어있는 token들을 행별로 나눠 tidy text의 형태로 만들어보겠습니다.

library(tidytext)

# text_df 줄에 있는 text를 word라는 열에 token으로 나눠주는 작업입니다.
# 이게 앞서 계속 말한 tidy text라고 할 수 있습니다.
# 보시다시피 text_df의 몇 번 째 줄인지의 정보가 보존됨과 동시에 단어를 뽑아내며,
# 문장부호를 지워주고 소문자로 자동 변환 해 tidy text의 형태로 변환시켜 줍니다.
text_df %>%
  unnest_tokens(word, text)



# 그러면 이 tidy text의 긴 글을 분석해 보겠습니다.

library(janeaustenr)
library(stringr)

View(austen_books())
unique(austen_books()$book)


original_books <- austen_books() %>%
  group_by(book) %>%
  mutate(linenumber = row_number(),
         chapter = cumsum(str_detect(text, regex("^chapter [\\divxlc]",
                                                 ignore_case = TRUE)))) %>%
  ungroup()

original_books

# 이걸 저희가 다룰 tidy text 형태로 바꿔보겠습니다.

tidy_books <- original_books %>%
  unnest_tokens(word, text)

tidy_books

# 불용어(stopwords를 제거해보겠습니다)
# 불용어 : “the”, “of”, “to” 같이 단어분석에 크게 쓰이지 않는 단어들
# tidytext에서는 anti_join()을 사요
data(stop_words)

tidy_books <- tidy_books %>%
  anti_join(stop_words)

# 이제 빈도수를 세어 보겠습니다.
tidy_books %>%
  count(word, sort = TRUE) 

# 시각화 하면
library(ggplot2)

tidy_books %>%
  count(word, sort = TRUE) %>%
  filter(n > 600) %>%                 # 600번 이상 나온 단어를 대상으로
  mutate(word = reorder(word, n)) %>%  # 단어 빈도수 순으로 나열
  # 원래는 x축 word, y축 n 인데, 
  # coord_flip을 사용하면 보기좋게 자동으로 축을 변환해 주는 함수입니다.
  ggplot(aes(word, n)) +  geom_col() + coord_flip() 

Rplot.png

# 단어 빈도수 비교를 위해 다른 예제를 들어보겠습니다.
# h.g.wells라는 공상과학 소설가의 소설을 가져오겠습니다.

url<-"http://www.gutenberg.org/cache/epub/35/pg35.txt"    
hgwells<-readLines(url, encoding ="UTF-8") 
# 여태했던 것 처럼 tidy text의 형태로 분석해 보겠습니다.
# token 단위로 나누고, 불용어를 제거하겠습니다.

text_df_1 <- data_frame(line = 1:3617, text =hgwells)
  tidy_hgwells <- text_df_1 %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words)
tidy_hgwells %>%
  count(word, sort = TRUE)

# bronte의 제인 에어 입니다.
urlb<-"http://www.gutenberg.org/cache/epub/1260/pg1260.txt"    
bronte<-readLines(urlb, encoding ="UTF-8") 

text_df_2 <- data_frame(line = 1:21062, text =bronte)
tidy_bronte <- text_df_2 %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words)
tidy_bronte %>%
  count(word, sort=TRUE)

library(tidyr)

frequency <- bind_rows(mutate(tidy_bronte, author = "Brontë Sisters"),
                       mutate(tidy_hgwells, author = "H.G. Wells"), 
                       mutate(tidy_books, author = "Jane Austen")) %>% 
  mutate(word = str_extract(word, "[a-z']+")) %>%   # 밑줄치거나 이태리체, 언더바 등을 모두 한단어로 
  count(author, word) %>%
  mutate(proportion = n / sum(n)) %>% 
  select(-n) %>%       # 비율만 살리고 개수는 제외
  spread(author, proportion) %>% # 작가별로 사용단어의 비율을 나눠줍니다.
  gather(author, proportion, `Brontë Sisters`:`H.G. Wells`) 

library(scales)


ggplot(frequency, aes(x = proportion, y = `Jane Austen`, color = abs(`Jane Austen` - proportion))) +
  geom_abline(color = "gray40", lty = 2) +
  geom_jitter(alpha = 0.1, size = 2.5, width = 0.3, height = 0.3) +
  geom_text(aes(label = word), check_overlap = TRUE, vjust = 1.5) +
  scale_x_log10(labels = percent_format()) +
  scale_y_log10(labels = percent_format()) +
  scale_color_gradient(limits = c(0, 0.001), low = "darkslategray4", high = "gray75") +
  facet_wrap(~author, ncol = 2) +
  theme(legend.position="none") +  labs(y = "Jane Austen", x = NULL)


Rplot02.png

# 상관관계를 찾아보면 0.69와 0.47로 bronte sisters와 더 유사한 단어를 많이 사용했음을
# 확인할 수 있습니다.
cor.test(data = frequency[frequency$author == "Brontë Sisters",],
         ~ proportion + `Jane Austen`)
cor.test(data = frequency[frequency$author == "H.G. Wells",], 
         ~ proportion + `Jane Austen`)

# 그럼 자소서로 한번 해보겠습니다
# 자소서는 동일인물의 skt와 삼성에 지원한 자소서입니다.
# 제 친구고... 
# 개인정보가 있어서 파일은 올리지 않겠습니다 시각화 한 것 보시고
# 필요하신분이 있으시면 연락해 주시길 바랍니다!
skt <- file("C:\\Users\\user\\Desktop\\투빅스\\개인세미나\\skt자소서.txt", encoding="UTF-8")
sam <- file("C:\\Users\\user\\Desktop\\투빅스\\개인세미나\\삼성자소서.txt", encoding="UTF-8")
CJ <- file("C:\\Users\\user\\Desktop\\투빅스\\개인세미나\\CJ자소서.txt", encoding="UTF-8")
skt_resume <- readLines(skt)
sam_resume <- readLines(sam)
CJ_resume <- readLines(CJ)

# 간단한 전처리
# skt
skt_resume <- skt_resume[-which(skt_resume=="")]
skt_resume <- unlist(extractNoun(skt_resume))
skt_resume<-gsub("한", "",skt_resume)
skt_resume<-gsub("수", "",skt_resume)
skt_resume<-gsub("들", "",skt_resume)
skt_resume<-gsub("것", "",skt_resume)
skt_resume<-gsub("적", "",skt_resume)
skt_resume<-gsub("\\d","",skt_resume)

skt_df <- data_frame(line = 1:1572, text =skt_resume)

tidy_skt <- skt_df %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words)
tidy_skt %>%
  count(word, sort = TRUE)

# 삼성
sam_resume <- sam_resume[-which(sam_resume=="")]
sam_resume <- unlist(extractNoun(sam_resume))
sam_resume<-gsub("한", "",sam_resume)
sam_resume<-gsub("년", "",sam_resume)
sam_resume<-gsub("들", "",sam_resume)
sam_resume<-gsub("것", "",sam_resume)
sam_resume<-gsub("적", "",sam_resume)
sam_resume<-gsub("\\d","",sam_resume)

sam_df <- data_frame(line = 1:649, text =sam_resume)

tidy_sam <- sam_df %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words)
tidy_sam %>%
  count(word, sort = TRUE)

# CJ
CJ_resume <- CJ_resume[-which(CJ_resume=="")]
CJ_resume <- unlist(extractNoun(CJ_resume))
CJ_resume<-gsub("한", "",CJ_resume)
CJ_resume<-gsub("수", "",CJ_resume)
CJ_resume<-gsub("들", "",CJ_resume)
CJ_resume<-gsub("것", "",CJ_resume)
CJ_resume<-gsub("적", "",CJ_resume)
CJ_resume<-gsub("\\d","",CJ_resume)

CJ_df <- data_frame(line = 1:535, text =CJ_resume)

tidy_CJ <- CJ_df %>%
  unnest_tokens(word, text) %>%
  anti_join(stop_words)
tidy_CJ %>%
  count(word, sort = TRUE)

# 위에서와 같게 진행할텐데, 이 친구는 작년 하반기에 skt 자소서로 서류를 붙었습니다.
# 그래서 skt를 기준으로 잡고 서로 얼마나 같은지를 보겠습니다!

library(tidyr)

frequency_2 <-bind_rows(mutate(tidy_sam, company = "SAMSUNG"),
                        mutate(tidy_CJ, company = "CJ"),
                        mutate(tidy_skt, company = "SKT")) %>% 
  mutate(word = str_extract(word, "[가-힣']+")) %>%    
  count(company, word) %>%
  mutate(proportion = n / sum(n)) %>% 
  select(-n) %>%       
  spread(company, proportion) %>% 
  gather(company, proportion, `SAMSUNG`:`CJ`)

library(scales)
library(ggplot2)

ggplot(frequency_2, aes(x = proportion, y = SKT, color = abs(SKT - proportion))) +
  geom_abline(color = "gray40", lty = 2) +
  geom_jitter(alpha = 0.1, size = 2.5, width = 0.3, height = 0.3) +
  geom_text(aes(label = word), check_overlap = TRUE, vjust = 1.5) +
  scale_x_log10(labels = percent_format()) +
  scale_y_log10(labels = percent_format()) +
  scale_color_gradient(limits = c(0, 0.001), low = "darkslategray4", high = "gray75") +
  facet_wrap(~company, ncol = 2) +
  theme(legend.position="none") +  labs(y = "SKT", x = NULL)

Rplot01.png

# 0.41 , 0.42 상관관계가 설명되는 것으로 크게 유사하다고는 보기 힘들거 같습니다.
cor.test(data = frequency_2[frequency_2$company == "SAMSUNG",],
        ~ proportion + SKT)
cor.test(data = frequency_2[frequency_2$company == "CJ",], 
         ~ proportion + SKT)

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 텍스트 마이닝 5장 - tidying and casting dtm and corpus objects file 유누리 2017.05.14 5468
4 텍스트 마이닝 2장 감성분석 1 file 호잇짜 2017.04.11 14075
3 3/29 텍스트마이닝 - 파이썬 기초1 1 file 2017.04.05 5720
» 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