본문으로 바로가기


2017년 1월 5일 날씨 맑음 


| 들어가며

지난 한해도 정리할 겸 Facebook에 작성했던 글을 한번 뽑아 보고 싶어졌다.

사실 예전에 R로 워드 클라우드 그렸던 거라 기억이 가물가물해 과거에 작성했던 교육내용하고 

최근 KoNLP가 0.80으로 업데이트 되었다는 소식에 전희원님의 글을 참고해 다시 뽑아봤다.



  KoNLP v.0.80.0 릴리즈 소식 : http://freesearch.pe.kr/archives/4520


참고로 0.80의 개선 포인트로 성능개선은 말할것도 없고, 버그 수정,  형태소 사전 추가 적용,  텍스트 전처리 플러그인 등이 추가되었다고 한다. 추후 RNN 을 연결하는 것을 생각하신다고 하니 R을 기반으로 텍스트 마이닝을 하시는 분들에게는 좋은 소식이지 않을까?



| 패키지 설치와 Facebook  토큰 받기


우선 워드 클라우드를 하기에 앞서 필요한 패키지를 설치 해야 한다.


install.packages(c('Rfacebook', 'KoNLP', 'wordcloud2'))

library(Rfacebook)

library(KoNLP)

library(wordcloud2)




그리고 Facebook 에서 데이터를 긁어오기 위해서는 Facebook 에서 제공하는 API를 통해 가져오면 되는데 

facebook developer 사이트에 들어가서 토큰을 받아야 한다.


  facebook developer URL : https://developers.facebook.com/tools/explorer



URL 치고 들어가게 되면 아래와 같이 액세스 토큰창이 뜨게 되는데 우측에 토큰 받기 > 사용자 엑세스 토큰받기를 누르른다.






사용자 액세스 토큰받기를 누르면 받고자 하는 정보들을 선택하는 창이 나오는데 적절하게 필요로 하는 내용들을 선택후 [엑세스토큰받기] 를 누른다.




그리고 마지막으로 액세스토큰을 copy 하면 되는데 copy 한 액세스토큰이 R에서 Facebook에 접근해 데이터를 가져오는 key 가 된다. 

일단 R에 토큰을 기록한다. 



Token <- '토큰정보'






| API로 Facebook 데이터 요청 


다음은 Facebook API를 이용해 작성한 글을 가져온다.


    fb_page <- getPage(page="me", token=token, n=2000, since='2016/01/01', until='2016/12/15')



    - getPage에 me는 자신의 정보를 가져온다는 것으로 me 그대로 적으면 된다.

    - token에는 token 값이 들어가고 

    - n 은 최대 가져올 post 정보 개수를 말하는 것으로 여기서는 2000를 최대한으로 했다.   헤비 유저이거나 자신의 노트북 램 용량이 크다면 더 많이 가져오는것도 무리는 안될듯 싶다.

    - since 와 until 은 내가 가져오려는 데이터의 기간을 말한다.




다 가져왔으면 fb_page$message 로 작성한 글을 정확하게 가져왔는지 확인한다.

fb_page$message


혹 이상한 숫자나 깨진 문자로 나온다면 인코딩이 맞지 않아서 생기는 문제인데

Encoding(fb_page$message) 을 쳤을 때 나오는 인코딩과

localeToCharset()  을 쳤을때 나오는 인코딩이 다를 경우 발생한다.

이를 해결하기 위해서 

Encoding(fb_page$message) <- "UTF-8"

을 추가하고 다시 시도해본다




| 전처리


정상적으로 보인다면 이제는 분석을 위한 형태소 사전을 다운 받는다

> useNIADic() ##형태소 다운로드



그리고 message 에서 이상치를 제거하고 명사만 추출한다.


all.reviews <- fb_page$message

all.reviews <- all.reviews[!is.na(all.reviews)]  ## na 값 제거


nouns <- extractNoun(all.reviews)  ##명사 추출

nouns_norm <- Map(function(x){if(!is.na(x) && is.ascii(x)) toupper(x) else x},unlist(nouns))  ##불필요 데이터 삭제




| Word cloud 출력


끝으로 word cloud를 출력하면 되는데 여기서는 wordcloud2를 사용했다.


cnts <- table(unlist(nouns_norm))  ## 명사별 count 결과 저장

cnts_ <- cnts[cnts > 2 & nchar(names(cnts)) > 1]  ## 단어가 1보다 크며, 건수가 2보다 큰 것만 선별


wordcloud2(data.frame(word=names(cnts_), freq=as.numeric(cnts_)),  color = "random-light", backgroundColor = "black", shape="cloud")



출력결과



출력 결과를 보면 빈도수에 따라 글씨 크기가 달라지고 색상은 random 값에 의해 조절이 된 것을 확인할 수 있다.

근데 나는 지난 한해 엄청 웃었나보다...   ;;



|결론


그 어려울것 같았던(?) 워드 클라우드가 코드 몇줄로 너무도 쉽게 끝나버렸다... 

이제 살짝 텍스트마이닝에 Hello world 격인 워드클라우드를 했다고 보면 된다.

다음에는 다시 기억을 더듬어 감성분석 방법을 적어볼까 한다.  



|전체코드


install.packages(c('Rfacebook', 'KoNLP', 'wordcloud2'))

library(Rfacebook)

library(KoNLP)

library(wordcloud2)



token <- '토큰정보'

fb_page <- getPage(page="me", token=token, n=2000, since='2016/01/01', until='2016/12/15')

fb_page$message  # 확인결과 한글 깨짐 발생

Encoding(fb_page$message) #인코디 확인  --  UTF-8 

localeToCharset()  ## system 인코딩 확인

Sys.setlocale("LC_ALL", "en_US.UTF-8")   ## 인코딩 변경

useNIADic() ##형태소 다운로드

all.reviews <- fb_page$message

all.reviews <- all.reviews[!is.na(all.reviews)]  ## na 값 제거


nouns <- extractNoun(all.reviews)  ##명사 추출

nouns_norm <- Map(function(x){if(!is.na(x) && is.ascii(x)) toupper(x) else x},unlist(nouns))  ##불필요 데이터 삭제

cnts <- table(unlist(nouns_norm))  ## 명사별 count 결과 저장

cnts_ <- cnts[cnts > 2 & nchar(names(cnts)) > 1]

wordcloud2(data.frame(word=names(cnts_), freq=as.numeric(cnts_)),  color = "random-light", backgroundColor = "black", shape="cloud")



[참고자료]

전희원님 site 페이스북 포스트 워드클라우로 돌아보는 2016년 : http://freesearch.pe.kr/archives/4538

마인드스케일 텍스트마이닝 sns 데이터 분석 강의자료


[추가 질문사항의 답변]

Scarly 님이 주신 추가 질문사항 : NiaDic을 다운 받을 수 없는 경우 어떡게 해야 하나요? 


?useNIADic()을 쳐보면 KoNLP의 function 임을 할 수 있다.

useNiaDic에 관련한 소스가 보고 싶다면  다음을 참고해도 좋다

https://github.com/haven-jeon/NIADic/


먼저  NiaDic 이 정상적으로 설치가 되었다면  다음의 명령어를 쳤을 때 경로가 나와야 한다.

예) > system.file(package = 'NIADic')

[1] "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/NIADic"

      

만약 경로가 "" 으로만 나온다면 정상적으로 설치되지 않은 상태인데 이 때는 NIADic tar.gz 파일을 수동을 받아 수작업 설치를 진행해야 한다.

NIADic 의 tar.gz 파일경로는 다음과 같다. 

 https://github.com/haven-jeon/NIADic/releases/download/0.0.1/NIADic_0.0.1.tar.gz


위 경로는 버전에 따라 바뀔 수 있는데 정확한 경로가 알고 싶다면 

https://github.com/haven-jeon/KoNLP/blob/master/R/manageDic.R

의 최 하단에 실제 다운 받는 곳이 나와 있다.


다운로드를 다 했으면 이제 명령어 한번만 더 치면 된다. 


> install.packages('/Users/josh/r_study/NIADic_0.0.1.tar.gz', repos = NULL, type="source")


이제 마지막으로 정상적으로 설치가 되었는지 확인해 본다. 


> system.file(package = 'NIADic')


끝으로, 현업에서 네트워크가 연결되지 않아 install.packages 로 설치되지 않을 때가 많이 있다. 

이럴때도 마찬가지로 수작업 설치를 진행해야 하는데 이 부분은 아래의 블로그를 확인하면 많은 도움을 받을 수 있다. 


▶ http://rfriend.tistory.com/177






도움이 되셨다면 공감버튼을 살포시~



댓글을 달아 주세요

  1. BlogIcon Scarly 2017.01.22 18:12 신고

    유용한 자료 감사합니다 그런데 형태소 다운이 안되면 어떡해야할까요~?

    • BlogIcon 쿡북 쿡북 2017.01.24 00:50 신고

      안녕하세요? 좋은 질문 해주셨네요. 질문에 대한 답변은 해당 블로깅 하단에 추가해서 적어 놓겠습니다.
      감사합니다.

  2. ryan 2017.02.08 10:32

    설명 감사합니다. 하나하나씩 따라해보려고하는 초보인데. . 페이스북에서 엑세스토큰을 받기까지는 했는데 이 토큰을 R에 기록하는건 말그대로 복사해서 붙여넣기하는건가요?

  3. BlogIcon 쿡북 쿡북 2017.02.08 10:32 신고

    네 복붙 맞습니다. 토큰 그대로 복붙 해주세요

  4. ryan 2017.02.08 10:40

    그대로 붙여넣기를 하면 에러가나서요 ㅠㅠ
    Error: object 'EAACEdEose0cBAHihnbGhrMDmbPZAbViZBMgF7TZBwaEZCPcbG1xlFJ9ZATGMcbHEAFaZAnVBfJVm2wYZCnZASdrpZCbWHEnBS8y04NYOGDlIHvMyAf2PdQuSgZA2pSFOEanFcH8ZAHNWxo8ZAt8EZCZBipiC18yyYuAe1xixq0ko7cvVBB95Uol9tGpCvyRFfvXo4ip8wZD' not found

  5. BlogIcon 쿡북 쿡북 2017.02.08 10:44 신고

    음 이상하네요. 본인 계정에 토큰이 만료된게 아니라면 not found가 나지 않을텐데... 토큰 다시 받기 하신다음에 해보시면 될 것 같습니다. 저는 토큰에서 에러난 적은 없어서요.

  6. go 2017.02.14 09:55

    토큰 붙여넣기하면 저도 여지없이 에러가 뜨네요 뭐가 잘못된건지....;;;

    • BlogIcon 쿡북 쿡북 2017.02.14 10:03 신고

      그렇군요~ 에러로스 첨부해주시면 저도 따로 확인해 보겠습니다 그 사이 뭔가 바뀌었나보네요

    • GO 2017.02.14 11:07

      아 토큰 정보에 큰따온표("")를 안쳐서 에러가 났었네요...;;
      근데
      > facebook<-getPage(page = "me",token=token,n=2000,since = '2017/02/10',until = '2017/02/14')
      Error: could not find function "getPage"
      이 에러는 왜 나올까요?

    • BlogIcon 쿡북 쿡북 2017.02.14 11:16 신고

      혹시 library(Rfacebook) 제대로 올라온건지 확인 부탁드릴게요 ^^ getPage 는 그쪽 라이브러리 라서 혹 이름이 충돌난게 있짐 않을지.. 확인이 필요하겠네요

  7. GO 2017.02.14 13:00

    아~ 바쁘심에도 불구하고 조언 해주셔서 결국은 완성은 했네요;;감사합니다 그런데 궁금한게 제 탐임라인의 글만 보이던데 제 페북 친구들 글까지 같이 크롤링 가능 한가요 ?

    • BlogIcon 쿡북 쿡북 2017.02.14 13:05 신고

      사실 facebook은 크롤링이라기 보다 API로 가져오는거라 열려있지 않으면 가져올 수가 없습니다. facebook API확인하셔서 같은 방법으로 get하시면 될것 같긴한데 정책적으로 막혀있지 않을까 하네요. 웹에서 크롤링하는 방법은 제가 올려 놓은 영화 평점 댓들이나 기타 클롤링 문법 참고하셔서 가져오셔야 할것 같네요 감사합니다

  8. GO 2017.02.14 17:05

    마지막으로 하나만 더 여쭤 볼께요 cnts_<-cnts[cnts>2&nchar(names(word))>1] 이렇게 써져있던데 cnt는 변수 아닌가요? 변수가 한번에 세번이나 들어가서 좀 헷갈리네요..;; 이럴때는 필터를 사용하여 걸러내는 방법은 없나요?

  9. 멍구 2017.03.25 12:29

    제가 getPage를 해서 post id를 받아온 다음에 각 포스트에 있는 comments태그에 있는 message들을 for문을 이용해서 한 변수에 paste0를 이용해서 몰아넣은 다음에 그 변수를 이용해서 명사 추출하고 워드 클라우드를 만들려고 햇는데 extractNoun 부분에서 명사추출이 안이루어지는데 그 이유를 모르겠습니다;; 그냥 getPage 긁어온다음에 message에서 명사 추출하면 명사추출이 되는데 저렇게는 안되네요. 이유가 뭔지 궁금합니다.

  10. BlogIcon 열정가이 2017.05.10 18:39

    다른사람 facebook의 뉴스피드를 보려면 어떻게 해야 하나요?

    • BlogIcon 쿡북 쿡북 2017.05.11 18:18 신고

      답변이 늦었네요. 제가 알기로 facebook api로는 타인의 글을 읽는것은 오픈하지 않은걸로 알고 있습니다. 일단 권한도 없거니와 트래픽 문제로 오픈을 안했을듯 하네요. 혹여 웹 크롤링 방식으로 가져올 수 있을지는 모르겠으나 채계적인 수집은 쉽지 않아보이네요

  11. 석당 2017.06.17 12:35

    유용한 글 감사합니다

  12. cke45 2017.11.29 20:08

    R을 공부하고 있는 초보자 입니다. 전체 공개 포스트를 분석하고 있는데
    nouns_norm <- Map(function(x){if(!is.na(x) && is.ascii(x)) toupper(x) else x},unlist(nouns))
    이부분에서 Error in is.ascii(x) : Input must be legitimate character!라고 어떡해야 할까요?

    • allen_choi 2019.11.05 20:30

      각 벡터안에 담긴 문장의 앞뒤 공배을 제거하고 하니 저는 되네요. 한번 시도해보세요

      * 공백 제거 관련 url :
      https://riptutorial.com/ko/r/example/20317/%EA%B3%B5%EB%B0%B1-%EC%A0%9C%EA%B1%B0

  13. Kim sook 2018.02.06 21:46

    > wordcloud2(data.frame(word=names(cnts_), freq=as.numeric(cnts_)), color = "random-light", backgroundColor = "black", shape="cloud")
    Error in `[.data.frame`(data, , 1:2) : undefined columns selected

    이런 에러가 나는데 도무지 모르겠어요 ㅠㅠ

  14. 김무스 2018.11.09 15:25

    제 페이스북 데이터 말고 유명인사들 데이터 끌어오려면 어떻게 해야하나요?