next up previous contents
Next: PLSA Up: 実験で使用したプログラム Previous: 実験で使用したプログラム   目次

LSA

#
# main 5_lsa.R
#
#   Make   : 2010.10.26
#   Modify : 2010.11.19
#   Author : Yoshimura. T
#

main = function (binary, type) {
  # 計算結果をファイルに出力する関数
  printout = function (x, out, th, rank = 10) {
    # 出力ファイルの初期化
    cat (file = out, append = FALSE)
    
    for(i in 1:dim (x)[1]) {
      cat (" ########", i, "######## \n", file = out, append = TRUE)
      
      o = order (x[, i], decreasing = TRUE)
      # 上位結果だけ書き出す
      o = replace (o, c (rank:dim (x)[1]), c (0))
      # しきい値以下は類似度を 0 とする
      x[o[th[i]:rank], i] = 0
      s = sprintf ("%-40s %.6f\n", colnames (x)[o], x[o, i])
      cat (s, "\n", file = out, append = TRUE, sep = "")
    }
  }
  
  # 主成分数を算出する関数
  adopt = function (x, type) {
    if (0 < type && type < 1) {
      # 累積寄与率から求めるパターン
      data.sm = summary (x)
      ## Standard deviation      : 標準偏差
      ## Proportion of Variance  : 寄与率
      ## Cumulative Proportion   : 累積寄与率
      
      # +1 は端数分を考慮
      num = sum (data.sm$importance["Cumulative Proportion", ] < type) + 1
    } else {
      # 固有値から求めるパターン
      num = sum (x$sdev > 1)
    }
    
    return (num)
  }
  
  # ベクトル空間法を実行する関数
  vsm = function (x) {
    size = dim (x)[2]
    
    # ベクトルの大きさを求める
    norm = sqrt (apply (x ** 2, 2, sum))
    
    # 類似度行列の初期化
    similar = matrix (0, nrow = size, ncol = size)
    
    for (i in 1:size) {
      for (j in 1:size) {
        # ベクトルの内積を求める
        inner = sum (x[, i] * x[, j])
        # 類似度 = cosθ を求める
        similar[i, j] = inner / (norm[i] * norm[j])
      }
    }
    
    return (similar)
  }
  
  # 2値化におけるしきい値を得る関数
  threthold = function (x) {
    size = dim (x)[2]
    th = NULL
    
    for (j in 1:size) {
      # 類似度の小さすぎる差は認めない
      mdif = 0.1
      max = dim (x)[2]
      
      # 一番目の教科の類似度は 1 であり,
      # 次との差が必然的に大きくなる為に対象外とする
      for (i in 2:(size - 1)) {
        dif = x[i, j] - x[i + 1, j]
        if (dif > mdif) {
          mdif = dif
          max = i + 1
        }
      }
      
      th = append (th, max)
    }
    
    return (th)
  }
  
  # 作業用ディレクトリ指定
  setwd ("C:/cygwin/home/吉村 建慶/Research/main/result/")
  
  # 入出力ファイル指定
  input  = "3_matrix/matrix.csv"
  output = "5_lsa/lsa.txt"
  
  # 行列データの取り込み
  data = read.csv (input, row.name = 1)
  
  # 主成分分析の実行
  data.pc = prcomp (data)
  ## $sdev      : 固有値
  ## $rotation  : 固有ベクトル
  ## $center    : 平均値
  ## $scale     : 標準偏差
  ## $x         : 主成分得点
  
  # 採用する主成分数の算出
  num = adopt (data.pc, type)
  
  # 特異値分解の実行
  data.svd = svd (data)
  ## $u : タームベクトル
  ## $d : 特異値ベクトル
  ## $v : 文書ベクトル
  
  # 近似行列の作成
  apx = t (data.svd$u[, 1:num]) %*% data.matrix (data)
  
  # ベクトル空間法の実行
  similar = vsm (apx)
  rownames (similar) = colnames (data)
  colnames (similar) = colnames (data)
  
  if (binary) {
    temp = apply (similar, 2, sort, decreasing = TRUE)
    th = threthold (temp)
  } else {
    th = rep (dim (similar)[2], dim (similar)[2])
  }
  
  printout (similar, output, th)
}

args = commandArgs ()
system.time (main (as.integer (args[6]), as.numeric (args[7])))

### END ###


Deguchi Lab. 2011年3月4日