コサイン類似度とかの話

少し間が空いてしまいました 

少しずつ技術的な話も増やしてきいきたいですね. (ネタに走らず雑味カット路線)

 

あるユーザーが読んだ本をまとめていくと、そのユーザーの趣味って出てきそうですよね

例えば...

[漫画:100%]

[小説:60%, ライトノベル:40%]

[ビジネス・経済・就職:30%, 人文・思想・社会:30%, 科学・医学・技術: 40%]

 

自分の本棚を見て、ヒヤリともしたり

 

こういった割合を、ユーザーごとにベクトルでまとめること(特徴ベクトル化)をしてみます. 特徴ベクトル化することで、コサイン類似度*などの計算も出来ますね.

*ベクトルごとの近さを数値化します

 

たとえば本のカテゴリー情報を元に、

ユーザーの読書履歴を純粋に特徴ベクトル化するなら、(0, 0, 0, 1, 0, 0, 0, ...)等と、

読んでいない本も含めてカテゴリーを全部取得しないといけません.

 

ただ0ばっかり(疎)のベクトルを愚直に用いるのもどうなのか。

ベクトル各々をDBに保存する形式をどうするか...ということにも迷いが生じました.

 

今回は、特徴ベクトルをjson形式でDBに格納して、

コサイン類似度を連想配列に一度戻して計算することを考えました.

 

(下記はphpサンプルコード)

$query = json_encode($query);

 

function norm($v){

  $sumsq = 0;

  foreach($v as $key => $value){

    $sumsq += pow($value,2);

  }

  return pow($sumsq,0.5);

}

 

function cosSim($json1, $json2){

  //内積 inner product

  $i_p = 0;

  //引数としてjsonを受け取る.

  $a=json_decode($json1,true);

  $b=json_decode($json2,true);

 

  $l = sizeof($a) < sizeof($b) ? $a : $b;

  foreach($l as $key => $value){

    if(isset($a[$key]) && isset($b[$key]))

      $i_p += $a[$key]*$b[$key];

  }

  return ($i_p/(norm($a)*norm($b)));

}

 

自分のコードを晒すのに全然慣れませんが

そろそろ、自分が書いたものには責任を取らないとですね( ・д・)怖い.