Lecture8: TF-IDF

★準備

getFreqDir.Rを読み込む

source("getFreqDir.R")

★課題の補足

tf<-getFreqDir("univ")
res1<-hclust(dist(t(tf)), method ="ward.D2")
plot(res1)

res2<-hclust(dist(t(tf)), method ="ward.D")
plot(res2)

plot(res1,xlab="euclidean distance", sub="ward method")

Shinyでの実装例

plot(hcus, xlab=paste("distance = ",input$choice1), sub=paste("clustering = ",input$choice2))

NB. hcusはhclust関数の結果を代入

★頻度数の重み付け

Term Frequency-Inverse Document Frequency

複数のテキストに共通して出現する単語の低く評価 ### TF-IDF 1 \[w=tf*log(\frac{N}{df}) \]

tf: term frequency

df: document frequency

tf値(頻度数)を計算

  tf<-getFreqDir("testData")
  tf
##   test1 test2 test3
## a     3     2     2
## b     4     4     0
## c    13     2     3
## d     0     0     1
## e     7     1     1
## f     0    11     9
## g     0     7     7
## h     0     0     4

少し脱線:条件抽出

  tf[1,]
##   test1 test2 test3
## a     3     2     2
  tf[,1]
## [1]  3  4 13  0  7  0  0  0
  tf[rownames(tf)=="e",]
##   test1 test2 test3
## e     7     1     1
  tf[rownames(tf)=="e" | rownames(tf)=="d",]
##   test1 test2 test3
## d     0     0     1
## e     7     1     1
  tf[rowSums(tf)>10,]
##   test1 test2 test3
## c    13     2     3
## f     0    11     9
## g     0     7     7
  tf[rowSums(tf)< 4,]
##   test1 test2 test3
## d     0     0     1
  tf[rowSums(tf)>=10,]
##   test1 test2 test3
## c    13     2     3
## f     0    11     9
## g     0     7     7
  tf[rowSums(tf)<=15,]
##   test1 test2 test3
## a     3     2     2
## b     4     4     0
## d     0     0     1
## e     7     1     1
## g     0     7     7
## h     0     0     4
  tf[(rowSums(tf)>=10) & (rowSums(tf)<=15) ,]
##   test1 test2 test3
## g     0     7     7
  hoge=1
  if (hoge==1 | hoge==2) {print("hoge = 1 or 2")}else{ print("hoge=??")}
## [1] "hoge = 1 or 2"
  hoge=2
  if (hoge==1 || hoge==2) {print("hoge = 1 or 2")}else{ print("hoge=??")}
## [1] "hoge = 1 or 2"
  hoge=3
  if (hoge==1 || hoge==2) {print("hoge = 1 or 2")}else{ print("hoge=??")}
## [1] "hoge=??"

N値(ドキュメント数)を計算

  N<-ncol(tf)
  N  
## [1] 3

df値(1行あたり0以上の要素数)を計算

  df<-apply(tf, 1, function(x) length(x[x>0]) )
  df
## a b c d e f g h 
## 3 2 3 1 3 2 2 1

tf-idf値を計算

  w<-round(tf*log(N/df),2)
  w
##   test1 test2 test3
## a  0.00  0.00  0.00
## b  1.62  1.62  0.00
## c  0.00  0.00  0.00
## d  0.00  0.00  1.10
## e  0.00  0.00  0.00
## f  0.00  4.46  3.65
## g  0.00  2.84  2.84
## h  0.00  0.00  4.39

TF-IDF 2

共通出現頻度も考慮したtf-idf式

\[w=tf*(log(\frac{N}{df})+1) \]

tf-idf値を計算

  w<-round(tf*(log(N/df)+1),2)
  w
##   test1 test2 test3
## a  3.00  2.00  2.00
## b  5.62  5.62  0.00
## c 13.00  2.00  3.00
## d  0.00  0.00  2.10
## e  7.00  1.00  1.00
## f  0.00 15.46 12.65
## g  0.00  9.84  9.84
## h  0.00  0.00  8.39

tf-idfの計算用の関数を作成:calcTFIDF

  calcTFIDF<-function(tf, type=1){
  
    N<-ncol(tf)
  
    idf<-apply(tf, 1, function(x) length(x[x>0]) )
  
    if(type==1) {
      w<-tf*log(N/idf)
    }else if(type==2) {
      w<-tf*(log(N/idf)+1)
    }
  
    return(w)
  }

実習1: getFreqDir関数にcalcTFIDF関数を組み込む

手順1:getFreqDir.RのgetFreqDir関数の下に上記のcalcTFIDF関数を追加

手順2:getFreqDir関数の引数にオプション引数tfidfを追加(デフォルト値0)

手順3:getFreqDir関数内にtfidfのオプションで計算を異なるようにコードを追加

tfidf=0: 何もしない
tfidf=1: 上記のTF-IDF 1の計算式を適用
tfidf=2: 上記のTF-IDF 2の計算式を適用

実行例

  source("getFreqDir.R")
  res <- getFreqDir("testData")
  round(res,2)
##   test1 test2 test3
## a     3     2     2
## b     4     4     0
## c    13     2     3
## d     0     0     1
## e     7     1     1
## f     0    11     9
## g     0     7     7
## h     0     0     4
  res1 <- getFreqDir("testData",tfidf=1)
  round(res1,2)
##   test1 test2 test3
## a  0.00  0.00  0.00
## b  1.62  1.62  0.00
## c  0.00  0.00  0.00
## d  0.00  0.00  1.10
## e  0.00  0.00  0.00
## f  0.00  4.46  3.65
## g  0.00  2.84  2.84
## h  0.00  0.00  4.39
  res2 <- getFreqDir("testData",tfidf=2)
  round(res2,2)
##   test1 test2 test3
## a  3.00  2.00  2.00
## b  5.62  5.62  0.00
## c 13.00  2.00  3.00
## d  0.00  0.00  2.10
## e  7.00  1.00  1.00
## f  0.00 15.46 12.65
## g  0.00  9.84  9.84
## h  0.00  0.00  8.39

実習2: Shiny

  library(shiny)
  runApp("shiny_apps/app_hclust")