ユークリッド距離とは?
閲覧数:2163
投稿日:2015-12-30
更新日:2016-01-02
差の2乗和の平方根
ユークリッド距離によるスコアとは?
・ユークリッド距離を基にした類似性スコア
・類似性スコアを求めて後で重み付けに使うためにこれに1を加えて逆数を取ったものを使う
・1を加えて、逆数を取ることで0-1の範囲に収まる
・差が0なら1になり後は徐々に差がつくたびに0に近づく
・こうすることで常に0から1の間の値を返すようになり、類似性が高ければ1に近くなる
実装
・評者二人の共通項を抜き出す
・共通項が無ければ類似度0を返す
・評者二人の共通項に対してユークリッド距離を計算し、総和に1を加えたものの逆数をとり、これを類似度として返す
ユークリッド距離だと差の二乗和の平方根をとったものなので、戻り値はreturn 1/(1 + sqrt($sum_of_squares));
書籍からの変更点
・sim_distance関数の最後の行
return 1/(1 + sum_of_squares)
↓
return 1/(1 + sqrt(sum_of_squares))
リンク先からの変更点
・'Michael Phillips' の 'The Night Listener' 評価を 3.0 から 4.0 へ変更
コード
$critics = array( 'Lisa Rose' => array( 'Lady in the Water' => 2.5, 'Snakes on a Plane' => 3.5, 'Just My Luck' => 3.0, 'Superman Returns' => 3.5, 'You, Me and Dupree' => 2.5, 'The Night Listener' => 3.0, ), 'Gene Seymour' => array( 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 3.5, 'Just My Luck' => 1.5, 'Superman Returns' => 5.0, 'You, Me and Dupree' => 3.5, 'The Night Listener' => 3.0, ), 'Michael Phillips' => array( 'Lady in the Water' => 2.5, 'Snakes on a Plane' => 3.0, 'Superman Returns' => 3.5, 'The Night Listener' => 4.0, ), 'Claudia Puig' => array( 'Snakes on a Plane' => 3.5, 'Just My Luck' => 3.0, 'Superman Returns' => 4.0, 'You, Me and Dupree' => 2.5, 'The Night Listener' => 4.5, ), 'Mick LaSalle' => array( 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 4.0, 'Just My Luck' => 2.0, 'Superman Returns' => 3.0, 'You, Me and Dupree' => 2.0, 'The Night Listener' => 3.0, ), 'Jack Matthews' => array( 'Lady in the Water' => 3.0, 'Snakes on a Plane' => 4.0, 'Superman Returns' => 5.0, 'You, Me and Dupree' => 3.5, 'The Night Listener' => 3.0, ), 'Toby' => array( 'Snakes on a Plane' => 4.5, 'Superman Returns' => 4.0, 'You, Me and Dupree' => 1.0, ), ); // person1とperson2の距離を基にした類似性スコアを返す //返り値は0-1の範囲で1に近いほど類似性がある function sim_distance($prefs, $person1, $person2){ $si = array(); //二人とも評価しているアイテムのリストを得る foreach($prefs["$person1"] as $item => $val){ if(isset($prefs["$person2"]["$item"])){ $si["$item"] = 1; } } if(count($si) == 0){ return 0;} //すべての差の平方を足し合わせる //上のループでできる $sum_of_squares = 0; foreach($prefs["$person1"] as $item => $val){ if(isset($prefs["$person2"]["$item"])){ $sum_of_squares += pow( ( $prefs["$person1"]["$item"] - $prefs["$person2"]["$item"]),2); } } return 1/(1 + sqrt($sum_of_squares)); } var_dump( sim_distance($critics,'Lisa Rose','Gene Seymour') ); //float(0.29429805508555) var_dump( sim_distance($critics,'Lisa Rose','Lisa Rose') ); //float(1) var_dump( sim_distance($critics,'Lisa Rose','Toby') ); //float(0.34833147735479)
結果
float(0.29429805508555) float(1) float(0.34833147735479)