この項では先に作ったtopMatches関数を使って作品ごとに類似性スコア高いほかの作品のリストを作っている。
だけど、R言語では作品ごとに処理するよりも行列として処理したほうが簡単なので、topMatches関数は使わずに類似性スコアの行列を直接作ってみる。
それと例によって類似性の指標をオプションで選べるようにしてある。
# 作品同士の類似性スコア行列を算出する関数。 # prefs 行が作品、列が評者のマトリクス # person 対象者 # similarity 類似性の指標。既定値はユークリッド平方距離。 # "euclidean" ユークリッド平方距離 # "euclidean.center" 評者ごとに中心化したユークリッド平方距離 # "manhattan" マンハッタン距離 # "manhattan.center" 評者ごとに中心化したマンハッタン距離 # "pearson" ピアソンの積率相関係数 # "spearman" スピアマンの順位相関係数 # "kendall" ケンドールの順位相関係数 calculateSimilarItems <- function(prefs, similarity="euclidean"){ switch(similarity, "euclidean" = sim.index <- as.matrix(1/(1+dist(prefs)^2)), "euclidean.center" = sim.index <- as.matrix(1/(1+dist(scale(prefs, scale=FALSE))^2)), "manhattan" = sim.index <- as.matrix(1/(1+dist(prefs, method="manhattan"))), "manhattan.center" = sim.index <- as.matrix(1/(1+dist(scale(prefs, scale=FALSE), method="manhattan"))), "pearson" = sim.index <- cor(t(prefs), use="pairwise.complete.obs"), "spearman" = sim.index <- cor(t(prefs), use="pairwise.complete.obs", method="spearman"), "kendall" = sim.index <- cor(t(prefs), use="pairwise.complete.obs", method="kendall") ) sim.index[is.na(sim.index)] <- 0 diag(sim.index) <- NA sim.index }
使い方。
(itemsim <- calculateSimilarItems(critics)) # 出力 # Lady.in.the.Water Snakes.on.a.Plane Just.My.Luck Superman.Returns You.Me.and.Dupree The.Night.Listener # Lady.in.the.Water 0.00000000 0.16949153 0.10909091 0.06666667 0.27586207 0.22222222 # Snakes.on.a.Plane 0.16949153 0.00000000 0.06299213 0.16666667 0.04428044 0.16000000 # Just.My.Luck 0.10909091 0.06299213 0.00000000 0.03791469 0.11267606 0.09411765 # Superman.Returns 0.06666667 0.16666667 0.03791469 0.00000000 0.04606526 0.08921933 # You.Me.and.Dupree 0.27586207 0.04428044 0.11267606 0.04606526 0.00000000 0.11049724 # The.Night.Listener 0.22222222 0.16000000 0.09411765 0.08921933 0.11049724 0.00000000
う〜ん、p25に載っているサンプルコードの結果と合わないぞ。
どうもdist関数におけるNAの扱いが要因みたい。
RjpWikiの初級Q&A アーカイブより、NAを含む行列を関数distで計算。
相関係数のほうは一致する。
逐語訳ではなくて意訳、超訳と宣言しましたので、ここはRの流儀のままで行きたいと思います。