Tech Blog

Information Technology / Machine Learning / Data Analysis / Big Data / System Integration

Rでテキストファイルをセンチメントの時系列データに変換する

目的

テキストファイルから読み取れるセンチメント(感情)を測定したい。そのために、テキストに現れる各単語のセンチメントを出現順に計測し、時系列データとみてグラフを描く。また、その平均・標準偏差・歪度・尖度などを算出する。

手法

感情辞書

単語と感情を対応付ける辞書として、「単語感情極性対応表」(高村大也, 乾孝司, 奥村学, "スピンモデルによる単語の感情極性抽出", 情報処理学会論文誌ジャーナル, Vol.47 No.02 pp. 627--637, 2006. )を用いる。本辞書では、各単語に対する印象を、positive: +1 ~ negative: -1の「感情極性値」で対応付けている。具体的には、辞書はテキストファイルで、55125個の単語に対して、「見出し語:読み:品詞:感情極性値」が記述されている。 なお、本辞書は研究目的に限り公開されている。

・pn_ja.txtの内容

優れる:すぐれる:動詞:1
良い:よい:形容詞:0.999995
喜ぶ:よろこぶ:動詞:0.999979
褒める:ほめる:動詞:0.999979
めでたい:めでたい:形容詞:0.999645
・・・
ない:ない:助動詞:-0.999997
酷い:ひどい:形容詞:-0.999997
病気:びょうき:名詞:-0.999998
死ぬ:しぬ:動詞:-0.999999
悪い:わるい:形容詞:-1

 

センチメントの計測

感情辞書を用いて、テキストファイルの形態素のセンチメントを割り出し、時系列データとみて、グラフ化・特徴量算出を行う。 

・Rのスクリプト(forループ多用してますが、あまりマネしないように。。)

# 感情辞書の読込み
affectDict <- read.table("C:/LyricsWorkspace/AffectDictionary/pn_ja.txt",sep=":",as.is=TRUE) #因子化を抑制しておく
 
# 歌詞の読込みと形態素解析
library(RMeCab)
dir <- "C:/LyricsWorkspace/Lyrics/Mr.Children_noheader"
lyricsList <- list.files(dir)
for (lyricName in lyricsList) {
 
textFile <- paste("C:/LyricsWorkspace/Lyrics/Mr.Children_noheader/",lyricName,".txt",sep="")
lyric <- RMeCabText(textFile)
 
# 単語を羅列したベクトルを作成する
wordVector <- rep(0,length=length(lyric))
for (i in 1:length(lyric)){
  wordVector[i] <- lyric[ [i]][8]
}
 
# 感情辞書を用いてセンチメントを羅列したベクトルを作成する
sentiVector <- c()
sentiVectorWords <- c()
for (i in 1:length(lyric)){
  cond <- (affectDict$V1 == wordVector[i])
  value <- affectDict[cond,]$V4
  word <- affectDict[cond,]$V1
  if (length(value)>=1) {
    value <- mean(value) #該当する単語が辞書に複数存在する場合は平均をとる
    word <- word[1]
    sentiVector <- append(sentiVector,value)
    sentiVectorWords <- append(sentiVectorWords,word)
  }
}
names(sentiVector) <- sentiVectorWords
 
# 特徴量の算出と保存
features <- list(0,0,0,0,c(0,0,0,0,0))
names(features) <- c("mean","sd","skew","kurto","quant")
features[ ["mean"]] <- mean(sentiVector) #平均
features[ ["sd"]] <- sd(sentiVector) #標準偏差
features[ ["skew"]] <- mean( (sentiVector-mean(sentiVector))^3)/(sd(sentiVector)^3) #歪度
features[ ["kurto"]] <- mean( (sentiVector-mean(sentiVector))^4)/(sd(sentiVector)^4) #尖度
features[ ["quant"]] <- quantile(sentiVector) #4分位偏差
write.table(unlist(features), paste("C:/LyricsWorkspace/TimeSeries/Features5_union/",lyricName,".txt",sep=""))
 
# グラフのプロットと保存
jpeg(paste("C:/LyricsWorkspace/TimeSeries/WithWords/",lyricName,".jpeg",sep=""), width=1440, height=960)
plot(sentiVector,type="l",ylim=c(-1.1,1.1))
par(ps=25)
text(1:length(sentiVector),sentiVector,names(sentiVector))
dev.off()
 
}

 

結果

Mr.ChildrenのMarshmallow dayを例に、出力結果を掲載する。縦軸にセンチメント(印象のpositive / negative)を、横軸にテキスト内での単語の順序をとると、以下のようなグラフが出力される。

f:id:tkdmah:20130113121129j:plain

また、特徴量として、以下のテーブルが出力される。

f:id:tkdmah:20130113121335j:plain