kaggleチャレンジ12日目 映画のデータセットから類似作品を予測してみた

シェアする

  • このエントリーをはてなブックマークに追加
スポンサーリンク

はじめに

 今回は、Kaggleに公開されている映画のデータセット TMDB 5000 Movie Dataset を使っていきたいとおもいます。データセットが公開されているだけで明確な目標が設定されているわけではないので、今回はこのデータセットを使って映画のレコメンドシステムをGoogleColaboratory上で作っていきたいと思います。

今回のデータセットのリンク

参考にしたカーネル

合わせて読みたい記事

データセットの説明

  • tmdb_5000_movies.csv
  • tmdb_5000_credits.csv

カラム

tmdb_5000_movies.csv
  • budget
  • genres
  • homepage
  • id
  • keywords
  • original_language
  • original_title
  • overview
  • popularity
  • production_companies
  • production_countries
  • release_date
  • revenue
  • runtime
  • spoken_languages
  • status
  • tagline
  • title
  • vote_average
  • vote_count
tmdb_5000_credits.csv
  • movie_id
  • title
  • cast
  • crew

TMDB 5000 Movie Dataset

参考にするカーネルの名前を見ればわかると思いますが、映画のスコアやレーティングを予測使用と思います。映画のスコアは、ジャンルや映画の俳優、特に映画の監督のような様々な要因によって決まることがわかっています。このような要因をすべて考慮し、このデータセットのスコア予測をしていきたいと思います。

まず、いつも通り学習データの数件を見てみましょう。GoogleColaboratory上でデータセットを使えるようにする手順は前回の記事を参考にしてください。

ライブラリの準備

In[1]:

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
import seaborn as sns
import numpy as np
import json
import warnings
warnings.filterwarnings('ignore')
import base64
import io
from scipy.misc import imread
import codecs
from IPython.display import HTML
%matplotlib inline

データの読み込み

In [2]:
movies=pd.read_csv('tmdb_5000_movies.csv')
mov=pd.read_csv('tmdb_5000_credits.csv')
In [3]:
movies.head(3)
表は横に長くなってしまうので短縮して表示させています。
Out[3]:
budget genres homepage vote_average vote_count
0 237000000 [{“id”: 28, “name”: “Action”}, {“id”: 12, “nam… 7.2 11800
1 300000000 [{“id”: 12, “name”: “Adventure”}, {“id”: 14, “… 6.9 4500
2 245000000 [{“id”: 28, “name”: “Action”}, {“id”: 12, “nam… 6.3 4466

 データセットを確認すると、ジャンル、キーワード、production_companies、production_countries、spoken_languagesがjson形式であることがわかります。他のCSVファイルでも同様に、キャストとクルーはjson形式です。なので、それらを文字列に変換し、後のためにリストに変換します。

jsonをstringに変換

In[4]:

# changing the genres column from json to string
movies['genres']=movies['genres'].apply(json.loads)
for index,i in zip(movies.index,movies['genres']):
    list1=[]
    for j in range(len(i)):
        list1.append((i[j]['name']))# the key 'name' contains the name of the genre
    movies.loc[index,'genres']=str(list1)
    
# changing the keywords column from json to string
movies['keywords']=movies['keywords'].apply(json.loads)
for index,i in zip(movies.index,movies['keywords']):
    list1=[]
    for j in range(len(i)):
        list1.append((i[j]['name']))
    movies.loc[index,'keywords']=str(list1)
    
## changing the production_companies column from json to string
movies['production_companies']=movies['production_companies'].apply(json.loads)
for index,i in zip(movies.index,movies['production_companies']):
    list1=[]
    for j in range(len(i)):
        list1.append((i[j]['name']))
    movies.loc[index,'production_companies']=str(list1)
    
# changing the production_countries column from json to string    
movies['production_countries']=movies['production_countries'].apply(json.loads)
for index,i in zip(movies.index,movies['production_countries']):
    list1=[]
    for j in range(len(i)):
        list1.append((i[j]['name']))
    movies.loc[index,'production_countries']=str(list1)
    
# changing the cast column from json to string
mov['cast']=mov['cast'].apply(json.loads)
for index,i in zip(mov.index,mov['cast']):
    list1=[]
    for j in range(len(i)):
        list1.append((i[j]['name']))
    mov.loc[index,'cast']=str(list1)

# changing the crew column from json to string    
mov['crew']=mov['crew'].apply(json.loads)
def director(x):
    for i in x:
        if i['job'] == 'Director':
            return i['name']
mov['crew']=mov['crew'].apply(director)
mov.rename(columns={'crew':'director'},inplace=True)

変換後出力させて確認してみましょう。

In[5]:

movies.head(2)
Out[5]:
budget genres homepage vote_average vote_count
0 237000000 [‘Action’, ‘Adventure’, ‘Fantasy’, ‘Science Fi… 7.2 11800
1 300000000 [‘Adventure’, ‘Fantasy’, ‘Action’] 6.9 4500

これでデータセットを扱いやすい形に変えることができました。

In[6]:

movies=movies.merge(mov,left_on='id',right_on='movie_id',how='left')# merging the two csv files
In [7]:
movies=movies[['id','original_title','genres','cast','vote_average','director','keywords']]

In [8]:

movies.head(2)

Out[8]:

id original_title genres cast vote_average director keywords
0 19995 Avatar [‘Action’, ‘Adventure’, ‘Fantasy’, ‘Science Fi… [‘Sam Worthington’, ‘Zoe Saldana’, ‘Sigourney … 7.2 James Cameron [‘culture clash’, ‘future’, ‘space war’, ‘spac…
1 285 Pirates of the Caribbean: At World’s End [‘Adventure’, ‘Fantasy’, ‘Action’] [‘Johnny Depp’, ‘Orlando Bloom’, ‘Keira Knight… 6.9 Gore Verbinski [‘ocean’, ‘drug abuse’, ‘exotic island’, ‘east…

現在、jsonだったものは現在string型です。 次は、これをリストに変換します。 なぜなら、1つの映画には多くのジャンルがあり、それぞれを個別に取得する必要があるからです。 そのようなときにはリストが使用されます。

ジャンルのカラムでの作業

・strip() : 文字列の両端から指定文字をとる。

・replace() : 文字列の置換。

"1,2,3".replace(",", "")   #'123'

・split():区切り文字を区切りとして、文字列を分割しリストを返す。

"1, 2, 3".split(",") #['1', ' 2', ' 3'] 
In [8]:
movies['genres']=movies['genres'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['genres']=movies['genres'].str.split(',')

matplotlibで棒グラフ

bar(left,        #それぞれの棒の左端の配列 
    height,      #高さの配列
    width=0.8,   #棒の太さ
    bottom=None, #複数の棒グラフを積み上げるときの土台を示す。
    hold=None,   #
    data=None,   #
    **kwargs)
In [9]:
plt.subplots(figsize=(12,10))
list1=[]
for i in movies['genres']:
    list1.extend(i)
ax=pd.Series(list1).value_counts()[:10].sort_values(ascending=True).plot.barh(width=0.9,color=sns.color_palette('summer_r',10))
for i, v in enumerate(pd.Series(list1).value_counts()[:10].sort_values(ascending=True).values): 
    ax.text(.8, i, v,fontsize=12,color='white',weight='bold')
ax.patches[9].set_facecolor('r')
plt.title('Top Genres')
plt.show()

ドラマやコメディが人気があるみたいですね。

In [10]:
for i,j in zip(movies['genres'],movies.index):
    list2=[]
    list2=i
    list2.sort()
    movies.loc[j,'genres']=str(list2)
movies['genres']=movies['genres'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['genres']=movies['genres'].str.split(',')

今度は、データセットに含まれているジャンル全部入れたリスト ‘genreList’を生成します。

In [11]:
genreList = []
for index, row in movies.iterrows():
    genres = row["genres"]
    
    for genre in genres:
        if genre not in genreList:
            genreList.append(genre)
ジャンルを10個表示させてみましょう。
In [12]:
genreList[:10] 
Out[12]:
['Action',
 'Adventure',
 'Fantasy',
 'ScienceFiction',
 'Crime',
 'Drama',
 'Thriller',
 'Animation',
 'Family',
 'Western']

現在、映画は「アクション」といった単一のジャンルだけでなく、一部には「アクション、アドベンチャー」などジャンルを複数持つ場合があります。ジャンルに応じて、映画を分類したいですね。

ジャンルをOnehot表現に変換しましょう。

例えば、リストに20のジャンルがあるとした場合、次の関数は20の要素持つリストを返す。つまり、「アクション」というジャンルをもつ映画がある場合は、次のように表現する。

[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

同様に「アクション、アドベンチャー」の場合、[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0]と返す。こうするとジャンルで映画を分類するときやりやすいでしょう。

キャスト、ディレクター、キーワードなどの他のカラムでも同じ表現を使います。

In [13]:
def binary(genre_list):
    binaryList = []
    
    for genre in genreList:
        if genre in genre_list:
            binaryList.append(1)
        else:
            binaryList.append(0)
    
    return binaryList
In [14]:
movies['genres_bin'] = movies['genres'].apply(lambda x: binary(x))
In [15]:
movies['genres_bin'].head(4)
Out[15]:
0    [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
1    [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
2    [1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
3    [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, ...
Name: genres_bin, dtype: object
 新しいカラムができました。[‘cast’、 ‘director’、 ‘keywords’]に対しても同じことを行います。

キャストのカラムでの作業

察しのいい人はわかると思いますが、ジャンルのカラムとほぼ同様なことをします。ジャンル同様にまず、扱いやすい形に変えた後、キャストのリストを作るのですが、ここで一つ問題があります。それは、キャストの数があまりにも多いことです。全てのキャストを扱った場合、約50万ありました。ですが、これら全て必要なことはないです。映画に貢献している人物だけでいいでしょう。ということで、各映画から主要な俳優を選びます。ここで、主要な人物をどのように選ぶかですが、JSON形式で、俳優の重要性も含まれているのでこれを使います。

In[16]:

movies['cast']=movies['cast'].str.strip('[]').str.replace(' ','').str.replace("'",'').str.replace('"','')
movies['cast']=movies['cast'].str.split(',')
In [17]:
plt.subplots(figsize=(12,10))
list1=[]
for i in movies['cast']:
    list1.extend(i)
ax=pd.Series(list1).value_counts()[:15].sort_values(ascending=True).plot.barh(width=0.9,color=sns.color_palette('inferno_r',40))
for i, v in enumerate(pd.Series(list1).value_counts()[:15].sort_values(ascending=True).values): 
    ax.text(.8, i, v,fontsize=10,color='white',weight='bold')
plt.title('Actors with highest appearance')
ax.patches[14].set_facecolor('r')
plt.show()
結果はこのようになりました。Samuel Jacksonさんが一番出演しているようですね。
In [18]:
for i,j in zip(movies['cast'],movies.index):
    list2=[]
    list2=i[:4]
    movies.loc[j,'cast']=str(list2)
movies['cast']=movies['cast'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['cast']=movies['cast'].str.split(',')
for i,j in zip(movies['cast'],movies.index):
    list2=[]
    list2=i
    list2.sort()
    movies.loc[j,'cast']=str(list2)
movies['cast']=movies['cast'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['cast']=movies['cast'].str.split(',')
4人ずつ選んで、castlistに突っ込んでいきます。
In [19]:
castList = []
for index, row in movies.iterrows():
    cast = row["cast"]
    
    for i in cast:
        if i not in castList:
            castList.append(i)
In [20]:
def binary(cast_list):
    binaryList = []
    
    for genre in castList:
        if genre in cast_list:
            binaryList.append(1)
        else:
            binaryList.append(0)
    
    return binaryList
In [21]:
movies['cast_bin'] = movies['cast'].apply(lambda x: binary(x))
In [22]:
movies['cast_bin'].head(2)
Out[22]:
0    [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
1    [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, ...
Name: cast_bin, dtype: object
同じく、キャストもOne hot 表現にし、新しいカラムをつくりました。

ディレクターのカラムでの作業

行なっていることは同じなので、淡々とコードを実行していきます。

In [23]:
def xstr(s):
    if s is None:
        return ''
    return str(s)
movies['director']=movies['director'].apply(xstr)
In [24]:
plt.subplots(figsize=(12,10))
ax=movies[movies['director']!=''].director.value_counts()[:10].sort_values(ascending=True).plot.barh(width=0.85,color='y')
for i, v in enumerate(movies[movies['director']!=''].director.value_counts()[:10].sort_values(ascending=True).values): 
    ax.text(.5, i, v,fontsize=12,color='white',weight='bold')
ax.patches[9].set_facecolor('r')
plt.title('Directors with highest movies')
plt.show()
In [25]:
directorList=[]
for i in movies['director']:
    if i not in directorList:
        directorList.append(i)
In [26]:
def binary(director_list):
    binaryList = []
    
    for direct in directorList:
        if direct in director_list:
            binaryList.append(1)
        else:
            binaryList.append(0)
    
    return binaryList
In [27]:
movies['director_bin'] = movies['director'].apply(lambda x: binary(x))

キーワードのカラムでの作業

キーワードやタグには、映画に関する多くの情報が含まれており、類似の映画を見つける際の重要な特徴です。 たとえば:「Avengers」や「Ant-man」のような映画には、スーパーヒーローのような共通のキーワードがあるかもしれません。

In[28]:

!pip install wordcloud

In[29]:

from wordcloud import WordCloud, STOPWORDS
import nltk
nltk.download('stopwords')
nltk.download('punkt')
from nltk.corpus import stopwords

twitterバードのように表示させたい方は参考にしたカーネルリンクのmaskからコードを引っ張ってきてください。*載せようとしたら重くなったので止めました。

必要がない方は下のmaskを適用していない方を実行してください。

In[30]:

plt.subplots(figsize=(12,12))
stop_words=set(stopwords.words('english'))
stop_words.update(',',';','!','?','.','(',')','$','#','+',':','...',' ','')
f1=open("mask.png", "wb")
f1.write(codecs.decode(mask,'base64'))
f1.close()
img1 = imread("mask.png")
hcmask1 = img1
words=movies['keywords'].dropna().apply(nltk.word_tokenize)
word=[]
for i in words:
    word.extend(i)
word=pd.Series(word)
word=([i for i in word.str.lower() if i not in stop_words])
wc = WordCloud(background_color="black", max_words=4000, mask=hcmask1,
               stopwords=STOPWORDS, max_font_size= 60,width=1000,height=1000)
wc.generate(" ".join(word))
plt.imshow(wc)
plt.axis('off')
fig=plt.gcf()
fig.set_size_inches(10,10)
plt.show()

ストップワードとは、あまりにも使われる単語のため、テキストデータを扱う時によく除去される言葉らしい。

In[30]:

plt.subplots(figsize=(12,12))
stop_words=set(stopwords.words('english'))
stop_words.update(',',';','!','?','.','(',')','$','#','+',':','...',' ','')
#f1=open("mask.png", "wb")
#f1.write(codecs.decode(mask,'base64'))
#f1.close()
#img1 = imread("mask.png")
#hcmask1 = img1
words=movies['keywords'].dropna().apply(nltk.word_tokenize)
word=[]
for i in words:
    word.extend(i)
word=pd.Series(word)
word=([i for i in word.str.lower() if i not in stop_words])
wc = WordCloud(background_color="black", max_words=4000,
               stopwords=STOPWORDS, max_font_size= 60,width=1000,height=1000)
wc.generate(" ".join(word))
plt.imshow(wc)
plt.axis('off')
fig=plt.gcf()
fig.set_size_inches(10,10)
plt.show()

上のは、映画を説明するために使用される主要なキーワードまたはタグを示すワードクラウドです。

下のコードも今までと同じことをキーワードのカラムでやっているだけなので特に説明しません。

In [31]:
movies['keywords']=movies['keywords'].str.strip('[]').str.replace(' ','').str.replace("'",'').str.replace('"','')
movies['keywords']=movies['keywords'].str.split(',')
for i,j in zip(movies['keywords'],movies.index):
    list2=[]
    list2=i
    movies.loc[j,'keywords']=str(list2)
movies['keywords']=movies['keywords'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['keywords']=movies['keywords'].str.split(',')
for i,j in zip(movies['keywords'],movies.index):
    list2=[]
    list2=i
    list2.sort()
    movies.loc[j,'keywords']=str(list2)
movies['keywords']=movies['keywords'].str.strip('[]').str.replace(' ','').str.replace("'",'')
movies['keywords']=movies['keywords'].str.split(',')
In [32]:
words_list = []
for index, row in movies.iterrows():
    genres = row["keywords"]
    
    for genre in genres:
        if genre not in words_list:
            words_list.append(genre)
In [33]:
def binary(words):
    binaryList = []
    
    for genre in words_list:
        if genre in words:
            binaryList.append(1)
        else:
            binaryList.append(0)
    
    return binaryList
In [34]:
movies['words_bin'] = movies['keywords'].apply(lambda x: binary(x))
In [35]:
movies=movies[(movies['vote_average']!=0)] #removing the movies with 0 score and without drector names 
movies=movies[movies['director']!='']

映画間の類似性の確認

2つの映画の類似点を見つけるためにCosine Similarityを使用します。 ベクトルが2つあるとして、ベクトルが平行に近い場合、つまりベクトル間の角度が0の場合、cos(0)= 1のように両方が「類似」と言えるでしょう。 cos(90)= 0のように独立しているとか「似ていない」と言うことができるらしい。

詳細を知りたい方は次のリンクへ。

http://blog.christianperone.com/2013/09/machine-learning-cosine-similarity-for-vector-space-models-part-iii/

以下では、類似性を定義して、映画間の類似性をチェックします。

ということで、上の式を使って類似度を測る関数を作ります。

In[36]:

from scipy import spatial

def Similarity(movieId1, movieId2):
    a = movies.iloc[movieId1]
    b = movies.iloc[movieId2]
    
    genresA = a['genres_bin']
    genresB = b['genres_bin']
    
    genreDistance = spatial.distance.cosine(genresA, genresB)
    
    scoreA = a['cast_bin']
    scoreB = b['cast_bin']
    scoreDistance = spatial.distance.cosine(scoreA, scoreB)
    
    directA = a['director_bin']
    directB = b['director_bin']
    directDistance = spatial.distance.cosine(directA, directB)
    
    wordsA = a['words_bin']
    wordsB = b['words_bin']
    wordsDistance = spatial.distance.cosine(directA, directB)
    return genreDistance + directDistance + scoreDistance + wordsDistance

適当にId:3の映画とId:160の映画の類似度を出してみたいと思います。

In[37]:

Similarity(3,160)
Out[37]:
2.7958758547680684

うーん、数値で見てもよくわかりませんね。Id:3と160の映画を見てましょう。

In[38]:

print(movies.iloc[3])
print(movies.iloc[160])

Out[38]:

id                                                            49026
original_title                                The Dark Knight Rises
genres                             [Action, Crime, Drama, Thriller]
cast              [AnneHathaway, ChristianBale, GaryOldman, Mich...
vote_average                                                    7.6
director                                          Christopher Nolan
keywords          [batman, burglar, catburglar, catwoman, cover-...
genres_bin        [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, ...
cast_bin          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, ...
director_bin      [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
words_bin         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
Name: 3, dtype: object
id                                                            82702
original_title                           How to Train Your Dragon 2
genres            [Action, Adventure, Animation, Comedy, Family,...
cast              [GerardButler, JayBaruchel, JonahHill, Kristen...
vote_average                                                    7.6
director                                               Dean DeBlois
keywords          [3d, deathofhusband, dragon, fathersonrelation...
genres_bin        [1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, ...
cast_bin          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
director_bin      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
words_bin         [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
Name: 160, dtype: object

調べてみましたが、かなり異なる映画なので、類似度の数値が大きい(距離が大きい)ですね。

In[39]:

new_id=list(range(0,movies.shape[0]))
movies['new_id']=new_id
movies=movies[['original_title','genres','vote_average','genres_bin','cast_bin','new_id','director','director_bin','words_bin']]
movies.head(2)
Out[39]:
original_title genres vote_average genres_bin words_bin
0 Avatar [Action, Adventure, Fantasy, ScienceFiction] 7.2 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
1 Pirates of the Caribbean: At World’s End [Action, Adventure, Fantasy] 6.9 [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …

スコア予測

スコア予測器を作成します。映画間の類似性を計算し、最も類似した10の映画を見つける。 そして、この10個の映画から、映画のスコアの平均をとり、目的の映画のスコアを見つけます。これにより、類似作品を見つけつつ、スコアを算出することができる。

In[40]:

import operator

def whats_my_score(name):
    print('Enter a movie title')
    new_movie=movies[movies['original_title'].str.contains(name)].iloc[0].to_frame().T
    print('Selected Movie: ',new_movie.original_title.values[0])
    def getNeighbors(baseMovie, K):
        distances = []
    
        for index, movie in movies.iterrows():
            if movie['new_id'] != baseMovie['new_id'].values[0]:
                dist = Similarity(baseMovie['new_id'].values[0], movie['new_id'])
                distances.append((movie['new_id'], dist))
    
        distances.sort(key=operator.itemgetter(1))
        neighbors = []
    
        for x in range(K):
            neighbors.append(distances[x])
        return neighbors

    K = 10
    avgRating = 0
    neighbors = getNeighbors(new_movie, K)

    print('\nRecommended Movies: \n')
    for neighbor in neighbors:
        avgRating = avgRating+movies.iloc[neighbor[0]][2]  
        print( movies.iloc[neighbor[0]][0]+" | Genres: "+str(movies.iloc[neighbor[0]][1]).strip('[]').replace(' ','')+" | Rating: "+str(movies.iloc[neighbor[0]][2]))
    
    print('\n')
    avgRating = avgRating/K
    print('The predicted rating for %s is: %f' %(new_movie['original_title'].values[0],avgRating))
    print('The actual rating for %s is %f' %(new_movie['original_title'].values[0],new_movie['vote_average']))

Godfatherを予測してみる

In[41]:

whats_my_score('Godfather')
Out[41]:
Enter a movie title
Selected Movie:  The Godfather: Part III

Recommended Movies: 

The Godfather: Part II | Genres: 'Crime','Drama' | Rating: 8.3
The Godfather | Genres: 'Crime','Drama' | Rating: 8.4
The Rainmaker | Genres: 'Crime','Drama','Thriller' | Rating: 6.7
The Outsiders | Genres: 'Crime','Drama' | Rating: 6.9
The Conversation | Genres: 'Crime','Drama','Mystery' | Rating: 7.5
The Cotton Club | Genres: 'Crime','Drama','Music','Romance' | Rating: 6.6
Apocalypse Now | Genres: 'Drama','War' | Rating: 8.0
Twixt | Genres: 'Horror','Thriller' | Rating: 5.0
New York Stories | Genres: 'Comedy','Drama','Romance' | Rating: 6.2
Peggy Sue Got Married | Genres: 'Comedy','Drama','Fantasy','Romance' | Rating: 5.9


The predicted rating for The Godfather: Part III is: 6.950000
The actual rating for The Godfather: Part III is 7.100000

いかがだったでしょうか。今回は、映画のスコアと類似作品を予測してみました。

最後まで読んでいただきありがとうございました。よろしければこの記事をシェアしていただけると励みになります。よろしくお願いします。

スポンサーリンク
レクタングル広告(大)
レクタングル広告(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
レクタングル広告(大)