[R] LDA를 활용한 토픽트렌트 분석

토픽 모델링

  • 사용한 패키지
    • excel file I/O
      • readxl: excel file input
      • openxlsx: excel file output
    • string 처리 및 text mining 패키지
      • tm: R 제공 text mining 패키지, corpus, tdm 및 dtm 등을 제공
      • stringr: string 처리 패키지
    • topic modeling 패키지
      • topicmodels, lda: lda 패키지, 본인이 배운걸로는 topicmodels로 lda 포맷 변환후 lda로 돌리는게 정확도가 높다고 들음
In [1]:
library(readxl)
  • 앞서 형태소 분석한 파일을 로딩
In [2]:
blog<- read_excel("after_POS.xlsx")
  • 데이터 살펴보기
In [3]:
str(blog)
Classes 'tbl_df', 'tbl' and 'data.frame':  206 obs. of  5 variables:
 $            : chr  "1" "2" "3" "4" ...
 $ a*****     : chr  "ㅁ**" "ㅋ**" "녹***" "맥****" ...
 $ date       : chr  "2015.04.18 05:18" "2015.04.18 07:26" "2015.04.18 10:55" "2015.04.18 11:10" ...
 $ desc       : chr  "첫부분만 읽고서는 그저 그러뉴변명하려는 줄 알고 짜증부터 났네요. 방청품질이 미국과 동일하다고 두괄식으로 결론부터 쓰시는게 좋을"| __truncated__ "이제까지 내수 수출 차별한건 사실이고 방청말고 내부사양에 다른 장난질을 쳤을 가능성이 있다는 것도 인정 하신다는 말씀이죠?  참 대"| __truncated__ "          이분 최소한 난독증...진실한 소통의 시작..응원합니다        " "          맞는 부분 있습니다.. 내수외 북미용이 다릅니다. 씨트프레임도 달라요..ㅋㅋ 제조해 봐서... ㅋㅋ        " ...
 $ article_POS: chr  "첫/MDT;부분/NNG;만/JX;읽/VV;고서/ECD;는/JX;그저/MAG;그/VV;러/ECD;뉴/NNG;변명/NNG;하/XSV;려는/ETD;줄/NNB;알/VV;고/ECE;짜증/NNG;"| __truncated__ "이제/NNG;까지/JX;내수/NNG;수출/NNG;차별/NNG;하/XSV;ㄴ/ETD;것/NNB;은/JKS;사실/NNG;이/VCP;고/ECE;방청/NNG;말/VV;고/ECE;내부/NNG;"| __truncated__ "이분/NNG;최소/NNG;하/XSV;ㄴ/ETD;난독/NNG;증/NNG;.../SE;진실/NNG;하/XSV;ㄴ/ETD;소통/NNG;의/JKG;시작/NNG;../SW;응원/NNG;하/XSV;ㅂ"| __truncated__ "맞/VV;는/ETD;부분/NNG;있/VV;습니다/EFN;../SW;내수/NNG;외/NNB;북미/NNG;용/XSN;이/JKS;다르/VV;ㅂ니다/EFN;./SF;씨트/UN;프레임/NNG;"| __truncated__ ...
  • 글이 없어 형태소 분석칸이 공란인 데이터를 삭제
In [4]:
blog_test<-blog[complete.cases(blog$article_POS),]
In [5]:
library(tm)
library(stringr)
library(rJava)
Loading required package: NLP
In [6]:
ko.words = function(doc){
  d = str_split(doc, ';')[[1]] ## 띄어쓰기(' ')를 기준으로 한 문장을 여러 단어로 나눔 
  
  extracted = tolower(str_match(d, '([가-힣a-zA-Z]+)/[NVO]'))
  extracted2 = tolower(str_match(d,'([가-힣]+)/XR'))
  keyword = extracted[,2]
  keyword2 = extracted2[,2]
  keyword<-c(keyword,keyword2)
  
  keyword[!is.na(keyword)]  
}
  • 형태소 분석이 된 데이터를 corpus로 만든다음, tdm 작성
  • 이후 dtm으로 전환, 애시당초 만들 때 dtm으로 만들어도 무방
In [7]:
options(mc.cores=1)

cps = Corpus(VectorSource(blog_test$article_POS))

tdm <- TermDocumentMatrix(cps, control=list(tokenize=ko.words,
                                            wordLengths=c(2, Inf)))

dtm <- as.DocumentTermMatrix(tdm)
In [8]:
head(as.matrix(dtm))
aid app arc article articleid as aspx auto bar blog 훌륭 휘어지 흉기 흐르 흐리 흔들리 흔하 흘리 흠집 힘들
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2
  • dtm을 ldaformat으로 변환
  • lda 분석 실행
    • K는 추출할 토픽 개수
    • iterations는 사후확률의 업데이트 횟수
    • burnin은 확률 추정시 제외되는 초반부 이터레이션 값
    • alpha는 문서내에서 토픽들의 확률분포(1을 주면 유니폼 분포)
    • eta: 한 토픽 내에 단어들의 확률분포
  • start와 end는 소요시간을 체크 하기 위한 구문으로 삭제해도 무방
In [9]:
set.seed(227)

library(topicmodels)
ldaform<-dtm2ldaformat(dtm, omit_empty = F)

library(lda)

start = Sys.time()
result.lda<-lda.collapsed.gibbs.sampler(ldaform$documents,
                                        K = 10,
                                        vocab = ldaform$vocab,
                                        num.iterations = 80000,
                                        burnin = 25000,
                                        alpha = 0.01,
                                        eta = 0.01)

end <- Sys.time()

end-start
Time difference of 1.65214 mins
  • 해당 토픽에 출현한 단어 보기
    • 본 포스팅에선 20개를 살펴봄
In [10]:
top.topic.words(result.lda$topics,20,by.score=T)
아니 시스 한국 차량 현대 소나타 소통 부식 수출 지도
대한민국 그랜저 미국 우리나라 지금 떨어지 이것 기차 내수 부식
내수 xg 안전 핑계 부식 바꾸 우리 방청 강판 지역
수출 사원 아니 as 자동차 정비소 산타페 품질 차량 현지
기업 어쩌 sm 발생 만들 고장 진실 코팅 동일 무관
나라 영업 만들 소비자 국민 이상 달리 이제 국내 자료
부식 그때 외제 고치 생각 사고 오해 사람 차이 미국
처리 아부지 에어백 하체 모르 주변 com 시작 차별 국내
고객 이번 사실 정도 현지 경험 http 하부 다르 자체
그러 세대 원가 설명 대하 한번 대하 구입 비교 세상
워드 불친절 차이 결함 그렇 bmw 재질 언더 방청 학회
표면 운행 절감 따르 아니 운전 미국 올리 들어가 어이
현대 지점 현대 사람 때문 뒷바퀴 흉기 차량 일본 이해
호구 괜찮 정도 거짓말 회사 ef 기사 문제 이상 나라
자동차 바뀌 홍보 기간 현대자동차 거기 naver 가지 달르 내리
이것 hg 신뢰 가죽 기아 고무 nf 회사 아연도금 소비자
양쪽 품질 가격 그리 고객 잔고 결정 소비자 모델 강판
다르 거리 현기 시트 말하 잡소리 말장난 보시 대우 기준
그렇 뒷자리 서비스 어디 보이 브레이크 부탁 버리 직원 그러
교체 무상 북미 녹이 위하 문제없 이야기 그러 구형 부분
  • 제대로 된 전처리를 하지 않아 http나 naver가 추출 (URL임)
    • 이 후, 단어들을 보고 토픽을 주관적으로 이름 지어야 함
    • 예를 들어 topic 4를 보면, 내외수 차별에 관련된 토픽임
In [11]:
top_topic<-top.topic.words(result.lda$topics,20,by.score = T)

theta = rowSums(result.lda$document_sums)

## 비율로 변환 및 추가
topic.proportion = theta/sum(theta)

####토픽내에 단어별  출현확률(비율)구하기(여기서 상위개수 지정한거에 따라서 함수식 변환해주기)
top.words = top.topic.words(result.lda$topics, 20)#상위 n개 지정
c_top.words<-as.character(top.words)#캐릭터로 바꾸기
new.topics<-subset(result.lda$topics,select=c_top.words)#top.words에 해당하는 토픽 뽑기

count_by_words<-new.topics

a=1
k=0
for(j in 1:ncol(new.topics))#count 모아주는 함수
{
  if(a*20+1==j)
  {
    k=20*a
    a=a+1
  }
  count_by_words[a,j-k]<-count_by_words[a,j]
}


proportion_by_words<-t(count_by_words[,1:20]/as.integer(result.lda$topic_sums))#비율구하기

result<-matrix(paste(top.topic.words(result.lda$topics, 20),"(",proportion_by_words,")"),byrow=F,nrow=20)#단어랑 비율 paste해서 행렬만들기
output<-rbind(result,topic.proportion,t(result.lda$topic_sums))

토픽 트렌드 구하기

  • 앞서 행한 토픽모델링에서 각 토픽에 속한 단어의 문서별 빈도 살펴보기
In [12]:
trends<-as.data.frame(t(result.lda$document_sums),stringsAsFactors=F)
trends
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 0 1 5 0 0 0 0 3 2 0
2 0 0 3 0 0 1 0 4 5 0
3 0 0 0 0 0 0 6 1 0 0
4 0 0 0 0 0 0 0 4 2 0
5 0 0 1 0 0 0 3 18 0 0
6 24 0 11 0 6 0 0 29 0 0
7 0 0 18 0 23 0 0 0 0 0
8 0 0 2 0 0 0 0 0 0 0
9 0 11 0 0 9 0 0 13 0 0
10 0 0 3 0 4 0 6 0 0 0
11 0 0 0 20 11 24 17 0 13 0
12 0 0 0 0 6 0 0 0 11 0
13 0 3 0 0 29 0 4 23 32 0
14 2 0 0 33 64 20 23 0 18 0
15 1 0 0 0 0 0 0 0 2 0
16 0 0 0 0 0 1 0 0 0 0
17 0 0 0 0 0 0 0 0 18 0
18 0 0 0 0 21 0 6 0 0 0
19 0 0 0 0 5 7 0 0 1 0
20 0 9 0 1 3 0 0 0 0 0
21 0 4 0 5 1 0 0 0 0 0
22 0 0 2 0 18 0 0 12 1 0
23 0 0 9 0 0 0 0 0 0 0
24 1 0 0 0 0 0 0 3 0 0
25 0 0 0 14 0 0 0 9 3 3
26 79 0 0 0 0 0 0 0 0 0
27 0 0 0 0 3 0 0 1 0 0
28 0 0 6 0 0 0 0 0 0 0
29 0 1 0 0 0 0 0 0 0 0
30 0 0 0 0 0 0 0 0 0 63
177 0 0 0 4 0 0 0 0 0 0
178 0 0 0 0 0 0 0 5 0 0
179 0 0 9 16 10 0 0 0 0 0
180 0 0 0 12 5 0 0 0 0 0
181 0 0 0 1 0 0 0 0 0 0
182 0 0 0 0 0 0 0 0 0 0
183 0 0 0 0 6 0 0 2 0 0
184 0 0 0 0 9 0 0 0 0 0
185 0 2 0 0 0 0 1 0 0 0
186 0 0 6 0 0 0 0 0 0 6
187 0 0 0 0 0 0 3 0 0 0
188 0 0 0 10 0 0 0 0 10 0
189 5 0 18 0 0 0 0 24 0 0
190 0 4 0 4 14 0 1 0 0 0
191 0 0 0 1 0 0 0 0 0 0
192 0 0 0 0 0 0 5 0 0 0
193 0 0 0 0 16 0 16 0 5 0
194 0 0 7 0 0 17 0 0 0 0
195 0 0 3 0 0 0 0 1 0 4
196 0 0 0 4 1 7 0 0 11 0
197 25 0 0 0 0 7 0 0 0 0
198 0 0 0 0 0 0 2 0 0 0
199 0 0 0 1 16 0 0 0 0 0
200 0 0 0 2 5 0 0 0 0 0
201 0 0 0 1 23 0 0 0 0 0
202 0 9 0 6 7 0 0 4 0 0
203 0 0 0 0 6 0 0 2 0 0
204 0 0 0 0 0 0 6 2 0 0
205 0 0 0 0 11 0 0 0 0 0
206 0 0 1 0 0 0 0 0 0 0
  • 토픽트렌드를 살펴보기 위해선 시간의 흐름이 있어야 함
    • 또한 기준을 일 단위로 할건지, 월 단위로 할건지, 년 단위로 할건지 또한 미리 고려해야 함
    • 본 포스팅에서는 월 단위로 살펴볼 예정임
In [13]:
blog$date
  1. “2015.04.18 05:18”
  2. “2015.04.18 07:26”
  3. “2015.04.18 10:55”
  4. “2015.04.18 11:10”
  5. “2015.04.18 08:32”
  6. “2015.04.18 09:38”
  7. “2015.04.18 10:18”
  8. “2015.04.18 10:06”
  9. “2015.04.18 11:02”
  10. “2015.04.18 11:15”
  11. “2015.04.18 12:48”
  12. “2015.04.18 13:05”
  13. “2015.04.18 16:42”
  14. “2015.04.18 18:42”
  15. “2015.04.18 19:20”
  16. “2015.04.18 21:16”
  17. “2015.04.19 01:26”
  18. “2015.04.19 01:51”
  19. “2015.04.19 07:00”
  20. “2015.04.19 11:06”
  21. “2015.04.20 17:27”
  22. “2015.04.19 17:51”
  23. “2015.04.20 16:57”
  24. “2015.04.20 17:03”
  25. “2015.04.20 17:24”
  26. “2015.04.20 17:37”
  27. “2015.04.20 19:18”
  28. “2015.04.20 19:20”
  29. “2015.04.20 19:30”
  30. “2015.04.20 20:41”
  31. “2015.04.20 21:49”
  32. “2015.04.20 22:07”
  33. “2015.04.20 22:21”
  34. “2015.04.20 22:57”
  35. “2015.04.20 22:59”
  36. “2015.04.21 02:27”
  37. “2015.04.21 11:45”
  38. “2015.04.21 15:47”
  39. “2015.04.21 20:31”
  40. “2015.04.21 20:38”
  41. “2015.04.21 21:09”
  42. “2015.04.21 21:46”
  43. “2015.04.21 23:52”
  44. “2015.04.21 23:52”
  45. “2015.04.22 02:00”
  46. “2015.04.22 12:19”
  47. “2015.04.22 16:26”
  48. “2015.04.22 09:01”
  49. “2015.04.22 12:17”
  50. “2015.04.22 10:19”
  51. “2015.04.22 12:10”
  52. “2015.04.22 12:14”
  53. “2015.04.22 12:23”
  54. “2015.04.22 12:23”
  55. “2015.04.22 15:20”
  56. “2015.04.22 16:24”
  57. “2015.04.22 16:29”
  58. “2015.04.22 16:36”
  59. “2015.04.23 03:24”
  60. “2015.04.23 05:01”
  61. “2015.04.23 13:42”
  62. “2015.04.23 17:16”
  63. “2015.04.23 18:20”
  64. “2015.04.24 03:07”
  65. “2015.04.24 12:28”
  66. “2015.04.24 16:56”
  67. “2015.04.24 16:56”
  68. “2015.04.26 01:44”
  69. “2015.04.26 01:44”
  70. “2015.04.26 07:13”
  71. “2015.04.26 07:17”
  72. “2015.04.26 09:23”
  73. “2015.04.27 13:44”
  74. “2015.04.27 14:27”
  75. “2015.04.28 07:59”
  76. “2015.04.28 20:56”
  77. “2015.04.28 21:21”
  78. “2015.05.02 12:48”
  79. “2015.05.03 21:44”
  80. “2015.05.03 21:44”
  81. “2015.05.04 00:24”
  82. “2015.05.04 12:52”
  83. “2015.05.04 13:10”
  84. “2015.05.04 16:07”
  85. “2015.05.04 17:21”
  86. “2015.05.04 19:27”
  87. “2015.05.04 22:46”
  88. “2015.05.05 13:01”
  89. “2015.05.05 16:55”
  90. “2015.05.06 08:45”
  91. “2015.05.06 20:52”
  92. “2015.05.13 11:36”
  93. “2015.05.17 13:10”
  94. “2015.05.17 23:12”
  95. “2015.05.17 23:15”
  96. “2015.05.18 13:11”
  97. “2015.05.21 11:15”
  98. “2015.05.21 21:27”
  99. “2015.05.23 20:21”
  100. “2015.05.26 15:32”
  101. “2015.05.26 15:39”
  102. “2015.05.26 18:11”
  103. “2015.05.26 18:39”
  104. “2015.05.26 21:45”
  105. “2015.05.26 21:59”
  106. “2015.05.26 22:01”
  107. “2015.05.26 22:05”
  108. “2015.05.27 02:33”
  109. “2015.05.27 02:43”
  110. “2015.05.27 02:50”
  111. “2015.05.27 05:38”
  112. “2015.05.27 08:51”
  113. “2015.05.27 08:56”
  114. “2015.05.27 09:03”
  115. “2015.05.27 09:32”
  116. “2015.05.27 10:29”
  117. “2015.05.27 12:50”
  118. “2015.05.27 15:02”
  119. “2015.05.28 01:17”
  120. “2015.05.28 18:00”
  121. “2015.06.01 15:32”
  122. “2015.06.03 19:56”
  123. “2015.06.06 15:53”
  124. “2015.06.07 00:04”
  125. “2015.06.08 02:42”
  126. “2015.06.08 18:51”
  127. “2015.06.09 03:16”
  128. “2015.06.13 02:42”
  129. “2015.06.14 01:17”
  130. “2015.06.15 14:26”
  131. “2015.06.23 14:02”
  132. “2015.06.26 11:42”
  133. “2015.06.26 12:03”
  134. “2015.06.26 23:39”
  135. “2015.07.02 21:49”
  136. “2015.07.09 17:18”
  137. “2015.07.11 15:19”
  138. “2015.07.12 21:14”
  139. “2015.07.12 21:18”
  140. “2015.07.14 23:02”
  141. “2015.07.16 19:25”
  142. “2015.07.17 17:33”
  143. “2015.07.18 06:40”
  144. “2015.07.23 13:10”
  145. “2015.07.23 13:45”
  146. “2015.07.23 17:25”
  147. “2015.07.23 22:22”
  148. “2015.07.23 23:18”
  149. “2015.07.24 07:49”
  150. “2015.07.23 22:23”
  151. “2015.07.24 00:02”
  152. “2015.07.24 01:57”
  153. “2015.07.24 03:12”
  154. “2015.07.24 07:26”
  155. “2015.07.24 09:19”
  156. “2015.07.24 15:31”
  157. “2015.07.25 09:24”
  158. “2015.08.06 11:32”
  159. “2015.08.06 12:48”
  160. “2015.08.09 19:31”
  161. “2015.08.09 21:49”
  162. “2015.08.09 22:41”
  163. “2015.08.10 08:42”
  164. “2015.08.10 10:44”
  165. “2015.08.10 17:22”
  166. “2015.08.12 01:44”
  167. “2015.08.18 02:51”
  168. “2015.08.18 04:11”
  169. “2015.08.18 10:13”
  170. “2015.08.19 01:07”
  171. “2015.08.23 06:01”
  172. “2015.08.23 20:25”
  173. “2015.08.24 09:10”
  174. “2015.08.28 21:00”
  175. “2015.09.03 09:15”
  176. “2015.09.03 09:15”
  177. “2015.09.03 09:16”
  178. “2015.09.03 09:29”
  179. “2015.09.03 13:28”
  180. “2015.09.03 13:30”
  181. “2015.09.03 18:08”
  182. “2015.09.03 18:11”
  183. “2015.09.03 18:14”
  184. “2015.09.08 17:41”
  185. “2015.09.10 10:57”
  186. “2015.09.10 19:34”
  187. “2015.09.12 14:59”
  188. “2015.10.05 16:42”
  189. “2015.10.22 16:51”
  190. “2015.10.23 09:15”
  191. “2015.10.28 14:44”
  192. “2015.10.28 14:48”
  193. “2015.11.03 15:15”
  194. “2015.11.07 14:53”
  195. “2015.12.06 14:52”
  196. “2016.02.04 09:00”
  197. “2016.02.11 13:35”
  198. “2016.02.12 04:05”
  199. “2016.02.13 18:23”
  200. “2016.02.15 21:40”
  201. “2016.02.16 00:41”
  202. “2016.02.16 17:14”
  203. “2016.02.20 19:32”
  204. “2016.02.25 22:09”
  205. “2016.03.04 17:14”
  206. “2016.04.02 21:44”
  • 시간을 제거하고 년/월 단위만 남기기
    • 데이터 타입을 Date 형식으로 바꿔줘야 이후 계산이 편함
In [14]:
date<-unlist(strsplit(blog$date," "))[1:length(blog$date)%%2==1]
head(date)
  1. “2015.04.18”
  2. “2015.04.18”
  3. “2015.04.18”
  4. “2015.04.18”
  5. “2015.04.18”
  6. “2015.04.18”
In [15]:
str(date)
 chr [1:206] "2015.04.18" "2015.04.18" "2015.04.18" "2015.04.18" ...
In [16]:
date<-as.Date(date,format("20%y.%m.%d"))
In [17]:
str(date)
 Date[1:206], format: "2015-04-18" "2015-04-18" "2015-04-18" "2015-04-18" ...
In [18]:
date<-format(date,"%Y-%m")
date
  1. “2015-04”
  2. “2015-04”
  3. “2015-04”
  4. “2015-04”
  5. “2015-04”
  6. “2015-04”
  7. “2015-04”
  8. “2015-04”
  9. “2015-04”
  10. “2015-04”
  11. “2015-04”
  12. “2015-04”
  13. “2015-04”
  14. “2015-04”
  15. “2015-04”
  16. “2015-04”
  17. “2015-04”
  18. “2015-04”
  19. “2015-04”
  20. “2015-04”
  21. “2015-04”
  22. “2015-04”
  23. “2015-04”
  24. “2015-04”
  25. “2015-04”
  26. “2015-04”
  27. “2015-04”
  28. “2015-04”
  29. “2015-04”
  30. “2015-04”
  31. “2015-04”
  32. “2015-04”
  33. “2015-04”
  34. “2015-04”
  35. “2015-04”
  36. “2015-04”
  37. “2015-04”
  38. “2015-04”
  39. “2015-04”
  40. “2015-04”
  41. “2015-04”
  42. “2015-04”
  43. “2015-04”
  44. “2015-04”
  45. “2015-04”
  46. “2015-04”
  47. “2015-04”
  48. “2015-04”
  49. “2015-04”
  50. “2015-04”
  51. “2015-04”
  52. “2015-04”
  53. “2015-04”
  54. “2015-04”
  55. “2015-04”
  56. “2015-04”
  57. “2015-04”
  58. “2015-04”
  59. “2015-04”
  60. “2015-04”
  61. “2015-04”
  62. “2015-04”
  63. “2015-04”
  64. “2015-04”
  65. “2015-04”
  66. “2015-04”
  67. “2015-04”
  68. “2015-04”
  69. “2015-04”
  70. “2015-04”
  71. “2015-04”
  72. “2015-04”
  73. “2015-04”
  74. “2015-04”
  75. “2015-04”
  76. “2015-04”
  77. “2015-04”
  78. “2015-05”
  79. “2015-05”
  80. “2015-05”
  81. “2015-05”
  82. “2015-05”
  83. “2015-05”
  84. “2015-05”
  85. “2015-05”
  86. “2015-05”
  87. “2015-05”
  88. “2015-05”
  89. “2015-05”
  90. “2015-05”
  91. “2015-05”
  92. “2015-05”
  93. “2015-05”
  94. “2015-05”
  95. “2015-05”
  96. “2015-05”
  97. “2015-05”
  98. “2015-05”
  99. “2015-05”
  100. “2015-05”
  101. “2015-05”
  102. “2015-05”
  103. “2015-05”
  104. “2015-05”
  105. “2015-05”
  106. “2015-05”
  107. “2015-05”
  108. “2015-05”
  109. “2015-05”
  110. “2015-05”
  111. “2015-05”
  112. “2015-05”
  113. “2015-05”
  114. “2015-05”
  115. “2015-05”
  116. “2015-05”
  117. “2015-05”
  118. “2015-05”
  119. “2015-05”
  120. “2015-05”
  121. “2015-06”
  122. “2015-06”
  123. “2015-06”
  124. “2015-06”
  125. “2015-06”
  126. “2015-06”
  127. “2015-06”
  128. “2015-06”
  129. “2015-06”
  130. “2015-06”
  131. “2015-06”
  132. “2015-06”
  133. “2015-06”
  134. “2015-06”
  135. “2015-07”
  136. “2015-07”
  137. “2015-07”
  138. “2015-07”
  139. “2015-07”
  140. “2015-07”
  141. “2015-07”
  142. “2015-07”
  143. “2015-07”
  144. “2015-07”
  145. “2015-07”
  146. “2015-07”
  147. “2015-07”
  148. “2015-07”
  149. “2015-07”
  150. “2015-07”
  151. “2015-07”
  152. “2015-07”
  153. “2015-07”
  154. “2015-07”
  155. “2015-07”
  156. “2015-07”
  157. “2015-07”
  158. “2015-08”
  159. “2015-08”
  160. “2015-08”
  161. “2015-08”
  162. “2015-08”
  163. “2015-08”
  164. “2015-08”
  165. “2015-08”
  166. “2015-08”
  167. “2015-08”
  168. “2015-08”
  169. “2015-08”
  170. “2015-08”
  171. “2015-08”
  172. “2015-08”
  173. “2015-08”
  174. “2015-08”
  175. “2015-09”
  176. “2015-09”
  177. “2015-09”
  178. “2015-09”
  179. “2015-09”
  180. “2015-09”
  181. “2015-09”
  182. “2015-09”
  183. “2015-09”
  184. “2015-09”
  185. “2015-09”
  186. “2015-09”
  187. “2015-09”
  188. “2015-10”
  189. “2015-10”
  190. “2015-10”
  191. “2015-10”
  192. “2015-10”
  193. “2015-11”
  194. “2015-11”
  195. “2015-12”
  196. “2016-02”
  197. “2016-02”
  198. “2016-02”
  199. “2016-02”
  200. “2016-02”
  201. “2016-02”
  202. “2016-02”
  203. “2016-02”
  204. “2016-02”
  205. “2016-03”
  206. “2016-04”
In [19]:
blog$date<-date
  • 토픽 비율 구하기
      • 수식

In [20]:
tot<-rowSums(trends)
In [21]:
trends
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 0 1 5 0 0 0 0 3 2 0
2 0 0 3 0 0 1 0 4 5 0
3 0 0 0 0 0 0 6 1 0 0
4 0 0 0 0 0 0 0 4 2 0
5 0 0 1 0 0 0 3 18 0 0
6 24 0 11 0 6 0 0 29 0 0
7 0 0 18 0 23 0 0 0 0 0
8 0 0 2 0 0 0 0 0 0 0
9 0 11 0 0 9 0 0 13 0 0
10 0 0 3 0 4 0 6 0 0 0
11 0 0 0 20 11 24 17 0 13 0
12 0 0 0 0 6 0 0 0 11 0
13 0 3 0 0 29 0 4 23 32 0
14 2 0 0 33 64 20 23 0 18 0
15 1 0 0 0 0 0 0 0 2 0
16 0 0 0 0 0 1 0 0 0 0
17 0 0 0 0 0 0 0 0 18 0
18 0 0 0 0 21 0 6 0 0 0
19 0 0 0 0 5 7 0 0 1 0
20 0 9 0 1 3 0 0 0 0 0
21 0 4 0 5 1 0 0 0 0 0
22 0 0 2 0 18 0 0 12 1 0
23 0 0 9 0 0 0 0 0 0 0
24 1 0 0 0 0 0 0 3 0 0
25 0 0 0 14 0 0 0 9 3 3
26 79 0 0 0 0 0 0 0 0 0
27 0 0 0 0 3 0 0 1 0 0
28 0 0 6 0 0 0 0 0 0 0
29 0 1 0 0 0 0 0 0 0 0
30 0 0 0 0 0 0 0 0 0 63
177 0 0 0 4 0 0 0 0 0 0
178 0 0 0 0 0 0 0 5 0 0
179 0 0 9 16 10 0 0 0 0 0
180 0 0 0 12 5 0 0 0 0 0
181 0 0 0 1 0 0 0 0 0 0
182 0 0 0 0 0 0 0 0 0 0
183 0 0 0 0 6 0 0 2 0 0
184 0 0 0 0 9 0 0 0 0 0
185 0 2 0 0 0 0 1 0 0 0
186 0 0 6 0 0 0 0 0 0 6
187 0 0 0 0 0 0 3 0 0 0
188 0 0 0 10 0 0 0 0 10 0
189 5 0 18 0 0 0 0 24 0 0
190 0 4 0 4 14 0 1 0 0 0
191 0 0 0 1 0 0 0 0 0 0
192 0 0 0 0 0 0 5 0 0 0
193 0 0 0 0 16 0 16 0 5 0
194 0 0 7 0 0 17 0 0 0 0
195 0 0 3 0 0 0 0 1 0 4
196 0 0 0 4 1 7 0 0 11 0
197 25 0 0 0 0 7 0 0 0 0
198 0 0 0 0 0 0 2 0 0 0
199 0 0 0 1 16 0 0 0 0 0
200 0 0 0 2 5 0 0 0 0 0
201 0 0 0 1 23 0 0 0 0 0
202 0 9 0 6 7 0 0 4 0 0
203 0 0 0 0 6 0 0 2 0 0
204 0 0 0 0 0 0 6 2 0 0
205 0 0 0 0 11 0 0 0 0 0
206 0 0 1 0 0 0 0 0 0 0
In [22]:
str(trends)
'data.frame':  206 obs. of  10 variables:
 $ V1 : int  0 0 0 0 0 24 0 0 0 0 ...
 $ V2 : int  1 0 0 0 0 0 0 0 11 0 ...
 $ V3 : int  5 3 0 0 1 11 18 2 0 3 ...
 $ V4 : int  0 0 0 0 0 0 0 0 0 0 ...
 $ V5 : int  0 0 0 0 0 6 23 0 9 4 ...
 $ V6 : int  0 1 0 0 0 0 0 0 0 0 ...
 $ V7 : int  0 0 6 0 3 0 0 0 0 6 ...
 $ V8 : int  3 4 1 4 18 29 0 0 13 0 ...
 $ V9 : int  2 5 0 2 0 0 0 0 0 0 ...
 $ V10: int  0 0 0 0 0 0 0 0 0 0 ...
In [23]:
trends<-trends/tot
  • 해당 변수를 상기 문서별 빈도 항목에 조인
In [24]:
for(i in 1:ncol(trends)){
    trends[,i][is.nan(trends[,i])]<-0
}
In [25]:
trends$date<-blog$date
In [26]:
colnames(trends)<-c(paste("Topic",1:10),"date")
In [27]:
str(trends)
'data.frame':  206 obs. of  11 variables:
 $ Topic 1 : num  0 0 0 0 0 ...
 $ Topic 2 : num  0.0909 0 0 0 0 ...
 $ Topic 3 : num  0.4545 0.2308 0 0 0.0455 ...
 $ Topic 4 : num  0 0 0 0 0 0 0 0 0 0 ...
 $ Topic 5 : num  0 0 0 0 0 ...
 $ Topic 6 : num  0 0.0769 0 0 0 ...
 $ Topic 7 : num  0 0 0.857 0 0.136 ...
 $ Topic 8 : num  0.273 0.308 0.143 0.667 0.818 ...
 $ Topic 9 : num  0.182 0.385 0 0.333 0 ...
 $ Topic 10: num  0 0 0 0 0 0 0 0 0 0 ...
 $ date    : chr  "2015-04" "2015-04" "2015-04" "2015-04" ...
In [28]:
trends_month<-aggregate(trends,list(trends$date),FUN=mean)
Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"Warning message in mean.default(X[[i]], ...):
"argument is not numeric or logical: returning NA"
In [29]:
trends_month
Group.1 Topic 1 Topic 2 Topic 3 Topic 4 Topic 5 Topic 6 Topic 7 Topic 8 Topic 9 Topic 10 date
1 2015-04 0.0793968904893884 0.0528391157939827 0.136716236876628 0.0752850405786972 0.196978093326653 0.0537135727757259 0.0776765207301671 0.0982045832040327 0.0970428183244726 0.132147127900253 NA
2 2015-05 0.0570373753963607 0.0243327652278947 0.0744564442287837 0.0922455256524787 0.201379106066506 0.0638904123766745 0.0857503498619204 0.132854628152255 0.109407267111734 0.135390311971904 NA
3 2015-06 0.115125448028674 0.0901282051282051 0.0952690166975881 0.00793650793650794 0.245895195434366 0.0480286738351254 0.135319582378406 0.0714285714285714 0.134846390168971 0.0560224089635854 NA
4 2015-07 0.102484472049689 0.0215757317419722 0.132539278388114 0.049580472921434 0.200778550923658 0.0873437775039606 0.0483478260869565 0.171505496791538 0.0899096109839817 0.0524565217391304 NA
5 2015-08 0.0457332541670804 0.07934601880743 0.0621657903143021 0.0323126300090512 0.356577222260576 0.0461326593925453 0.0534502262443439 0.125394329839852 0.0952004452773949 0.103687423687424 NA
6 2015-09 0 0.0512820512820513 0.0582417582417582 0.320232708468003 0.179217840982547 0.0576923076923077 0.102564102564103 0.0961538461538462 0.0192307692307692 0.0384615384615385 NA
7 2015-10 0.0212765957446809 0.0347826086956522 0.0765957446808511 0.334782608695652 0.121739130434783 0 0.208695652173913 0.102127659574468 0.1 0 NA
8 2015-11 0 0 0.145833333333333 0 0.216216216216216 0.354166666666667 0.216216216216216 0 0.0675675675675676 0 NA
9 2015-12 0 0 0.375 0 0 0 0 0.125 0 0.5 NA
10 2016-02 0.0868055555555556 0.0384615384615385 0 0.0878763062266899 0.408500505367513 0.0581219806763285 0.194444444444444 0.0726495726495727 0.0531400966183575 0 NA
11 2016-03 0 0 0 0 1 0 0 0 0 0 NA
12 2016-04 0 0 1 0 0 0 0 0 0 0 NA
In [30]:
trends_month$date<-NULL
In [31]:
str(trends_month)
'data.frame':  12 obs. of  11 variables:
 $ Group.1 : chr  "2015-04" "2015-05" "2015-06" "2015-07" ...
 $ Topic 1 : num  0.0794 0.057 0.1151 0.1025 0.0457 ...
 $ Topic 2 : num  0.0528 0.0243 0.0901 0.0216 0.0793 ...
 $ Topic 3 : num  0.1367 0.0745 0.0953 0.1325 0.0622 ...
 $ Topic 4 : num  0.07529 0.09225 0.00794 0.04958 0.03231 ...
 $ Topic 5 : num  0.197 0.201 0.246 0.201 0.357 ...
 $ Topic 6 : num  0.0537 0.0639 0.048 0.0873 0.0461 ...
 $ Topic 7 : num  0.0777 0.0858 0.1353 0.0483 0.0535 ...
 $ Topic 8 : num  0.0982 0.1329 0.0714 0.1715 0.1254 ...
 $ Topic 9 : num  0.097 0.1094 0.1348 0.0899 0.0952 ...
 $ Topic 10: num  0.1321 0.1354 0.056 0.0525 0.1037 ...
  • 시각화 하기
In [32]:
library(ggplot2)
p<-ggplot(trends_month,aes(x=Group.1))
trends_plot<-p+geom_line(aes(y=`Topic 1`,group=1),color="red")+
  geom_line(aes(y=`Topic 2`,group=1),color="brown")+
  geom_line(aes(y=`Topic 3`,group=1),color="blue")+
  geom_line(aes(y=`Topic 4`,group=1),color="yellow")+
  geom_line(aes(y=`Topic 5`,group=1),color="green")+
  geom_line(aes(y=`Topic 6`,group=2),color="orange")+
  geom_line(aes(y=`Topic 7`,group=2),color="purple")+
  geom_line(aes(y=`Topic 8`,group=2),color="aquamarine1")+
  geom_line(aes(y=`Topic 9`,group=2),color="black")+
  geom_line(aes(y=`Topic 10`,group=2),color="cyan")+
  ylab("Topics") + xlab("")+ ggtitle("Topic Trends")
Attaching package: 'ggplot2'

The following object is masked from 'package:NLP':

    annotate

In [33]:
trends_plot

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다