iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
AI & Data

親手打造推薦系統系列 第 5

Day05 - 利用 sklearn 的 TfidfVectorizer 做電影資訊的向量化 - 親手打造推薦系統

  • 分享至 

  • xImage
  •  

今天我們要說明如何用sklearn 的 TfidfVectorizer 將電影資訊向量化。

要怎麼做呢?只要4個步驟。

第1步:準備好斷好的文章

我準備了11198篇的電影資訊,然後把電影資訊、卡司、演員表等,全部都串成一個字串。

將字串斷詞過後的,每一篇文章就會長成像這個樣子。

故事 由 《 魔戒 首 部 曲 : 魔戒 現身 》 展開 , 一 位 名叫 的 年輕人 , 無意 間 得到 一 枚 有 著 神秘 力量 的 戒指 , 卻 發現 這 枚 戒指 原來 是 黑暗 魔王 所 擁有 。 幾經 波折 後 , 他 決定 摧毀 魔戒 , 以免 奪回去 鞏固 自己 的 勢力 。 巫師 、 精靈 、 矮人 、 和 人類 於是 組成 魔戒 遠征隊 , 協助 佛羅多 前往 索倫 統治 的 「 中土 世界 」 , 將 魔戒 丟入 末日 火山 摧毀 。 旅途 中 派出 怪獸 追殺 佛羅多 一 群 人 , 魔戒 也 開始 腐蝕 人心 , 讓 人 產生 難以 抵擋 的 慾望 , 考驗 著 每 位 接觸 戒指 的 意志力 。 Peter Jackson 、 Sean  Astin 、 Sean  Bean 、 Cate Blanchett  奧蘭多布魯 ( Orlando Bloom )  、 ( Marton Csokas) 、 ( Ian Holm ) 、 李 ( Christopher Lee ) 、 瑟克斯 ( Andy Serkis ) 、 維果 莫天森 ( Viggo Mortensen ) 、 ( Hugo  Weaving )

為了等下展示方便,seg_line_list 就是我放資料的變數。

print(len(seg_line_list))  ## 有1萬多篇的電影資料構成的串列
11198

共有 11198 篇

第2步:訓練出含有 tfidf 的 特徵矩陣

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
vectorizer = TfidfVectorizer()
feature_matrix = vectorizer.fit_transform(seg_line_list)
feature_matrix
<11198x117753 sparse matrix of type '<class 'numpy.float64'>'
	with 1529011 stored elements in Compressed Sparse Row format>

這什麼意思呢? 11198 是我的電影資料篇數,117753 是這些文章找出的所有的詞的總數。

feature_matrix[0] 裡放著什麼呢?

print(feature_matrix[0])

他是一個稀疏矩陣,所以表示的方法跟一般的串列不一樣。

  (0, 35755)	0.062127121469352994
  (0, 73377)	0.04926651860664991
  (0, 81134)	0.046503387146599545
  (0, 39644)	0.022203660939488494
  (0, 15632)	0.11405749636828087
  (0, 15223)	0.11405749636828087
  (0, 112131)	0.11571064071739166
  (0, 11140)	0.13516798172170535
  (0, 20872)	0.08270790227245117
  (0, 7243)	0.09312136735253172
  (0, 19811)	0.09460015536396717
  (0, 7807)	0.0917836408770831

先忽略掉每一行的第一個0,你看到第一個數字,例如35755代表的是第355755號的詞,而後面帶有小數點的數字就是TFIDF 值,就是這個詞在這篇文章的重要程度。

那35755是哪個詞呢? 我們可以用 get_feature_names_out() 找出字典

words = vectorizer.get_feature_names_out()
print(words[35755])
print(words[73377])
傳記
歷史

第3步:做相似度計算

similarity = cosine_similarity(feature_matrix)
print(similarity)
[[1.         0.04314573 0.02149657 ... 0.02443829 0.00418044 0.00128481]
 [0.04314573 1.         0.0279604  ... 0.03061228 0.00751541 0.01318771]
 [0.02149657 0.0279604  1.         ... 0.01694194 0.01199874 0.02370222]
 ...
 [0.02443829 0.03061228 0.01694194 ... 1.         0.00225818 0.02985038]
 [0.00418044 0.00751541 0.01199874 ... 0.00225818 1.         0.0108662 ]
 [0.00128481 0.01318771 0.02370222 ... 0.02985038 0.0108662  1.        ]]

把特徵矩陣丟進去,得到相似矩陣。

第4步:建造相關影片函式

def get_related_movie_index(movie_index, similarity):
  related_limit = 11
  movie_similarity = list(enumerate(similarity[movie_index]))
  sorted_movie_similarity = sorted(movie_similarity, key = lambda x: x[1], reverse= True)
  return [m_index for m_index, score in sorted_movie_similarity[0:related_limit]]

因為我知道 2861 是美國隊長,所以用以下程式找出和美國隊長相似的電影:

get_related_movie_index(2861, similarity)
[2861, 4070, 5126, 3168, 1889, 6865, 2508, 4809, 2867, 2665]

除了第1個2861是美國隊長外,從4070開始分別是:

  1. 美國隊長2:酷寒戰士:
  2. 美國隊長3:英雄內戰:
  3. 復仇者聯盟:
  4. 無敵浩克:
  5. 驚奇隊長:
  6. 鋼鐵人2:
  7. 真愛BJ4:
  8. 雷神索爾:
  9. 麥克邁:超能壞蛋:

看起來除了 真愛BJ4 及 麥克邁:超能壞蛋 外 似乎還不錯!

接下來呢?

看起來效果還是不錯,我們明天再來仔細研究一下為什麼會這樣推薦?


上一篇
Day 04 - 電影資訊要怎麼轉成特徵向量呢? - 親手打造推薦系統
下一篇
Day 06 - 用中研院 CKIP Transformers 做中文斷詞,台灣國語不再結巴 - 親手打造推薦系統
系列文
親手打造推薦系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言