ユークリッド距離とは?
閲覧数:2469
投稿日: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)