############R로하는 감성분석
############네이버 맛집 리뷰 데이터로서 0~5점 사이 척도로 scoring 되어있습니다.
setwd("C:\\taling\\감성분석") ## Working Directory 설정
load("comments.RData") ## 데이터를 load합니다.
load("score.RData")
head(comments) ## 데이터 확인, length확인
head(score)
length(comments)
length(score)
sam<-sample(1:length(comments),5000) ## 5000개만 sampling해서 합니다. 전체데이터는 너무 많아서.
co_sam<-comments[sam]
score_sam<-score[sam]
#########################
##Supervised Learning방법으로 감성분석 하기
##이 예에서는 Lasso와 Ridge를 사용하지만 같은 형태로 다른 알고리즘을 사용하실 수 있습니다.
ibrary(stringr)
## 편의상 형태소 분석을 하지 않고 공백으로 분리하여 진행합니다.
ta<-table(unlist(str_split(co_sam," ")))
head(ta,30)
ta2<-ta[ta> 20] ## 단어 빈도 20개이상인것들만 추출
df<-data.frame(matrix(0,ncol=length(ta2),nrow=length(sam))) ## Document Term Matrix 생성, 학습에 사용될 input data
colnames(df)<-names(ta2) ## 칼럼 name은 앞서 추출한 word들
head(df)
i<-1
for(i in 1:length(sam)){
uu<- unlist(str_split(co_sam[i]," ")) ## review를 불러들여 공백으로 분리 후,
df[i,which(colnames(df) %in% uu)]<-1 ## 칼럼 name과 일치하는 index에 1 부여
cat("\n",i)
}
df2<-df[!apply(df,1,sum)==0,] ## 모든 칼럼이 0인 경우는 학습에 필요하지 않으므로 제거
score_sam2<- score_sam[!apply(df,1,sum)==0] ## Y에서도 제거
nrow(df2);length(score_sam2)
save(df2,file="df2.RData") ## 저장
save(score_sam2,file="score_sam2.RData")
load("df2.RData")
load("score_sam2.RData")
new_score<-ifelse(score_sam2 >2.5,1,0) ## 2.5이상이면 긍정(1), 아니면 부정(0)
library(glmnet)
### 학습에 사용할 알고리즘(Lasso, Ridge) library 호출
sam2<-sample(1:length(new_score),length(new_score)*0.7) ## Train / Validation으로 나누기 위한 작업
fit1<-glmnet(as.matrix(df2[sam2,]),new_score[sam2],family="binomial",lambda=0.001,alpha = 1) ## 모델fitting
## alpha 가 1일때 lasso
### lambda 값에 따라 계수들을 0으로 만듦
## alpha 가 0일때 ridge
### lambda 값에 따라 계수들을 0으로 수렴시키지만 완전히 0으로 만들지는 않음
### 예측면에서는 ridge가 일반적으로 좋고, 변수를 선택한다고 한다면 lasso가 좀더 좋음
pr<-predict(fit1,as.matrix(df2[-sam2,])) ## validation data prediction
pr2<-ifelse(pr>0,1,0) ## y값이 0이상이면 긍정(1) 그게 아니면 부정으로 판단.
sum(pr2==new_score[-sam2])/length(pr2) ## accuracy ## 정확도
fit1$beta #######회귀 계수 출력
#########################
##Dictionary 기반 방법으로 감성분석 하기
##기본적인 Dictionary 기반 감성분석은 사전을 직접 제작하여야하나, 편의상 위 회귀모델에서 회귀계수를 출력하여 그 회귀 값들을 사전이라고 간주하고 감성분석을 진행하겠습니다.
beta<-fit1$beta[,1]
posi<-beta[beta > 0] ### 긍정 단어
nega<-beta[beta<0] ### 부정 단어
sort(posi,decreasing = T)[1:10] ## top 10개
sort(nega,decreasing = F)[1:10]
dic<-c(posi,nega) ## concat
save(dic,file="dic.RData") ##저장
load("comments.RData")
load("score.RData")
### supervised learning에 쓰인 review들로 만들어진 사전이기 때문에, 검증을 위해서 다른 (확률상) review를 추출합니다.
test_sam<-sample(1:length(comments),5000)
test_co<-comments[test_sam]
test_score<-score[test_sam]
length(dic)
library(stringr)
j<-1
cal_score<-NULL
for(j in 1:length(test_score)){
upc<- unlist(str_split(test_co[j]," ")) ## 각 리뷰들을 공백으로 분리후
ma<-match(upc,names(dic)) ## 사전과 match 시켜서, matching되는 사전들의 계수의 합을 감성 값으로 계산!!
cal_score<-c(cal_score,sum(dic[ma[!is.na(ma)]]))
cat("\n",j)
}
pred<-ifelse(cal_score > 0,1,0) ## 0이상이면 긍정, 아니면 부정으로 판단
test_score2<-ifelse(test_score>2.5,1,0)
sum(pred==test_score2)/length(pred) ## 정확도 계산
cal_emotion<-function(x){ ### 함수화
upc<-unlist(str_split(x," "))
ma<-match(upc,names(dic))
dic[ma[!is.na(ma)]]
score<-round(sum(dic[ma[!is.na(ma)]]),1)
score2<-ifelse(score>0,"긍정","부정")
return(paste(c("감성점수 값은 ", score,"로서 ",score2,"입니다 "),collapse=""))
}
cal_emotion(("이 집은 엄청 맛없네요 비추 최악"))
'R-텍스트마이닝' 카테고리의 다른 글
네이트 뉴스 수집 및 탑키워드, 워드클라우드 (0) | 2018.04.04 |
---|
댓글