IshidaMotohiro / RMeCab

Interface to MeCab
30 stars 10 forks source link

単語頻度の重みづけの修正 #22

Closed paithiov909 closed 1 year ago

paithiov909 commented 1 year ago

こんにちは

この自作パッケージでRMeCabにおける単語頻度の重みづけの再現をしていたところ、RMeCab側の処理におかしいと思われるところを見つけたのでPRを出します。ご確認いただければ幸いです

このPRではRMeCabの次の2点を修正しています

  1. weight="idf3"を指定したときに期待どおりにglobalIDF3が呼ばれない点
  2. 行側に文書がある(tp=1)ときのエントロピーが計算できない、列側に文書があるときと計算結果が一致しない点

2点目については、次のように計算結果が一致するように修正しています

# テスト用の文書単語行列の作成
dtm <- gibasa::gbs_tokenize(audubon::polano[5:8]) |>
    dplyr::group_by(doc_id) |>
    dplyr::count(token) |>
    tidytext::cast_sparse(doc_id, token, n) |>
    as.matrix()

# 現在のRMeCabにおけるエントロピーの計算
entropy <-
  function (m, tp = 0) {
    if (tp == 1){
      gf = colSums(m, na.rm = TRUE)  # 大域的頻度 F_i
      p = m / gf                     # 各出現頻度 / 大域頻度
      ndocs = nrow(m)          # 文書数(行側に文章)
      entropy = - colSums( (p*log(p)) / log(ndocs), na.rm = TRUE )
    } else {
      gf = rowSums(m, na.rm = TRUE)  # 大域的頻度 F_i
      p = m / gf                     # 各出現頻度 / 大域頻度
      ndocs = ncol(m)           # 文書数(列側に文章)
      entropy = - rowSums( (p*log(p)) / log(ndocs), na.rm = TRUE )
    }
    return(entropy)
  }
globalEntropy <-
    function(m, tp = 0) {
        return( (1 - entropy(m, tp = tp)) )
    }

# この場合の計算結果
identical(
    globalEntropy(t(dtm)),
    globalEntropy(dtm, tp = 1)
)
#> [1] FALSE

# このforkでの計算結果
identical(
    RMeCab::globalEntropy(t(dtm)),
    RMeCab::globalEntropy(dtm, tp = 1)
)
#> [1] TRUE

Created on 2022-10-15 with reprex v2.0.2

IshidaMotohiro commented 1 year ago

全く気がついていませんでした。深謝します。