如果媽祖託夢,告訴我們每一個人對每部電影有多喜歡,喜歡程度從 1 星到 5 星,最後得到下表,那我們的推薦系統只要查表就好了,這樣變得非常簡單!
例如我們有一張表如下,數字表示人對電影 1 星到 5 星的喜歡程度:
鐵達尼號 | 魔戒 | 不可能的任務 | 神隱少女 | |
---|---|---|---|---|
Hello Kitty | 5 | 2 | 3 | 4 |
Pikachu | 2 | 4 | 5 | 3 |
Sonic | 3 | 5 | 2 | 4 |
例如若要推薦Sonic 有可能看的電影,那就是 5 星的魔戒和 4 星的神隱少女。
我們也可以把這個表做轉置,變成下表:
Hello Kitty | Pikachu | Sonic | |
---|---|---|---|
鐵達尼號 | 5 | 2 | 3 |
魔戒 | 2 | 4 | 5 |
不可能的任務 | 3 | 5 | 2 |
神隱少女 | 4 | 3 | 4 |
如果要問推薦魔戒給誰比較容易成功?看表就知道,是填5星的 Sonic 和 填 4 星的 Pikachu。
但這一切都是 如果 我們有一個夢幻的評分表。但除非媽祖顯靈,不然現實中才不會有這東西!現實中有的資料,都是少數人對少數電影做評分!它們可能長得像:
鐵達尼號 | 魔戒 | 不可能的任務 | 神隱少女 | |
---|---|---|---|---|
Hello Kitty | 5 | 2 | 沒評分 | 4 |
Pikachu | 2 | 4 | 5 | 沒評分 |
Sonic | 沒評分 | 5 | 2 | 4 |
或
Hello Kitty | Pikachu | Sonic | |
---|---|---|---|
鐵達尼號 | 5 | 2 | 沒評分 |
魔戒 | 2 | 4 | 5 |
不可能的任務 | 沒評分 | 5 | 2 |
神隱少女 | 4 | 沒評分 | 4 |
為了解說方便,上面的資料還是放得有點多。總之,「沒評分」的地方會比有分數的地方多很多。
如果我們不要放棄希望,能不能想辦法把沒評分的地方填回來呢?
最常用的是根據已有評價,對目標分數進行預測,預測方式對其它人評分做加權平均,其中權重就是相似度。
以下為 ItemCF 及 UserCF 的簡單 2 個例子。
PS: 如果還不了解 ItemCF 或 UserCF,甚至還不知道協作過濾(Collaborative Filtering)推薦法,請看昨日的文章: Day 08 - 協作過濾(Collaborative Filtering)是什麼?UserCF和ItemCF有什麼差別?
如果有以下的評分表:
鐵達尼號 | 魔戒 | 不可能的任務 | 神隱少女 | |
---|---|---|---|---|
Hello Kitty | 5 | 2 | 沒評分 | 4 |
Pikachu | 2 | 4 | 5 | 沒評分 |
Sonic | 沒評分 | 5 | 2 | 4 |
User_X | 4 | 4 | 沒評分 | 沒評分 |
問:對 User_X 要推「不可能的任務」還是「神隱少女」?
只要能把沒評分的2處,預測出分數來,就可以知道要推薦什麼了!
因為1、2 分負評、4、5分好評, 3 星中性,所以以3星做填充。
鐵達尼號 | 魔戒 | 不可能的任務 | 神隱少女 | |
---|---|---|---|---|
Hello Kitty | 5 | 2 | 3 | 4 |
Pikachu | 2 | 4 | 5 | 3 |
Sonic | 3 | 5 | 2 | 4 |
User_X | 4 | 4 | 3 | 3 |
kitty = [5,2,3,4]
picachu = [2,4,5,3]
sonic = [3,5,2,4]
user_x = [4,4,3,3]
利用 consine similarity 計算相似度,user_x 和 hello kitty, Pikachu, Sonic 的 consine similarity 分別為: 0.98, 0.91, 0.93 。
用其它相似度算法也行。
不知怎麼從特徵向量算相似度的話,可以看這篇 Day 03 - 如何用 sklearn 算相似度?看懂這個蛋糕不見的故事就懂了!
我們預估 User_X 對「不可能的任務」的評分為:
(0.98 * 3 + 0.91 * 5 + 0.93 * 2)/3 = 3.11
對「神隱少女」的評分為:
(0.98 * 4 + 0.91 * 3 + 0.93 * 4)/3 = 3.46
鐵達尼號 | 魔戒 | 不可能的任務 | 神隱少女 | |
---|---|---|---|---|
Hello Kitty | 5 | 2 | 沒評分 | 4 |
Pikachu | 2 | 4 | 5 | 沒評分 |
Sonic | 沒評分 | 5 | 2 | 4 |
User_X | 4 | 4 | 3.11 | 3.46 |
看來,推薦神隱少女的成功率大一些。
如果有以下的評分表:
Hello Kitty | Pikachu | Sonic | |
---|---|---|---|
鐵達尼號 | 5 | 2 | 沒評分 |
魔戒 | 2 | 4 | 5 |
不可能的任務 | 沒評分 | 5 | 2 |
神隱少女 | 4 | 沒評分 | 4 |
Movie_X | 5 | 沒評分 | 沒評分 |
問: Movie_X 要推薦給 Pikachu 還是 Sonic 呢?
把沒評分的地方改成 3 分
Hello Kitty | Pikachu | Sonic | |
---|---|---|---|
鐵達尼號 | 5 | 2 | 3 |
魔戒 | 2 | 4 | 5 |
不可能的任務 | 3 | 5 | 2 |
神隱少女 | 4 | 3 | 4 |
Movie_X | 5 | 3 | 3 |
這時,每部電影的特徵向量變為:
movie_x = [5, 3, 3]
titanic = [5,2,3] # 鐵達尼號
ring = [2,4,5] # 魔戒
mission_impossible = [2,4,5] # 不可能的任務
spirited_away = [4,3,4] # 神隱少女
movie_x 和 鐵達尼號、魔戒、不可能的任務、神隱少女 的 consine similarity 分別為 0.97, 0.89, 0.89, 0.99。
不知怎麼從特徵向量算相似度的話,可以看這篇 Day 03 - 如何用 sklearn 算相似度?看懂這個蛋糕不見的故事就懂了!
我們預測:
Pikachu 對 movie_x 評分為:
(0.99*2+0.84*4+0.84*5+0.97*3)/4 = 3.1125
Sonic 對 movie_x 評分為:
(0.99*3+0.84*5+0.84*2+0.97*4)/4 = 3.1825
Hello Kitty | Pikachu | Sonic | |
---|---|---|---|
鐵達尼號 | 5 | 2 | 沒評分 |
魔戒 | 2 | 4 | 5 |
不可能的任務 | 沒評分 | 5 | 2 |
神隱少女 | 4 | 沒評分 | 4 |
Movie_X | 5 | 3.1125 | 3.1825 |
看來要對 Sonic 推薦 Movie_X 比較有機會成功。
今天的東西有點多,明天我們再來談談什麼時候用 UserCF , 什麼時候用 ItemCF。
明天見~
請問我用如下程式碼得到的相似值是 0.98954139 0.84112635 0.84112635 0.97646729,為什麼跟文中不一樣呢?
from sklearn.metrics.pairwise import euclidean_distances, cosine_similarity
movie_x = [5, 3, 3]
titanic = [5,2,3] # 鐵達尼號
ring = [2,4,5] # 魔戒
mission_impossible = [2,4,5] # 不可能的任務
spirited_away = [4,3,4] # 神隱少女
feature_vectors = [movie_x, titanic, ring, mission_impossible, spirited_away]
print("Cosine similarity:")
cosine_similarity_metrix = cosine_similarity(feature_vectors)
print(cosine_similarity_metrix)
Cosine similarity:
[[1. 0.98954139 0.84112635 0.84112635 0.97646729]
[0.98954139 1. 0.79802388 0.79802388 0.96271972]
[0.84112635 0.79802388 1. 1. 0.93124039]
[0.84112635 0.79802388 1. 1. 0.93124039]
[0.97646729 0.96271972 0.93124039 0.93124039 1. ]]