こしあん
2018-07-06

ニューラル協調フィルタリングで特徴量抽出して、アニメ同士の足し算・引き算をやってみる

Qiitaからお引越しテスト。Qiitaの記事では、ニューラル協調フィルタリングでMyAnimeListのレコメンドデータから、アニメの作品単位の特徴量抽出を行い、クラスタリングの手法を用いて、アニメを10個のグループに分類しました。この記事では、同様に抽出した特徴量を用いて、Word2Vecの「王+女-男=女王」のようなアニメ単位での足し算・引き算を行います。

元データはKaggleのMyAnimeListを使いました。

リポジトリ

https://github.com/koshian2/MyAnimeList_NCF
事前準備として、上記リポジトリからdataをダウンロードしておきます。また、analyze_plus.pyの表示用の関数を定義しておきます。コサイン類似度でソートしたり、IDを探してきたりする関数なので、特に解説はいらないと思います。

注意点

Qiitaのときと同じですが、「AIが分析したからこれは絶対的に正しい」「ディープラーニングでやったから人間よりも精度がいい」なんて誤解されると残念なので少し注意書きを書いておきます。

  • 今回出てきたモデルや結果は、ニューラルネットワークの性質上、エポック数、モデル設定、学習率や活性化関数などたくさんのハイパーパラメータの設定の中の1つにすぎません。これらの値が変われば(最悪初期値の乱数次第)結果が大きく変わるおそれがあります。
  • 結果は人間の目から見て大まかにあっているところもあれば、感覚的に結構おかしいところもあります。盲目的に信頼せず、こういう結果もあるんだ、ここはすごいけどここはダメだなぐらいの感じで見てください。

このモデルに関しての注意点です。

  • データとして与えているのは、どのユーザーがどのアニメに対して点数(1~10)で評価したかという情報だけです。アニメのタイトルや説明文、キャプチャ画像、ジャンル(マスターデータにはありますが使っていません)、口コミ文章などは一切与えていません。

アニメの類似度

初代ガンダムと似ているアニメ

まずはニューラル協調フィルタリングから求められた特徴量から、アニメどうしの類似度を見ていきます。例として初代ガンダムを見てみましょう。

if __name__ == "__main__":
    # データの読み込み
    anime = pd.read_csv("data/anime.csv")
    data = np.load("data/rating_light.npz")
    anime_features = np.load("data/anime_features.npz")["anime_features"]

    ## 似ているアニメ
    # 初代ガンダムを探す
    anime_lookup("Mobile Suit")
    # 初代ガンダムはanime_id = 80
    print_similar(80)

タイトルからanime_idを探して、作品の特徴量をコサイン類似度で比較して類似度が高いものから順にソートしています。アバウトに言うと、この類似度が高いほど「AIは2つのアニメが似ていると評価した」ということになります。

— Mobile Suit Gundam と似ているアニメ —
第 1 位 : Kyougoku Natsuhiko: Kousetsu Hyaku Monogatari (id = 279 ) 類似度 = 0.
919703
第 2 位 : Alien 9 (id = 1177 ) 類似度 = 0.9914942
第 3 位 : Metropolis (id = 522 ) 類似度 = 0.9900147
第 4 位 : Umi ga Kikoeru (id = 743 ) 類似度 = 0.98906034
第 5 位 : Mobile Suit Gundam: Char's Counterattack (id = 87 ) 類似度 = 0.9
54095
第 6 位 : The Big O (id = 567 ) 類似度 = 0.9779
第 7 位 : Bartender (id = 1589 ) 類似度 = 0.9771706
第 8 位 : NieA Under 7 (id = 800 ) 類似度 = 0.97462153
第 9 位 : The Animatrix (id = 1303 ) 類似度 = 0.97408974
第 10 位 : Hadashi no Gen (id = 1824 ) 類似度 = 0.970876

MyAnimeListyが英語なので、タイトルも英語表記されています。最も似ていると判断されたのは「京極夏彦 巷説百物語」でした。他のガンダム作品は「逆襲のシャア」だけ5位に、「Theビッグオー」なんかも入っていますが、全般的にこの順位は漠然としすぎかなと思います。何回か試してみたところ最近のアニメのほうがうまくいきやすいです。

きんいろモザイクと似ているアニメ

類似度検索で比較的うまくいくのが最近の深夜アニメ、特にきらら系アニメはかなり納得できる結果が出てきます。試しに「きんいろモザイク」の類似度を1期、2期で見てみます。コードは同様にanime_idを取ってきて類似度ソートするだけなので省略します。

— Kiniro Mosaic と似ているアニメ —
第 1 位 : Strike Witches Movie (id = 9751 ) 類似度 = 0.9915364
第 2 位 : Kanamemo (id = 5914 ) 類似度 = 0.9912745
第 3 位 : Gakuen Utopia Manabi Straight! (id = 1858 ) 類似度 = 0.9879216
第 4 位 : Hello!! Kiniro Mosaic (id = 23269 ) 類似度 = 0.9870818
第 5 位 : Yuru Yuri Nachuyachumi! (id = 23225 ) 類似度 = 0.98599994
第 6 位 : 30-sai no Hoken Taiiku (id = 9624 ) 類似度 = 0.9859426
第 7 位 : Yuru Yuri San☆Hai! (id = 30279 ) 類似度 = 0.98512614
第 8 位 : Gochuumon wa Usagi Desu ka? (id = 21273 ) 類似度 = 0.9805925
第 9 位 : Futakoi Alternative (id = 126 ) 類似度 = 0.9794409
第 10 位 : Gochuumon wa Usagi Desu ka?? (id = 29787 ) 類似度 = 0.97854054

— Hello!! Kiniro Mosaic と似ているアニメ —
第 1 位 : Gochuumon wa Usagi Desu ka?? (id = 29787 ) 類似度 = 0.9882132
第 2 位 : Kiniro Mosaic (id = 16732 ) 類似度 = 0.9870818
第 3 位 : Gochuumon wa Usagi Desu ka? (id = 21273 ) 類似度 = 0.98687494
第 4 位 : Yuru Yuri San☆Hai! (id = 30279 ) 類似度 = 0.985822
第 5 位 : Strike Witches: Operation Victory Arrow (id = 23725 ) 類似度 = 0.984379
第 6 位 : Tantei Opera Milky Holmes Dai 2 Maku (id = 11341 ) 類似度 = 0.9836747
第 7 位 : Yuru Yuri Nachuyachumi! (id = 23225 ) 類似度 = 0.98323166
第 8 位 : Strike Witches Movie (id = 9751 ) 類似度 = 0.98233503
第 9 位 : Yuuki Yuuna wa Yuusha de Aru (id = 25519 ) 類似度 = 0.98071516
第 10 位 : GA: Geijutsuka Art Design Class (id = 5670 ) 類似度 = 0.9801143

1期は「かなめも」「きんモザ2期」「ごちうさ1期、2期」の4/10、2期は「ごちうさ1期、2期」「きんモザ1期」「GA」の4/10がきらら系でした。「ゆるゆり」はきらら系ではありませんが、作品のテイストはかなり似ているのでここに出てきてもおかしくはないかなと思います。2期の類似度は個人的にはかなり納得できたものでした。少なくとも先程のガンダムの例よりは精度全然いいです。

アニメ同士の足し算・引き算

今アニメ作品単位の特徴量は16次元の数値ベクトルなので、足し算・引き算ができます。よく「この作品とこの作品を足したらこの作品だよね」という伝え方をすることがありますが、それを計算的にできるのが面白いところです。

「ラブライブ!」+「機動戦士ガンダム」=「侵略!イカ娘」

同じサンライズ製作の「ラブライブ!」と「機動戦士ガンダム」を足してみます。今ラブライブのanime_idは15051、機動戦士ガンダムのanime_idは80です。

    ## 足し算、引き算
    # ラブライブ+ガンダム
    combined = anime_features[find_anime_index(15051), :] + anime_features[find_anime_index(80), :]
    print("ラブライブ+ガンダムに似ているアニメ")
    print_similar_vec(combined)

ラブライブ+ガンダムに似ているアニメ
第 1 位 : Shinryaku!! Ika Musume (id = 13267 ) 類似度 = 0.9663032
第 2 位 : Umi Monogatari: Anata ga Ite Kureta Koto – Shinjiau Kokoro (id = 6883
) 類似度 = 0.9553549
第 3 位 : Seikai no Monshou Special (id = 1381 ) 類似度 = 0.9535371
第 4 位 : Bakuman.: Deraman. (id = 15711 ) 類似度 = 0.94782823
第 5 位 : Baka to Test to Shoukanjuu Ni!: Mahou Hideyoshi Hideyoshi (id = 24727
) 類似度 = 0.9453857
第 6 位 : Macross 7 (id = 1397 ) 類似度 = 0.9424778
第 7 位 : Umi Monogatari: Anata ga Ite Kureta Koto (id = 6129 ) 類似度 = 0.9416
22
第 8 位 : Mahou Sensei Negima! Mou Hitotsu no Sekai Extra: Mahou Shoujo Yue (id
= 10628 ) 類似度 = 0.9395186
第 9 位 : Love Live! Sunshine!! (id = 32526 ) 類似度 = 0.9380745
第 10 位 : Dirty Pair: Bouryaku no 005-bin (id = 1795 ) 類似度 = 0.9368505

自分の想定した答えは「歌+ロボットものだと、マクロスシリーズあたりでは」でしたが、なんと「イカ娘」がトップに出てきました。これは予想外でした。「星界の紋章」が出てくるのはわからなくもない。ただ「マクロス7」が6位にきているからぎりぎり合格という感じはします。

ちなみにラブライブ単体で見ると次のようになります。

— Love Live! School Idol Project と似ているアニメ —
第 1 位 : Mikakunin de Shinkoukei (id = 20541 ) 類似度 = 0.9998947
第 2 位 : Toradora!: Bentou no Gokui (id = 11553 ) 類似度 = 0.99974275
第 3 位 : Acchi Kocchi (TV) (id = 12291 ) 類似度 = 0.99891996
第 4 位 : Chuunibyou demo Koi ga Shitai! Lite (id = 15687 ) 類似度 = 0.99866235
第 5 位 : Hayate no Gotoku!! (id = 4192 ) 類似度 = 0.9982568
第 6 位 : Maoyuu Maou Yuusha (id = 14833 ) 類似度 = 0.9978518
第 7 位 : Hayate no Gotoku! (id = 2026 ) 類似度 = 0.99684525
第 8 位 : Seitokai Yakuindomo (id = 8675 ) 類似度 = 0.99582726
第 9 位 : GJ-bu (id = 14811 ) 類似度 = 0.9956496
第 10 位 : Hanbun no Tsuki ga Noboru Sora (id = 587 ) 類似度 = 0.9954182

「未確認で進行形」「あっちこっち」「GJ部」などと似ていると評価されているので、歌やアイドルよりも、日常モノ成分が強く評価されているということでしょうか。

「ご注文はうさぎですか?」+0.25×「School Days」=「フタコイオルタナティブ」

ベクトルの足し算なので、係数をかけることができます。「ごちうさ」は毒っ気のない素晴らしい癒しアニメですが、Nice boat.でおなじみの「School Days」の過激な成分を少し加えてみます。ただ、スクイズの成分が強すぎるので1/4に希釈して加えます。

ごちうさ+0.25*School Daysに似ているアニメ
第 1 位 : Futakoi Alternative (id = 126 ) 類似度 = 0.94593835
第 2 位 : Hitohira (id = 1721 ) 類似度 = 0.94340515
第 3 位 : Moetan Specials (id = 4421 ) 類似度 = 0.9365136
第 4 位 : Shakugan no Shana Movie Special (id = 3221 ) 類似度 = 0.9357285
第 5 位 : Renkin San-kyuu Magical? Pokaan Specials (id = 1489 ) 類似度 = 0.93546
4
第 6 位 : Strike Witches Movie (id = 9751 ) 類似度 = 0.93355536
第 7 位 : Kyou no 5 no 2 (TV) (id = 4903 ) 類似度 = 0.933148
第 8 位 : Kanamemo (id = 5914 ) 類似度 = 0.9311172
第 9 位 : Mahoromatic: I'm Home! (id = 7066 ) 類似度 = 0.929941
第 10 位 : To Heart (id = 472 ) 類似度 = 0.92984354

日常系ながら若干鬱要素のあるアニメが出てきたように見えます。「ひとひら」はどのような作品かよく知らないのでなんとも言えないですが、作品紹介を読んでいると多分似ているのだろうなと思います。スクイズのような過激な成分も、0.25かけたり適度に希釈すれば「切なさ」といったベクトルになるのではないのでしょうか。

「天空の城ラピュタ」をちょっと色っぽくしてみる

さて、このデータには「鬼父」「夜勤病棟」といったHentaiアニメがあったことを思い出します。そこで、「鬼父」の特徴量を使い、Hentaiベクトルを取り出してみます。ちなみにこちらは普通の深夜アニメですが「パパのいうことを聞きなさい」は、ネタで鬼父?と言われることがあるので、「鬼父」-「パパきき」のベクトルをHentaiベクトルの代用として用いることができます。つまり、次のような計算をします。

「天空の城ラピュタ」+0.5×(「鬼父」-「パパのいうことを聞きなさい!」)

引き算するときはこのように取りたい属性以外は近いアニメを使うとうまくいきます。例えば、Hentaiベクトルを取るのに「夜勤病棟」-「ガンダム」のような計算は上手くいかないはずです。0.5の係数は鬼父のHentai属性が強すぎるので、希釈しました。1で掛けてしまうとHentaiアニメしか出てこなくなってしまうので。

天空の城ラピュタ+0.5×(鬼父-パパのいうことを聞きなさい)に似ているアニメ
第 1 位 : Majo no Takkyuubin (id = 512 ) 類似度 = 0.8749825
第 2 位 : Last Exile (id = 97 ) 類似度 = 0.8749639
第 3 位 : RahXephon (id = 165 ) 類似度 = 0.874923
第 4 位 : Noein: Mou Hitori no Kimi e (id = 584 ) 類似度 = 0.87487996
第 5 位 : Colorful (Movie) (id = 8142 ) 類似度 = 0.8748535
第 6 位 : Ghost in the Shell: Stand Alone Complex (id = 467 ) 類似度 = 0.874796
5
第 7 位 : Cowboy Bebop: Tengoku no Tobira (id = 5 ) 類似度 = 0.87476814
第 8 位 : Ghost in the Shell: Stand Alone Complex 2nd GIG (id = 801 ) 類似度 =
.8747574
第 9 位 : Casshern Sins (id = 4981 ) 類似度 = 0.8746799
第 10 位 : Macross: Do You Remember Love? (id = 1089 ) 類似度 = 0.8746503

上から「魔女の宅急便」、「ラストエグザイル」、「ラーゼフォン」となりました。色っぽいというか深夜アニメっぽくなるんでしょうね。魔女の宅急便は同じ宮崎アニメながらキキの生足の描写が素晴らしいですし、ラストエグザイルはかなりラピュタをリスペクトした部分も多いです。この結果は個人的にはかなり納得できますね。

「ガルパン」+「Free!」-「けいおん」(ガルパンを男っぽくしてみる)

さて、Word2Vecではワードのジェンダーバイアスを補正できることが確認されています。似たような感じで、登場人物に女の子が多いアニメを男っぽくしてみたり、登場人物に男が多いアニメを女っぽくしてみたりできます。それをやってみましょう。

いま、男女の例として「Free!」と「けいおん」をとってみました。どちらも京アニ製作ですし、水泳と音楽とテーマは違うものの男女のベクトルをとる例としては十分かなと思います。女っぽくするには「けいおん-Free!」を足せばいいですし、男っぽくするには「Free!-けいおん」を足せばいいです。

ガルパン+Free-けいおんに似ているアニメ
第 1 位 : Senyuu. 2 (id = 18523 ) 類似度 = 0.94757694
第 2 位 : New Game! (id = 31953 ) 類似度 = 0.9460944
第 3 位 : Ixion Saga DT (id = 14765 ) 類似度 = 0.94170475
第 4 位 : Mouretsu Pirates (id = 8917 ) 類似度 = 0.9410649
第 5 位 : A-Channel+smile (id = 11339 ) 類似度 = 0.93886906
第 6 位 : Denki-gai no Honya-san (id = 24031 ) 類似度 = 0.9351859
第 7 位 : Futsuu no Joshikousei ga [Locodol] Yattemita. (id = 22189 ) 類似度 =
.93363273
第 8 位 : Fate/kaleid liner Prisma☆Illya (id = 14829 ) 類似度 = 0.9324879
第 9 位 : Namiuchigiwa no Muromi-san (id = 16910 ) 類似度 = 0.9292762
第 10 位 : Bamboo Blade (id = 2986 ) 類似度 = 0.92850393

「戦勇。」「New Game!」「イクシオンサーガDT」がトップにきました。New Game!はちょっと違うかなという感じはしますが、「戦勇。」や「イクシオンサーガDT」は言われてみればなるほどという感じはします。必ずしも男の登場人物が多いアニメがサジェストされたわけではありませんが、こういったアニメが出てきたのは興味深いですね。

「Tiger&Bunny」+「けいおん」-「Free!」(タイバニを女っぽくしてみる)

先程女→男の計算をしたので、同様に男→女の計算をしてみます。今回はタイバニを女っぽくしてみました。

TigerBunny-Free+けいおんに似ているアニメ
第 1 位 : Mahou Shoujo Madoka★Magica Movie 1: Hajimari no Monogatari (id = 1197
7 ) 類似度 = 0.96080554
第 2 位 : Mahou Shoujo Madoka★Magica Movie 2: Eien no Monogatari (id = 11979 )
類似度 = 0.96045065
第 3 位 : Macross F Movie 2: Sayonara no Tsubasa (id = 7222 ) 類似度 = 0.9581585
第 4 位 : Hajime no Ippo: Rising (id = 19647 ) 類似度 = 0.95801693
第 5 位 : Hajime no Ippo: Champion Road (id = 264 ) 類似度 = 0.9578624
第 6 位 : Rainbow: Nisha Rokubou no Shichinin (id = 6114 ) 類似度 = 0.9567764
第 7 位 : Hajime no Ippo: New Challenger (id = 5258 ) 類似度 = 0.9544414
第 8 位 : Hikaru no Go (id = 135 ) 類似度 = 0.95321274
第 9 位 : Major S6 (id = 7655 ) 類似度 = 0.95201063
第 10 位 : Hajime no Ippo (id = 263 ) 類似度 = 0.95089656

「まどか☆マギカ劇場版」がトップになりました。個人的にはこれはかなり納得できました。あとははじめの一歩がよく出ていますね。

まとめ

ニューラル協調フィルタリングの隠れ層から、作品単位の特徴量を抽出することで、作品単位の足し算・引き算ができることがわかりました。思い出してほしいのは、これらの特徴量は作品の情報(タイトル、ジャンル、紹介文、スクショ等)を一切データとして与えていなく、ユーザーのレビューの得点だけをデータとして与えたということです。

Word2Vecなどと比べると、計算結果が不自然なところもまだ多いですが、上手くいくと面白い計算結果が出てくるのでなかなか楽しめると思います。これを通じて機械学習面白いなと感じていただければ幸いです。

Related Posts

Kerasに組み込まれているMobileNetの実装 MobileNetのsummary _________________________________________________________________ Layer (type) Output Shape Param # ...
Kerasに組み込まれているNASNet(Mobile)の実装... NASNet Mobileのsummary __________________________________________________________________________________________________ Layer (type) ...
Kerasに組み込まれているNASNet(Large)の実装... NASNet Largeのsummary __________________________________________________________________________________________________ Layer (type) ...
Google ColabのTPU環境でmodel.fitのhistoryが消える現象... Google ColabのTPU環境でmodel.fitしたときに、通常の環境で得られるhistory(誤差や精度のログ)が消えていることがあります。その対応法を示します。 原因はTPU用のモデルに変換したから まず結論からいうとこの現象はCPU/GPU環境では再発しません。TPU環境特有の現...
BrestCancerデータセットをCNNで分類する 構造化データを畳み込みニューラルネットワーク(CNN)で分析することを考えます。BrestCancerデータセットはScikit-learnに用意されている、乳がんが良性か悪性かの2種類を分類する典型的な構造化データです。サンプル数569、データの次元30の典型的な構造化データです。 なぜ畳み込...

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です