統計学、機械学習などを使って身近な世界を分析したりするブログです

機械学習を使って自分に映画をおすすめしてみた

なんかいい映画ないかなぁと思うことは誰にだってありますよね。ちょっと時間ができた時なんかに、映画でも見てみようかと。でもこれはそんなに簡単なことではありません。

世の中にある映画なんて多すぎて一体いくつあるのか分からないくらいですし、一回選んだらだいたい2時間は取られるわけです。おもしろくない映画に2時間奪われるリスク、そして最高の映画を見ずに人生を終えてしまうリスク。こんなハイリスクを背負って僕たちは映画と向き合っていかなければいけません。

恐ろしい。

こんな恐ろしいことがありますか。

でも安心してください。機械学習がそれを解決してくれます。今回の記事では、機械学習を使って、自分自身に映画をおすすめするモデルを作ってみました。

何は無くともまずはデータが必要です。今回はみんなのレビューサイトさんからデータを拝借しています。

みんなのレビューサイトでは、レビュアーが自身のプロフィールを登録し、いろんな映画をレビューしています。レビューは0〜10点の評価点とコメントの2種類でなされます。この記事では、コメントではなく評価点を使ってレコメンドモデルを構築していきます。

スクレイピング編は以下の記事をご覧ください。

www.analyze-world.com

取得したデータは、レビュアー数2,755人、映画数20,655本、レビュー数320,358です。データサイズとしては十分でしょう。

さて、まずはレコメンドモデル構築の前に、データの中身を見ていきましょう。なお、言語はRを使っており、コードはGitHubに置いてあります。

github.com

データ探索

どんなレビュアーがいるのかを見ておきます。

f:id:shokosaka:20171121074702p:plain

年齢、性別を入力していないレビュアーは省いていますが、これでおおよその分布を知ることができます。

一番多いのは31〜35歳で、25歳以下と56歳以上はやや少なめです。全体的に男性が多いですが、31〜35歳だけ女性数が異常に多いですね。ライフスタイルと関係しているのでしょう。映画供給サイドにとってはこのあたりの分析を深めていけば マーケティングに使えそうです。

年齢、性別によって、評価点の付け方は変わるのでしょうか。見てみましょう。

f:id:shokosaka:20171121074839p:plain

ある程度レビュアー数のいる26〜55歳だけに絞っています。まず、 評価点は0〜10点でつけるようになっていますが、全体的にレビュー評価点の平均値は5点ではなく、6〜7点のようです。

興味深いのは、26〜30歳の若い世代では男性の方が高い評価点をつけがちですが、46歳以上の世代では逆に、女性の方が平均評価点が高くなっています。若い女性は映画に対して辛口な傾向があるのでしょうか。興味深いですね。

次に、どんな映画の評価点が高いのかが気になるところです。

ここでは、各映画の平均評価点とそのバラツキ(標準偏差)をプロットします。

f:id:shokosaka:20171121074934p:plain

なんと美しいプロットでしょうか。形状、密度、左のほうの半円っぽいやつ。最高です。

このプロットが三角形っぽくなるには必然性があります。

バラツキ(標準偏差)が大きいということは、高い評価点をつけた人と低い評価点をつけた人の差が大きいことを表しています。つまり、賛否両論ある映画だと言えます。

平均値が10点になるには、全員が10点をつける必要があるため、バラツキは0になります。0点の場合も同様です。ところが、平均点が5点になるためには、極端な話、全員が5点をつける場合と、半数の人が10点をつけて他の人は0点をつける場合があり、後者の場合バラツキが最大になります。

また、このプロットから、平均値が4〜8、標準偏差が1〜3の映画が多いことも見て取れます。

では、このプロットの左上、つまりバラツキが小さく、平均点が高いエリアを拡大して、どんな映画があるか見てみます。

f:id:shokosaka:20171121075028p:plain

これが、バラツキが少なく、平均点が高いTOP20の映画です。なお、レビュー数は少ないと信頼性に欠けるため、30人以上にレビューされたものだけ表示しています。

「ロード・オブ・ザ・リング」強し。

「バック・トゥ・ザ・フューチャー」、「ターミネーター2」、「ショーシャンクの空に」などの有名どころや、「サウンド・オブ・ミュージック」、「ローマの休日」などの古き良き映画の中に、最近の映画である「この世界の片隅に」がランクインしていますね。

これらの映画は、誰に見せても高評価が得られると言っても過言ではありません。過言ではありませんが、過言があるとすれば、映画マニア向けのコアなものが入っている可能性があります。例えば、「人情紙風船」は1937年公開の日本映画で、万人受けするかどうかは疑問が残ります。しかし、少なくとも30人からは高評価を得ているので、見る価値はあるとも言えそうです。より万人受けする映画を知りたいのであればレビュー数を100以上などに限定すれば良いですが、隠れた名作が埋もれてしまうことになるので注意しましょう。

平均点とレビュー数をプロットしたものがこちらです。

f:id:shokosaka:20171121075138p:plain

レビュー数が多い映画ほど評価が高い傾向にあります。これは当然の結果でしょう。

良い映画の方が話題になりますし、そのような映画をレビューする人が増えるのは自然な流れです。何も面白いことはありませんね。さて、それでは次に移りましょう。


あれ?

ちょっと待ってください。レビュー数が多いのに評価が低い映画もありますね。どういうことでしょうか。中をのぞいて見ましょう。

f:id:shokosaka:20171121075230p:plain

これが100人以上にレビューされているにもかかわらず平均点が4点以下の問題作たちです。

「デビルマン」や「ファイナルファンタジー」など、漫画やゲームが原作のものや、「スピード2」や「バトルロワイアル2」などの二作目ものが入っています。このような映画はたとえ評価が低くとも話題性があり、ある程度の人に見てもらえるのでしょう。

また、これは映画レビューサイトなので、「ひどい映画があると聞いて見てみたらホントにひどかった」という映画ファンならではの怖いもの見たさみたいなものもあるのかもしれません。

試しにこれらの映画名でググると、どれだけひどいかをレビューしたブログがたくさんあり、それらを読むと逆に興味が湧くのでオススメです。


だいたいの状況がつかめましたね。それでは、いよいよレコメンドモデルを作っていきましょう。

レコメンドモデル構築

レコメンドモデルの構築には、いろいろな手法がありますが、今回はユーザーベースド協調フィルタリングを用います。これは、「あなたと同じ好みの人はAさんで、Aさんが映画Bを高評価しているので、あなたにもオススメです」という手法です。自分と感性が似ている人のオススメは信用できますよね。これを使います。

問題は、自分と感性が似ている人をどう見つけるか。膨大なデータの中から目で見て探すことは不可能です。ここが機械学習の出番なわけです。

具体的には、以下の手順で進めます。

1. レビューしていない映画をレビュアーの平均点で置き換え
2. 正規化(平均点を0、標準偏差を1に変換)
3. レビュアー(自分含む)をクラスタリング
4. クラスタごとに映画の評価点を算出
5. 自分が属しているクラスタの高評価点映画が自分にとってのオススメ!

1. レビューしていない映画をレビュアーの平均点で置き換え

簡単な例で説明します。

天空の城ラピュタ 風の谷のナウシカ シザーハンズ ターミネーター
田中 8 6 4
安藤 10 9 6 4
中山 5 10 6

ここに3人のレビュアーがいて、それぞれ0〜10点でレビューしています。

1つ目の問題は、レビューしていない映画があることです。田中にとっての「シザーハンズ」、中山にとっての「天空の城ラピュタ」がそれです。そのままコンピューターに計算させると、これらは0として扱われます。それでは困ります。見ていないのと、評価点が0点というのはまるっきり違います。

そこで、各レビュアーの平均点で空欄を埋めます。

天空の城ラピュタ 風の谷のナウシカ シザーハンズ ターミネーター
田中 8 6 6 4
安藤 10 9 6 4
中山 7 5 10 6

はい、これで空白問題は解決されました。

2. 正規化(平均点を0、標準偏差を1に変換)

次は、レビュアーによって評価点の付け方が違う問題です。以下の図を見てください。

f:id:shokosaka:20171121075501p:plain

これは、実際にレビュアーを2人抜き出して評価点の分布を比較したものです。レビュアー1は7〜8点をつけることが多いのに比べて、レビュアー2は5〜6点が多く、また0点をつけることもよくあります。

この場合、レビュアー1にとっての7点とレビュアー2にとっての7点は意味合いが異なります。レビュアー1にとっての7点は「悪くない」に対して、レビュアー2にとっての7点は「結構いい」という感じでしょうか。

天空の城ラピュタ 風の谷のナウシカ シザーハンズ ターミネーター
田中 8 6 6 4
安藤 10 9 6 4
中山 7 5 10 6

この例でも、安藤よりも田中の方が低く点数をつける傾向にあるのが分かります。これを正規化して、各レビュアーに対して平均値が0、標準偏差が1になるように変換します。

天空の城ラピュタ 風の谷のナウシカ シザーハンズ ターミネーター
田中 1.22 0 0 -1.22
安藤 1 0.64 -0.45 -1.18
中山 0 -0.93 1.39 -0.46

正規化してみると、例えば、天空の城ラピュタに対して、田中は8点、安藤は10点と評価していたものの、 実際には田中の方が高評価しているということが分かります。

ここまでで、見たことのない映画に対する評価をニュートラルにし、評価の付け方の癖を調整することができました。

3. レビュアー(自分含む)をクラスタリング

今回のデータには2,755人のレビュアーが含まれています。この中で自分と感性が似た人を探すのが目的ですが、たった一人を探すべきでしょうか。たとえ感性が似ているとしても、たった一人の意見を信じ込むのはリスキーです。

そこで、自分を含め、全てのレビュアーをいくつかのクラスタに分けます。すると、自分は感性が似ている人たちと同じクラスタに所属することになります。たった一人の意見よりも、自分と感性が似ている人たちで構成されたクラスタ内での評価の方が信用できそうです。

クラスタの数をいくつにするか、それが問題です。

クラスタ数が少なすぎると、いろんな趣向の人たちがまとめられてしまうため、個人個人の好みに合わせてパーソナライズすることが難しくなります。一方、クラスタ数が多すぎると、クラスタ内の人数が少なくなり、たった一人の意見を信じ込んでしまう問題に近いものが発生してしまいます。

今回は、そのバランスを考慮し、クラスタ数を50に設定します。つまり、自分を含めた全レビュアーをその趣向別に50個のクラスタに分類します。この50という数字は結構恣意的なものです。

さて、ここからが機械学習の出番です。

クラスタリングの手法にはKmeansを用いますが、この手法は初期値の影響を大きく受ける問題があるので、まずは良い初期値を得るために階層クラスタリングをします。

以下の図が、階層クラスタリングを用いて、レビュアーを50個のクラスタに分類したものです。

f:id:shokosaka:20171121075622p:plain

う〜ん、なんだか階層っぽいぞ、という感じですね。あと色が綺麗。

ここで得た各クラスタの中心値をKmeansの初期値として与えて、改めてクラスタリングします。

まぁ、ざっくり言うと、階層クラスタリングでクラスタリングして、Kmeansで調整する、といった感じです。

4. クラスタごとに映画の評価点を算出

Kmeansでクラスタリングをすると、各クラスタの中心値が与えられます。これこそが、「クラスタごとの各映画への評価点」となります。

何を言っているのかさっぱり分かりませんね。

先ほどの例で見てみましょう。

天空の城ラピュタ 風の谷のナウシカ シザーハンズ ターミネーター
田中・安藤クラスタ 1.11 0.32 -0.27 -1.2
中山クラスタ 0 -0.93 1.39 -0.46

これは、上のやり方と同様に、クラスタ数を2に設定して実際に階層クラスタリングとKmeansで計算した結果です。

好みが似ている田中と安藤が同じクラスタに入り、クラスタの中心値が表示されています。なんと、単に田中と安藤の評価点が平均されているだけです。

仕組みは驚くほど簡単ですが、データが大きくなると手計算できなくなるので、コンピューターに任せる必要があります。

これで、自分を含めた全てのレビュアーを趣向別に50個のクラスタに分類し、さらにクラスタ別に各映画に対する評価点を得ることができました。

5. 自分が属しているクラスタの高評価点映画が自分にとってのオススメ!

さて、ついに結果発表です!

一体どんな映画がオススメされているのでしょうか。

その前に、僕の好みを晒しておきましょう。全部で148本の映画にレビューしましたが、その中で9〜10点をつけたのは以下の映画たちです。

タイトル 評価点
もののけ姫 10
フォレスト.ガンプ.一期一会 10
ライフ.イズ.ビューティフル 10
パッチ.アダムス 10
ショーシャンクの空に 9
サマーウォーズ 9
シン.ゴジラ 9
千と千尋の神隠し 9
レオン.完全版 9
バック.トゥ.ザ.フューチャーPART2 9
耳をすませば 9
ウォーターボーイズ 9
サトラレ.TRIBUTE.to.a.SAD.GENIUS 9
モンスターズ.インク 9
I.am.Sam.アイ.アム.サム 9
スタンド.バイ.ミー 9
AKIRA 9
ジム.キャリーはMr.ダマー 9
ザ.マジックアワー 9
ドリームガールズ.2006. 9
ALWAYS.三丁目の夕日 9

わりかしジブリが好きで、あとは少し悲しくも爽快感のある映画が好きなのかなぁといった感じでしょうか。

それでは、機械学習を使ったレコメンドモデルが僕に推奨する映画TOP20はこちら!

クラスタ内ランキング 総合ランキング タイトル
1 3 天空の城ラピュタ
2 53 フォレスト・ガンプ/一期一会
3 12 ロード・オブ・ザ・リング/王の帰還
4 28 セブン
5 20 パルプ・フィクション
6 21 となりのトトロ
7 8 風の谷のナウシカ
8 493 手紙(2006)
9 85 レオン/完全版
10 167 耳をすませば
11 406 千と千尋の神隠し
12 29 CUBE
13 153 アポロ13
14 323 もののけ姫
15 20627 リリイ・シュシュのすべて
16 249 タイタニック(1997)
17 199 機動警察パトレイバー2 the Movie
18 39 グラディエーター
19 1 ショーシャンクの空に
20 500 劇場版 フランダースの犬

どうですか!!すごくないですか!?

一番左が、僕が属するクラスタ内でのランキング、総合ランキングというのは、全クラスタを合わせた中でのランキングです。例えば、「リリイ・シュシュのすべて」は、全体的には評価されていないけれども、このクラスタには高評価だということです。

ちなみに、青字のタイトルが、僕が見たことがない、つまり事前に評価をインプットしていない映画です。それらがこのようにパーソナライズして推奨されています。

すごい!!

ランキングを見ると、ジブリや「フォレスト・ガンプ」、「レオン」など、事前に高評価でインプットしているものがランクインしているので、妥当性はありそうです。

これで僕はもう「全米で大ヒット!」とか「全米が泣いた!」とかいう煽り文句に惑わされることはなくなりました。なんせ、機械学習が僕にとっておきの映画をオススメしてくれるのですから。

いやぁ、機械学習って、本当にいいものですね。

ところで、他のクラスタにはどんな映画がオススメされているのでしょうか。50個のクラスタのうち、そのいくつかをちょっと見てみましょう。

まずはこちら!

クラスタ内ランキング 総合ランキング タイトル
1 2 バック・トゥ・ザ・フューチャー
2 4 ターミネーター2
3 6 ダイ・ハード
4 55 バック・トゥ・ザ・フューチャーPART3
5 42 バック・トゥ・ザ・フューチャーPART2
6 3 天空の城ラピュタ
7 30 ザ・ロック
8 22 ターミネーター
9 33 ジュラシック・パーク
10 94 インディ・ジョーンズ/魔宮の伝説
11 34 スター・ウォーズ
12 1 ショーシャンクの空に
13 249 タイタニック(1997)
14 112 スピード(1994)
15 10 ルパン三世 カリオストロの城
16 185 逃亡者(1993)
17 92 フェイス/オフ
18 855 ホーム・アローン
19 32 マトリックス
20 66 エイリアン2

1980年〜1990年最高!クラスタ

1980年〜1990年の映画がずらり。特にバック・トゥ・ザ・フューチャーに目がないクラスタ。年齢はおそらく30代〜40代でしょう。

次はこちら!

クラスタ内ランキング 総合ランキング タイトル
1 12 ロード・オブ・ザ・リング/王の帰還
2 25 ロード・オブ・ザ・リング/二つの塔
3 375 ロード・オブ・ザ・リング
4 63 ラスト サムライ
5 1 ショーシャンクの空に
6 2 バック・トゥ・ザ・フューチャー
7 18 ライフ・イズ・ビューティフル
8 39 グラディエーター
9 26 ビッグ・フィッシュ
10 51 ギルバート・グレイプ
11 31 遠い空の向こうに
12 5 サウンド・オブ・ミュージック
13 90 インファナル・アフェア
14 55 バック・トゥ・ザ・フューチャーPART3
15 3 天空の城ラピュタ
16 13 ニュー・シネマ・パラダイス
17 40 ラブ・アクチュアリー
18 32 マトリックス
19 277 ロード・オブ・ザ・リング - スペシャル・エクステンデッド・エディション -
20 10 ルパン三世 カリオストロの城

ロード・オブ・ザ・リング好きすぎクラスタ

ロード・オブ・ザ・リング好きすぎです。今回の分析にはタイトルや監督の情報を入れていないので、これは驚くべき結果です。ロード・オブ・ザ・リングを好きな人は「ラストサムライ」も好きな可能性が高いようです。

こちらはどうでしょう。

クラスタ内ランキング 総合ランキング タイトル
1 24 ゴッドファーザーPART II
2 11 ゴッドファーザー
3 4 ターミネーター2
4 65 セント・オブ・ウーマン/夢の香り
5 138 ブラックホーク・ダウン
6 1 ショーシャンクの空に
7 64 クレイマー、クレイマー
8 219 バタリアン
9 527 2010年
10 22 ターミネーター
11 126 ブレイブハート
12 114 ブレードランナー
13 202 プライベート・ライアン
14 20228 Avalon アヴァロン
15 43 戦場のピアニスト
16 243 戦争のはらわた
17 214 ゴッドファーザーPART III
18 681 ブレードランナー 2049
19 1452 マッドマックス
20 1504 トロン:レガシー

ハードボイルドクラスタ

ゴッドファーザーを始め、渋いタイトルが並びます。アニメやコメディとは無縁。おそらく50代以降の男性で形成されたクラスタでしょう。

そして最後はこちら!

クラスタ内ランキング 総合ランキング タイトル
1 81 生きる
2 6 ダイ・ハード
3 45 ALWAYS 三丁目の夕日
4 12 ロード・オブ・ザ・リング/王の帰還
5 10 ルパン三世 カリオストロの城
6 73 2001年宇宙の旅
7 3 天空の城ラピュタ
8 102 天国と地獄
9 20624 ダンサー・イン・ザ・ダーク
10 178 ミリオンダラー・ベイビー
11 375 ロード・オブ・ザ・リング
12 54 ファイト・クラブ
13 96 Kids Return キッズ・リターン
14 47 スパイダーマン2
15 701 ニュールンベルグ裁判
16 32 マトリックス
17 34 スター・ウォーズ
18 259 ランボー
19 555 異人たちとの夏
20 19178 ヴァイブレータ

「生きる」!そして「ダイ・ハード(Die Hard)」!!

機械学習のブラックジョークはエッジが効いてますね。

まとめ

シンプルなモデルにしては、なかなか面白い結果が出たのではないかと思います。課題としては、クラスタ数が50で適切だったのか、というところですね。ここは如何せん恣意的にならざるを得ないところがあるので、もう少し試行錯誤の余地がありそうです。また、この手法ではレコメンドの対象ユーザーをクラスタに分類するときに毎回全体のクラスタリングを回さないといけないので、実装には向いてないですね。あらかじめ作っておいたクラスタとユーザーの類似性を見つけるような仕組みにした方が良さそうです。

それではまた次回の記事をお楽しみに、さよなら、さよなら、さよなら。