DEVELOPER’s BLOG

技術ブログ

【M-1 記念】ミルクボーイを機械学習で再現してみた

2019.12.27 都築 勇祐
コラム 機械学習
【M-1 記念】ミルクボーイを機械学習で再現してみた

【ネタバレあり】


皆さん今年のM-1グランプリご覧になりましたか? 今年はミルクボーイさんが見事歴代最高得点で優勝しました。本当におめでとうございます!


ミルクボーイさんといえば

「それコーンフレークやないかい!」

「いやほなコーンフレークちゃうやないかい!」

と一方の文章に対してもう一方がコーンフレークかどうかをつっこむ、というネタですよね。


そこでテレビを見ながら思ったわけです。

「これって、機械学習でできるんじゃね?」

与えられた文章に対して、それがコーンフレークについての文章かどうかを判別する、というのはいかにも機械学習ができそうなことです。

ということで作ってみました!

スクリーンショット 2019-12-27 16.40.46.png @1_milkboy
このツイッターアカウントは入力した文章に対して「それコーンフレークやないかい!」/「いやほなコーンフレークちゃうやないかい!」と突っ込んでくれます。


BERTを使ってみた

まずは、元データを用意します。
これはミルクボーイさんの漫才の中の言葉の他に、ウィキペディアの記事などから集めてきました。
コーンフレークなら1、そうでないなら0という風に値を指定していきます。
時間もなかったので、全部で70件ほどしか集まりませんでした...
image1.png
次に、学習機です。
文章の学習、ということで用いたのはBERTです。(BERTについてはこちらを参照
Googleさんが104ヶ国語に対応しているmultilingual BERTを公開しているので、改めて日本語を学習していく必要はありません。
日本語を学習済みのBERTを使って、元データを読み込ませてどういう分がコーンフレークなのか学習していきます。

train = pd.read_csv(text, header=0)
BERT_MODEL_HUB = "https://tfhub.dev/google/bert_multi_cased_L-12_H-768_A-12/1"

[途中略]

print(f'Beginning Training!')
start_time = datetime.now()
model.train(input_fn=train_input_fn, max_steps=num_train_steps)
print("Training took time ", datetime.now() - start_time)


学習が終わったところで、実際の文で試していきましょう!

今回は
「朝ごはんに食べると目が覚めるやつ」

「ごはんと食べるとおいしいやつ」
の2文で試していきます。

前者が「ほなそれコーンフレークやないか」、後者が「ほなそれコーンフレークちゃうやないか」の予定なのですが、元データが少ないので、「朝ごはん」と「ごはん」の違いに引っかからないかがポイントですね。


labels = ["ほなそれコーンフレークやないか", "ほなそれコーンフレークちゃうやないか"]

[途中略]

predict_text = ["朝ごはんに食べると目が覚めるやつ", "ごはんと食べるとおいしいやつ"]
predictions = getPrediction(model, predict_text)
predictions


結果がこちら!
image2.png
残念ながらどちらも「ほなそれコーンフレークやないか!」とつっこまれています...
やはり元データを増やさないと精度はまだまだ出ませんね。


Word2Vecを使ってみた

ということで今度はWord2Vecを使ってみました!(切り替えが早い...)
BERTはWord2Vecより性能が高いのですが、元データが小さい場合、Word2Vecでキーワードだけ拾ったほうがよいのではと思い試してみることにしました。
まずは日本語のWord2Vecを(http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/)から引っ張ってきました。
BERTもそうでしたが、日本語に対して学習済みの機械が出ているのは非常に助かりますね!

次に、入力を処理していきます。与えられた文章の中から名詞と動詞のみを抽出し、単語のlistにします。

def counter(texts):
            t = Tokenizer()
            word_count = defaultdict(int)
            words = []
            for text in texts:
                tokens = t.tokenize(text)
                for token in tokens:
                    pos = token.part_of_speech.split(',')[0]
                    if pos in ['名詞', '動詞']:
                        # 必要ない単語を省く(実際の結果を見て調整)
                        if token.base_form not in ["こと", "よう", "そう", "これ", "それ", "もの", "ため", "ある", "いる", "する"]:
                            word_count[token.base_form] += 1
                            words.append(token.base_form)
            return word_count, words


続いて、この単語のlistとキーワード(今回はコーンフレーク)との相関度を計算します。
Gensimのライブラリは充実しているので一行ですみます。

score = self.model.n_similarity([keyword], words)


最後にこの数字が0.5以上なら「ほなそれコーンフレークやないか」、0.5以下なら「ほなそれコーンフレークちゃうやないか」を出力する、という形にしました。

if (score > 0.5):
          return("ほなそれコーンフレークやないか")
        else:
          return("ほなそれコーンフレークちゃうやないか")


これをキーワードは「コーンフレーク」、文章は「アフリカの名産品って言ってた」で試してみましょう。
文章の中から「アフリカ」「名産品」「言って」を抜き出し、それぞれと「コーンフレーク」との相関の平均を取ります。
するとなんということでしょう、「ほなそれコーンフレークちゃうやないか」と出力されるではありませんか!

さきほど失敗した「ごはんとめっちゃ合うって言ってた」でも試してみると、
今度は大成功です!


まとめ

今回Word2VecとBERTの両方を試してみて、ぱっと見たところWord2Vecのほうが結果が良いことがわかりました。
しかしこれは本当は苦肉の策です。単語だけを抜き出すより、文脈全体を考慮したほうがよいですし、0.5という敷居値も独断っと偏見でしかありません。それぞれの単語とキーワードの相関も足し合わせただけではホントは良くないかもしれません。そういった点で、最初にBERTを使ってみたのですが、いかんせん元データの数が少なすぎました。いずれ十分なデータ量がたまれば、BERTが活躍できる日が来るかもしれません。
最終的にはミルクボーイさんとコラボなんてしてみたいですね。
それではまた!皆様よい新年をお迎えください!


Twitter・Facebookで定期的に情報発信しています!

関連記事

準委任契約に込めた私たちの想い〜お客様と一緒に考える柔軟な開発のかたち~

はじめに 小さな仕様変更のつもりが、大きな追加費用の話に発展してしまった。思い描いていたイメージと違う画面ができあがってきた。そんなすれ違いに、もどかしさを感じたことはありませんか? 私たちも、「もっと柔軟に、一緒に考えられる開発のかたち」を模索してきました。 本記事では、変化に寄り添う開発パートナーでありたいという私たちの想いと、準委任契約に込めた想いをご紹介します。 一緒に考えるパートナーであるためには? 請負契約の現場でよく交わされる言葉── 例

記事詳細
準委任契約に込めた私たちの想い〜お客様と一緒に考える柔軟な開発のかたち~
コラム
受託開発でも最新技術・企画・提案にも携わることができる環境とは?

はじめに:受託開発はつらい? 「いつかは自社サービスで自由に開発がしたい」 「受託開発って納期に追われてしんどそう」 「裁量もやりがいもなさそう...」 そんなふうに思っていませんか? 最近は、SNSやイベントでも"自社サービス開発の魅力"が語られる場面が多く、「エンジニアとしてカッコいいキャリア=自社サービスに関わること」といったイメージが強まっているように感じます。 でも、実は受託開発にもさまざまなスタイルがあり、その中には"やりたいこと"を

記事詳細
受託開発でも最新技術・企画・提案にも携わることができる環境とは?
コラム
システム導入の成功戦略:パッケージ (もしくはSaaS)かオーダーメイドか?

企業のシステム選びにおける選択肢 パッケージとオーダーメイド開発の比較 オーダーメイド開発で競争力を強化する最新アプローチ オーダーメイド開発が向いている企業とは? まとめ 1.企業のシステム選びにおける選択肢 近年、企業のデジタル変革が加速する中で、自社に最適なシステムを選定することが、競争力を左右する重要な要素となっています。企業がシステムを導入する際の選択肢として、大きく分けて「パッケージ※1」と「オーダーメイド開発」の2

記事詳細
システム導入の成功戦略:パッケージ (もしくはSaaS)かオーダーメイドか?
コラム
クラウド時代のセキュリティ運用最適化:SREが推奨する5つのポイント

はじめに 「ゼロトラスト」の考え方を取り入れる 設定ミスを防ぐ!インフラのコード化(IaC)を活用 「監視」と「インシデント対応」の自動化を強化 セキュリティパッチの適用を自動化する 社員のセキュリティ意識を高める まとめ 1.はじめに 最近、「クラウドを導入したものの、セキュリティ運用が複雑になって管理が大変...」といったお悩みを耳にすることが増えました。クラウドの柔軟性や拡張性を活かしつつ、どうすればセキュリティリスクを

記事詳細
クラウド時代のセキュリティ運用最適化:SREが推奨する5つのポイント
SRE コラム

お問い合わせはこちらから