読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

2人間の類似値を取得する(2)

scala 勉強 アルゴリズム

ピアソン相関を使って類似度を出力する

ピアソン相関ってなんぞ?と思った人は統計学の講座。 参考になるのが下記

http://kusuri-jouhou.com/statistics/soukan.html

http://www.koka.ac.jp/morigiwa/sjs/les10801.htm

片方は薬学ですがキニシナイ。

論よりRUN

  def exec(left:Map[String, Int], right:Map[String, Int]) = {
    val commonValues = findCommonItem(left, right).toList
    if (commonValues.isEmpty) {
      0.0
    } else {
      // 全ての嗜好を合計
      val leftSum  = commonValues.map(_._1).sum.toDouble
      val rightSum = commonValues.map(_._2).sum.toDouble

      // 平方和
      val leftSqSum  = commonValues.map(v => Math.pow(v._1, 2.0)).sum
      val rightSqSum = commonValues.map(v => Math.pow(v._2, 2.0)).sum

      // 積
      val pSum = commonValues.map(lr => lr._1 * lr._2).sum

      // 統計量の計算
      val n   = commonValues.length.toDouble
      def num = pSum.toDouble - (leftSum * rightSum / n)
      def den = Math.sqrt((leftSqSum - Math.pow(leftSum, 2) / n) * (rightSqSum - Math.pow(rightSum, 2) / n))

      if (den == 0.0) {
        0.0
      } else {
        num / den
      }
    }
  }

となる。

findCommonItem及びデータは下記参照。

http://white-azalea.hatenablog.jp/entry/2013/10/08/000419

これ相関値がマイナスになったら、好みが逆であることを意味する。

好みが完全一致で「1」真逆で「-1」です。

こちらのアルゴリズムなら評価した共通アイテムに差があっても問題なく出てくるし、評価の厳しい人と緩い人でも同列に計算できる利点がある。