【Pandas】映画のレコメンデーション機能を作る(その1)

 

データ分析にはまっているのっくんです。

 

pandasを使ってデータ分析をしてみます。

 

映画の評価データを使ってユーザにオススメの映画を提案するコードを書いてみます。

 

映画データは以下のレポジトリのものを使用しました。

https://github.com/nishitjain/movie-recommendation-system-scratch

使用する映画のデータ

 

使用するデータは以下の通り。

映画や映画に対する評価、ユーザIDなどからなる4列のデータだ。全部で100万行程あるが、私のMacBook Proでサクサク動きました。

ここでユーザ間の類似スコアを求めてみます。

ユーザ間の類似スコアは、ユーザ1とユーザ2の映画の評価のユークリッド距離を算出することで求められます。

 

処理としては以下の通り。

  1. ユーザ1のみた映画のリストを取得
  2. ユーザ2のみた映画のリストを取得
  3. ユーザ1とユーザ2が見た共通の映画を取得
  4. 共通の映画のユーザ1とユーザ2のそれぞれの評価を取得する
  5. 2つの評価のユークリッド距離を計算する

 

ユークリッド距離っていうのは、2つのリストの距離のこと。

例えば、ユーザ1の見た3つの映画の評価が[4,3,5]、ユーザ2が[3,4,6]だった場合、引算して二乗した値の総和の平方根をとれば良い。

ユークリッド距離 = √(4-3)^2+(3-4)^2+(5-6)^2

 

では順番に解説していきます。

観た映画のリストを取得

 

観た映画リストを取得する。`to_list()`を使うとSeriesをリストにして取得できる。

def get_movies(userid):
    movies=[]
    tmp = df_rating[df_rating.UserID == userid]
    return tmp.MovieID.to_list()

 

映画の評価を取得する関数も作る。

def get_rating(userid,movieid):
    #複数条件にするにはカッコが必要、useridとmovieidの一致した行を取得,返り値はデータフレーム
    df_tmp = df_rating[(df_rating.UserID == userid) & (df_rating.MovieID == movieid)]
    #取得した行のインデックスが0ではないため、リセットする
    df_tmp = df_tmp.reset_index() 
    # 0行目、Rating列を指定する
    return df_tmp.loc[0,'Rating']

最初、useridとmovieidが一致したデータフレームのインデックスを`reset_index()`でリセットしなかったため、0番目の行を指定するとエラーがでた。

ユークリッド距離の計算

 

2つのリストから共通の項目を取り出すにはset型に変換してから積集合をとれば良い。

import math
def similarily_score(user1,user2):

    movies1 = get_movies(user1)
    movies2 = get_movies(user2)

    # リスト同士を比較して、共通の映画を取り出す
    both_movies = set(movies1) & set(movies2)
  
    rating1=[]
    rating2=[]
    for m in both_movies:
        rating1.append(get_rating(user1,m))
        rating2.append(get_rating(user2,m))
    
    # ユークリッド距離を算出
    distance = math.sqrt(sum([(a - b) ** 2 for a, b in zip(rating1, rating2)]))
    
    # ユークリッド距離の逆数をスコアとする。0除算防止のため+1をする。
    score = 1/(distance+1)
    
    return score
    
user1 = 1
user2 = 310

print(similarily_score(user1,user2))

 

参考記事のコードよりはスッキリしたコードになっていることは間違いない。

 

おわり。

参考

building-a-movie-recommendation-engine-using-pandas:

https://towardsdatascience.com/building-a-movie-recommendation-engine-using-pandas-e0a105ed6762

Python Math: Compute Euclidean distance:

https://www.w3resource.com/python-exercises/math/python-math-exercise-79.php

How can I compare two lists in python and return matches:

https://stackoverflow.com/questions/1388818/how-can-i-compare-two-lists-in-python-and-return-matches