Python, 機械学習, 数学, 統計学

協調フィルタリング cos(コサイン)類似度

 

 

グループ分けを行い、各グループの類似度をベクトルの内積の公式を使って、cosθの値で類似度を判断する。

 

  • 類似度が高い・・・似てるほど1に近づく、類似度100%で1
  • 類似度が低い・・・似てないほど0に近づく、類似度0%で0

 

 

補足1. ベクトルの基本的なところ

 

補足2. ベクトルの内積の公式

  • a, bベクトルのなす角θが直角である時にcos90° = 0であり、
    a, bベクトルがそれぞれどのような長さの値でも、内積は0になる性質があります。
  • a, bベクトルのなす角θが0°である時にcos0° = 1であり、
    a, bベクトルの内積は一辺が|a|の大きさ, 一辺が|b|の大きさの長方形の面積と等しくなります。

 

 

 

補足3. ベクトルの正規化, 単位ベクトル

 

ベクトルの成分に対して、ベクトルの大きさで割ることで大きさ1の成分が出せます。ベクトルの方向を変えずに大きさを1にする操作を正規化と呼びます。

 

  • 大きさが1のベクトルを単位ベクトルと呼ぶ
  • ベクトルの正規化
    ベクトルをそのベクトルの長さで割ると、単位ベクトルを取得できます
  • ベクトルの内積の公式
    単位ベクトルに変換した大きさ1同士のベクトルの内積がcosθということですね。

 

補足4.  cosθって何者?

 

bの長さの屋根から出来る影をcの長さとして見ると、
cosθはbの長さがcの影になった時の縮小率として捉えることが出来ますね。

 

内積は屋根が作る影地面の大きさとの掛け算

| b | が | a |につくる影の長さ = C = | b | ・ cosθ

ベクトルa ・ ベクトル b = | b | ・ cosθ × | a | 

 

 

 

単位円の時、cosθは影の長さ

 

成分が負(-)を含まない場合 θ = 0~90°, 0 ≦ cosθ ≦ 1

  • ベクトル同士が完全に同じ方向の時はθ = 0°, cos0°= 1
  • ベクトル同士が全く異なる場合はθ = 90°, cos90° = 0

 

※ 成分が負を含む場合 θ = 0~180°, -1 ≦ cosθ ≦ 1

  • ベクトル同士が完全に逆向きの時はθ = 180°, cos180° = -1

 

 

ベクトルの内積はどれだけベクトル同士が同じ方向を向いているか = 類似度、この性質を利用します。

 

 

補足5.  n次元

軸が3つの空間ベクトルが軸が2つの平面ベクトルと同じ要領でベクトル計算出来たように、n次元に関しても同様に計算出来ます。

 

 

 

実際にやってみよう! 好きなフルーツの例

ばなな もも ぶどう りんご
Aさん 1 1 1 0
Bさん 1 0 1 0
Cさん 1 1 1 0
Dさん 0 1 0 1
Eさん 1 0 0 1
Fさん 1 0 1 1

 

  • 1 = 好き
  • 0 = 興味なし

 

ばなな好きグループの合算値

構成データ:A, B, C, E, Fさん

 

ばなな もも ぶどう りんご
ばなな好き 5 2 4 2

 

 

各グループの合算値

ばなな もも ぶどう りんご
ばなな好き 5 2 4 2
もも好き 2 3 2 1
ぶどう好き 4 2 4 1
りんご好き 2 1 1 3

 

 

プログラムで計算しよう

 

# coding: utf-8
import numpy as np

# ベクトル正規化
def normarize(v):
    return v / np.linalg.norm(v)

# cos類似度
def cos_similarity(v1, v2):
    return np.dot(v1, v2)


if __name__ == '__main__':

    bananaZuki = np.array([ 5, 2, 4, 2 ])
    momoZuki   = np.array([ 2, 3, 2, 1 ])
    budouZuki  = np.array([ 4, 2, 4, 1 ])
    ringoZuki  = np.array([ 2, 1, 1, 3 ])

    n_bananaZuki = normarize(bananaZuki)
    n_momoZuki   = normarize(momoZuki)
    n_budouZuki  = normarize(budouZuki)
    n_ringoZuki  = normarize(ringoZuki)


    print( 'ばなな好き・もも好き:',   cos_similarity(n_bananaZuki, n_momoZuki) )
    print( 'ばなな好き・ぶどう好き:', cos_similarity(n_bananaZuki, n_budouZuki) )
    print( 'ばなな好き・りんご好き:', cos_similarity(n_bananaZuki, n_ringoZuki) )

    print( 'もも好き・ぶどう好き:',   cos_similarity(n_momoZuki, n_budouZuki) )
    print( 'もも好き・りんご好き:',   cos_similarity(n_momoZuki, n_ringoZuki) )

    print( 'ぶどう好き・りんご好き:', cos_similarity(n_budouZuki, n_ringoZuki) )

 

Numpy

  • ベクトルの内積: nunpy.dot(v1, v2)
  • ベクトルの長さ: numpy.linalg.norm(v1)

Functions

  • 正規化:normarize(v)
  • cos類似度: cos_similarity(v1, v2)

 

 

# python3  cosSimFruit.py

ばなな好き・もも好き: 0.875465538611916
ばなな好き・ぶどう好き: 0.9863939238321437
ばなな好き・りんご好き: 0.8114822249196492
もも好き・ぶどう好き: 0.891231897035948
もも好き・りんご好き: 0.7302967433402215
ぶどう好き・りんご好き: 0.7216098119626152

 

 

類似度

ばなな好き もも好き ぶどう好き りんご好き
ばなな好き 1 0.875 0.986 0.811
もも好き 1 0.891 0.730
ぶどう好き 1 0.721
りんご好き 1

ばなな好きグループとぶどう好きグループの好みはほとんど同じだということがわかります。

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)