技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

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

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

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

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」です。

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