iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 7
1
AI & Data

一服見效的 AI 應用系列 第 7

Day 07:初探推薦系統(Recommendation System)

前言

上一篇我們介紹了『購物籃分析』,可以幫公司建立商品組合,也可以推薦商品給顧客,它單純依據銷售記錄進行分析,但是,如果是線上網購,瀏覽(Page View)也是一個關鍵的購買訊號,還有用戶評價(Rating)也能提供給商品推薦的有力依據,所以,我們就花幾天的時間好好來討論一下來看看『推薦系統』(Recommendation System 或稱 Recommender System) 。

推薦系統分類

推薦系統的類別主要分為下列三種:

https://ithelp.ithome.com.tw/upload/images/20190923/20001976tm6UFDgeeN.png

  1. 以內容為基礎的過濾(Content Based Filtering):比較商品的屬性,找出最相似的商品。
  2. 協同過濾(Collaborative Filtering, CF):集合眾人的意見,找出最相似的顧客或找出最相似的商品,進而推薦商品。依分析的方法又分為兩種:
  • 以記憶體為基礎的過濾(Memory Based Collaborative Filtering)
  • 以模型為基礎的過濾(Model Based Collaborative Filtering):使用各種機器學習、深度學習(Deep Learning, RL)或強化學習(Reinforcement learning, DL)的演算法構築推薦系統。
  1. 混合型的過濾(Hybrid approach):同時採用上述兩種方法,建立推薦系統。

今天我們就先來介紹『以內容為基礎的過濾』(Content Based Filtering)的作法。

Content Based Filtering 範例實作

Content Based Filtering又分為兩種:

  1. 依據一件瀏覽或已購買的商品,推薦屬性相似的商品。
  2. 結合使用者評價與商品屬性,推薦使用者偏好的商品。

第一種作法

先舉一個簡單的例子說明,如果使用者之前看過幾部電影,發現他比較看漫威電影,那就應該推薦他看『復仇者聯盟』,而不是恐怖片,這是只有一個屬性的狀況,如果,我們有收集很多屬性資料,那該怎麼做呢? 請看下面範例說明。

我們以 Kaggle 的 TMDB 5000 Movie Dataset 為例,說明『以內容為基礎的過濾』(Content Based Filtering)的處理步驟。

資料集內含兩個檔案:電影基本資料(tmdb_5000_movies.csv)及演員/工作人員資料(tmdb_5000_credits.csv),我們要從這兩個檔案內的欄位找出相似的電影推薦給使用者,由於,檔案內多個欄位是Json格式,需要前置處理,將資料整理好。

以下程式來自這裡,筆者加了中文註釋,主要步驟如下:
https://ithelp.ithome.com.tw/upload/images/20190921/20001976sR8itbJAsZ.png

  1. 合併tmdb_5000_movies.csv、tmdb_5000_credits.csv兩個檔案
movies = pd.read_csv('./tmdb_5000_movies.csv')
credits = pd.read_csv('./tmdb_5000_credits.csv')

# Join datasets
credits.columns = ['id', 'title', 'cast', 'crew']

alldata = movies.merge(credits, on = 'id')
  1. Json格式欄位處理,找出關鍵字、風格、演員、導演,這部份程式過於瑣碎,請參考 GitHub Repo 上完整的程式。

  2. 使用rake.extract_keywords_from_text()找出檔案中的所有關鍵字:去除停用詞(stop words)、標點符號(puntuation characters)後,剩下的單字。

# Initialize empty column
df['plotwords'] = ''

# function to get keywords from a text
def get_keywords(x):
    plot = x
    
    # initialize Rake using english stopwords from NLTK, and all punctuation characters
    rake = Rake()
    
    # extract keywords from text
    rake.extract_keywords_from_text(plot)
    
    # get dictionary with keywords and scores
    scores = rake.get_word_degrees()
    
    # return new keywords as list, ignoring scores
    return(list(scores.keys()))

# Apply function to generate keywords
df['plotwords'] = df['overview'].apply(get_keywords)
  1. 使用 BOW(Bag Of Words) 將每一部電影的文字內容,統計每個單字出現的次數,進而計算相似性(cosine similarity)。BOW是統計每個單字在評論中出現的次數,次數越多,表示這個單字越具代表性。
# 將文件中的詞語轉換為詞頻矩陣
cv = CountVectorizer()
# 統計每個單字出現的次數
cv_mx = cv.fit_transform(df_keys['keywords'])
# create cosine similarity matrix
cosine_sim = cosine_similarity(cv_mx, cv_mx)
  1. 推薦(Recommendation) 處理函數,輸入參數為電影名稱,輸出為前N名相似的電影
def recommend_movie(title, n = 10, cosine_sim = cosine_sim):
    movies = []
    
    # retrieve matching movie title index
    if title not in indices.index:
        print("Movie not in database.")
        return
    else:
        idx = indices[title]
    
    # cosine similarity scores of movies in descending order
    scores = pd.Series(cosine_sim[idx]).sort_values(ascending = False)
    
    # top n most similar movies indexes
    # use 1:n because 0 is the same movie entered
    top_n_idx = list(scores.iloc[1:n].index)
        
    return df_keys['title'].iloc[top_n_idx]
  1. 推薦測試
# 找出Toy Story這部電影的前5部最相似的電影
recommend_movie('Toy Story', n = 5)
# 找出The Avengers這部電影的前10部最相似的電影
recommend_movie('The Avengers')

以上使用BOW,也可以改用 TF-IDF,有興趣的讀者可以參考這一篇『Building a Content Based Recommender System for Hotels in Seattle』

本例是針對文字內容找出相似性,這種方法也可以適用於類別欄位或數值欄位,就不需使用BOW,直接作cosine similarity。這種作法單純以商品屬性作比對,並未考慮使用者的評價及交易狀況,推薦的商品可能是滯銷品,會造成使用者體驗欠佳,造成使用者對推薦的內容不信任。

適用時機:沒有使用者回饋的資料,只有商品屬性資料時使用。
缺點:只會推銷屬性相近的商品,不考慮商品暢銷與否,不考慮使用者的偏好。

第二種作法

如果我們有使用者評價資料,那就可以結合商品屬性資料,那就可以作矩陣相乘,產生使用者喜歡的商品屬性,之後,就可以按第一種作法進行相似性計算或進行統計,找出推薦的商品,結果出來後,記得刪除使用者已購買過的商品。

這部份的程式碼可參考 Coursera 『Recommendation Systems with TensorFlow on GCP』線上課程的Lab,礙於版權,不能與大家分享,說聲抱歉。

適用時機:有目前使用者的偏好,可結合商品屬性資料時使用。
缺點:若是新顧客,會造成無法推薦,這就是所謂的『冷啟動』(Cold Start)的問題,遇到這種狀況,可以回歸第一種作法。

結論

下次我們來看看另一種更普遍的推薦方法 -- 協同過濾(Collaborative Filtering),集合眾人的意見,進行推薦。

相關程式碼放在這裡的 Day07 Content Based Filtering 目錄。


上一篇
Day 06:購物籃分析背後的演算法 -- Apriori
下一篇
Day 08:協同過濾(Collaborative Filtering)
系列文
一服見效的 AI 應用14

尚未有邦友留言

立即登入留言