cocomoff("blog")

@cocomoffの奇妙な日常.

Scalala使ってHITSアルゴリズムの計算(笑)を書いてテストしていた

前回,ようやくScalalaが使えるようになったので,ようやく線形代数のライブラリが使えるようになりました.統計とかはあんまり入ってないのでScipyっぽくは使えないのですが,まぁ我慢するとしましょう.行列とベクトル程度で書けるようなものがすぐ思いつかなかったので(後で思いついたのですが,線形回帰とか主成分分析も書けますね),HITSアルゴリズムのハブとオーサの計算をテストしてみた.自分で例題を考えたわけではなく,これらのサイトを参考にしてきました(ありがとうございます).

準備

昨日の記事でビルドしたscalalaの出力してくれたjarファイルを使います.具体的にはこの2つ.

  • scalala_2.9.1-1.0.0.RC3-SNAPSHOT.jar
  • scalala_2.9.1-1.0.0.RC3-SNAPSHOT.min.jar

ところでこういうiterativeなメソッドってvalの変数と相性悪いですよね,リストにするのかな?本当は.僕はそういう高度な技術は持ってないので普通にvarの変数使います.

import scalala.scalar._
import scalala.tensor.::
import scalala.tensor.mutable._
import scalala.tensor.dense._
import scalala.tensor.sparse._
import scalala.library.Library._
import scalala.library.LinearAlgebra._
import scalala.library.Statistics._
import scalala.library.Plotting._
import scalala.operators.Implicits._

object Main{
  def main(arg: Array[String]) = {

    // L
    val L = DenseMatrix.zeros[Double](6,6)
    L(0,2) = 1.0; L(0,4) = 1.0
    L(1,0) = 1.0
    L(2,4) = 1.0
    L(4,2) = 1.0; L(4,3) = 1.0
    L(5,4) = 1.0
    
    // initial value of y and repeat 20 times
    val y0 = DenseVector.ones[Double](6)
    val iterMax = 20
    val _xi = L.t * y0
    var xi = _xi / _xi.sum
    var yi = y0
    for( i <- 0 until iterMax ) {
      xi = L.t * yi
      xi = xi / xi.sum
      yi = L * xi
      yi = yi / yi.sum
    }

    // output
    println(" -- L.T * L -- ")
    println(L.t * L)

    println(" -- x 20 -- ")
    xi.foreach{ ch => printf(" %2.4f¥n", ch) }
    
    println(" -- y 20 -- ")
    yi.foreach{ ch => printf(" %2.4f¥n", ch) }    

  }
}

APIがあまりよくわかってないのは秘密ですわよ.