[R] 감성사전을 활용한 감성분석

감성 사전을 활용한 감성분석

  • Sentiment Indicators
    pn
        Polarity=pnp+n
        Subjectivity=n+pN
        pos_refs_per_ref=pN
        neg_refs_per_ref=nN
       senti_diffs_per_ref=pnN
      (p: 긍정단어, n: 부정단어, N: 전체단어)

 

  • 본 분석에서는 polarity를 사용하기로 함
  • 긍정/부정 사전 부르기
    • 해당 사전은 서울대 컴퓨터 언어학과에서 만든 KOSAC 기반의 Korean Sentiment Lexicon에서 한 단어 단위의 각 감정일 확률이 50%이상인 단어들
In [2]:
pos.dic <- scan("pos_dic.txt",what="character")
neg.dic <- scan("neg_dic.txt",what="character")
In [3]:
head(pos.dic)
  1. ‘가/VX’
  2. ‘가격/NNG’
  3. ‘가꾸/VV’
  4. ‘가늠/NNG’
  5. ‘가도/NNG’
  6. ‘가리/VV’
  • 분석할 파일 부르기
In [4]:
library(readxl)
blog <- read_excel("after_POS.xlsx",1)
In [6]:
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 [16]:
library(stringr)
  • 각 문서 별로 사전에 포함된 단어의 갯수 count
In [18]:
pos=0

for(word in pos.dic){
    pos_match = str_count(blog$article_POS,word)
    pos = pos+pos_match
}
In [20]:
neg=0

for(word in neg.dic){
    neg_match = str_count(blog$article_POS,word)
    neg = neg+neg_match
}
  • senti_diff 알아보기
In [25]:
score = pos-neg
In [26]:
blog$sent_score <- score
  • polarity를 위한 p+n 구하기
In [27]:
tot = pos+neg
In [28]:
blog$sent = score/tot
In [29]:
str(blog)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':  206 obs. of  8 variables:
 $            : chr  "1" "2" "3" "4" ...
 $ a*****     : chr  "ㅁ**" "ㅋ**" "녹***" "맥****" ...
 $ 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__ ...
 $ date       : Date, format: "2015-04-18" "2015-04-18" ...
 $ time       : chr  "05:18" "07:26" "10:55" "11:10" ...
 $ sent_score : num  4 9 9 4 9 30 5 1 -6 2 ...
 $ sent       : num  0.286 0.529 1 0.667 0.243 ...
  • polarity 값
In [56]:
cat("PROS: ",sum(blog$sent>0,na.rm=T))
POS:  135
In [57]:
cat("CONS: ",sum(blog$sent<=0,na.rm=T))
CONS:  70
  • 단순 word count 값과 비교
In [58]:
cat("PROS: ",sum(blog$sent_score>0))
PROS:  135
In [60]:
cat("PROS: ",sum(blog$sent_score<=0))
PROS:  71
  • NaN 값 데이터 살펴보기
In [61]:
blog[is.na(blog$sent),]
a***** desc article_POS date time sent_score sent
142 142 흉** ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 에휴ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ/EMO;에휴/UN;ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ/EMO; 2015-07-17 17:33 0 NaN

댓글 남기기

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