Machine Readable Recipe開発の舞台裏

伊尾木将之:研究開発部の伊尾木といいます。自己紹介をします。

研究開発部ではエンジニアを主にやっております。今日もエンジニアリングに関するお話なんですが、私はエンジニアリングだけではなくて食文化研究のほうも担当しております。

具体的に何をやっているかと言うと、江戸時代のレシピを研究しています。なんと最近のクックパッドって江戸時代のレシピも検索できるんです。

ご興味があればぜひ調べてみてください。江戸時代のレシピを古文献から調べて、現代の人でも料理ができるように翻訳して載せるというプロジェクトをやっております。けっこう人気のプロジェクトです。

あと、言い忘れました。私の本業は川崎フロンターレのサポーターです。もしかしてこの中にフロサポっていらっしゃいますか?

(会場挙手)

あ、ありがとうございます。3連覇がんばりましょう!

(会場笑)

今日はMachine Readable Recipeの話をしますが、そもそもMachine Readable Recipeとは何なのか? という前に、なぜこの技術が必要になったかというお話をしますね。

クックパッドはもちろんレシピがメインの会社です。ですが本当はそれだけではなくて、ミッションとして「毎日の料理を楽しみにする」ということをやりたいと思っているわけですね。宇野さんも語っていたように、そのためにいろんなチャレンジをしているのですが、うまく行っていることも、まだまだうまくいっていないこともあります

その中の1つとして、調理している現場に対して僕らがなにかできているのかというと、今はレシピを参照していただくこと以上のことはできていないじゃないかと。本当に物理的に料理をするところに対してなにもアクションできていないなと思いました。

そこを僕らはもっとサポートしたい。本当に料理を楽しみにするためには、実際に手を動かすところでサポートが必要だろうということで、「レシピのその先へ」ということで、昨年からスマートキッチン事業を始めました。

IoT家電の問題点

最近はこれらをご存知の方も多いかと思いますが、ANOVAなどですね。いわゆるIoT家電系がたくさん登場しています。ANOVAというのは、人間では制御し得ないような絶妙な温度で肉を温めてくれる機械ですね。

他には、June OvenとTasty One Topというものです。これはすごくおもしろくて、温度計を肉にぶっ刺して肉の中の温度を測ってちょうどいい温度に仕上げてくれるというものです。

こちらはホットクックですね。いわゆる全自動調理マシンと呼ばれるもので、食材を切って調味料と一緒に放り込んでおくといい感じにシチューやカレーを作ってくれるものです。

ただ、IoT家電って素敵なんですが問題が1つあります。例えばどの機械でもそうなんですが、メーカーが作った専用レシピしか対応できていません。

だけど僕らがなにか料理を作りたいと思ったときに、わざわざメーカーのところにいって検索をして、その機械で使えるレシピを探して使うという行動は基本的にはしないわけです。僕らは基本的には食べたいものを考えて、そのためのレシピを探して、結果そういうIoT家電を使うという考え方が素直なわけですよね。

クックパッドは大量レシピデータを持っていて、しかもクックパッドはそういう使われ方をしているので、クックパッドのレシピデータがこれらのIoT家電につながればいいじゃないかと思いませんか? 思いますよね!? 思ってください(笑)。

ですが、そんな簡単には連携できるわけではありません。当然、人間が書いたレシピなのでなかなか機械はスッと読んでくれません。どんな問題があるかと言うと、例えば「かぼちゃ」と材料に書かれていても、それがひらがなの「かぼちゃ」なのか、「南京」なのか、「パンプキン」なのか、あるいはカタカナの「カボチャ」なのか。表記揺れの問題があります。どの食材を言っているのかわからない。

もう1つは、手順のほうですが「蓋をして弱火で10分ほど蒸します」。これ、何を蒸してるかわかりますか? こうした自由に記述されたテキストを機械に送りつけても、機械はすごく困ってしまうわけですね。

MRRとはなにか?

というわけで、そうした自由に記述されたレシピをMRRという機械が読める形式に変換してあげて、それを機械に送れば機械は動きやすいということで、Machine Readable Recipeという技術を開発しています。

具体的にはどういうこと? というと、こういうやつです。

こういうグラフ表現されたレシピというものを僕らはMRRと呼んでいます。ちょっと見づらいんですが、一番上に「ベーコン」を切って「切ったベーコン」にする。

「ベーコン」を切って「切ったベーコン」にして、「サラダ油」と合わせて「炒めたベーコン」ノードができる。ほかに「かぼちゃ」を切っていろいろ入れて混ぜて、最後に蒸して、「蒸された野菜」ノードができます。

これなら何を蒸すかは一目瞭然ですよね。全材料を蒸しているし、かぼちゃにもID6048というIDが振られています。こうやってID化してあげると、どの材料を使うか機械は迷わなくて済むので非常に便利です。こうしてグラフ構造にされたものをMRRと呼んでいます。

これ、けっこう夢が広がる技術です。例えばIoT機器に送る以外にどんな夢が広がるかと言うと、例えば中間ノード検索みたいな話ですね。「炒めたベーコン」ノードで検索します。炒めたベーコンではピンときませんが、例えばよくある話として、にんじん、じゃがいもを切って炒めました。カレー作るつもりだったけどカレー粉がないことに気づいたから、じゃあどうしよう? みたいなとき。

そのときに「にんじんとじゃがいもを炒めた」ノードのあるレシピを探し出して、そのレシピの続きがあれば、そのレシピに移れるわけです。これは便利だと思います。

ほかにも複数のレシピをマージして最適な手順を提示してあげたり、あるいはこれだと「切る」というエッジが2つありますね。じゃあ2人いれば平行でできたり、平行でできるのであればこれくらいの調理時間で終わるとか。

あるいはコンロが2つあるから煮ると焼くが平行にできるということがグラフ表現だとよくわかります。こういう技術でやっていくために、R&Dは取り組んでいます。

調味料サーバー「OiCy Taste」

その1つのサンプルとしてOiCy Tasteという調味料サーバーを、私たちのコンセプトモデルとして提案しております。

調味料サーバーなので酒・酢・しょうゆ・みりんですね。この4種類がここから出てきます。

それはレシピがあって、MRR化されたレシピデータをこちらに送ると、その分量に従って調味料を出てくれるという機械です。ちなみにこれは技術情報を公開しております。

基盤の設計情報のコードまで公開していますので、これを見れば同じものが作れます。作って売ってみてください(笑)。

MRRってすごくいい技術だと思うんですけど、じゃあそんな夢のような技術がすぐに作れるかと言うと、やっぱりそうは問屋が卸さないので、作るのが難しいわけですね。

元のオリジナルレシピがあって、そのオリジナルレシピからいろいろな情報を抜き出さなければいけません。どんな情報を抜き出すかと言うと、材料情報です。材料名がどういう正規か。

かぼちゃをどうID化するかという話ですね。分量の正規化。大さじ1とか、1大とか、大1とか書かれたやつをどう正規化するか。

Action種類は、このエッジですね。煮る、焼くというのがどう書かれているか。中火って書かれてるとか。あるいはINPUTは何か。何と似てるのか、という情報を取らなくてはいけません。

あとはメタ情報ですね。これはグラフそのものには直接関与はしませんが、使う分には必要になってくる情報です。栄養価とか。それが主菜メニューなのか副菜なのかとか。

しかも情報を取っただけではリッチなグラフにするのはけっこう大変です。実際特殊なトポロジカルソートを開発して対応しているくらい複雑な問題なんですね。この複雑さを全部紹介していると時間がないので、今日は材料情報についてだ紹介します。

材料名の正規化

まずは材料名の正規化の話です。例えば先ほどはかぼちゃだったんですが、今度はしょうゆの例でいきましょう。「しょうゆ」という材料はみんな知ってますよね。しょうゆをクックパッドで見てみると、しょうゆという材料だけで200パターン以上の書かれ方があります。すごいですよね。

同義語表現系だと漢字の醤油、カタカナのショウ油、正しい油みたいなやつ。あとは付属表現系。これはすごく多いです。☆醤油とか、醤油(〇〇)とか、お好みで醤油みたいな。しょうゆ以外にいろんなものがくっついてしまうパターン。

こういうものを正規化するときにパッと思いつくのは正規表現だと思いますが、正規表現で対応しようとすると、確かに付属表現系はある程度うまく対応できるんですね。

ですが、同義語表現系はやはり正規表現だけでは大変で、結局全パターンを書かなくてはいけなくなってしまいます。しかも問題は「しょうゆ」だけだったらいいですけど、そんな材料や単語が何万とあるわけなんですよね。

そんなものは正規表現では対応してられないので、僕らはどうしているかと言うと、みんな大好き機械学習です。今流行ってますよね。僕らも流行りに乗っかります。

僕らはどんなモデルを使っているかと言うとEncoder-Decoderというモデルを使って対応しています。

すごく簡単に言うと……Encoder-Decoder自体は翻訳系で使われているモデルですね。それを名寄せの問題領域に適用しました。「★醤油」という入力を受け付けると、「しょうゆ」という出力を出しなさい、というようにいろいろなパターンを入力させて学習していくというものです。

これを対応した結果どれくらい対応できているかと言うと、正答率71.2パーセントです。

どう思いますか? 高いと思ってくれたらすごく嬉しいのですが、現実的にはちょっと低い感じですね。ただ、正規表現で対応した場合は28.6パーセントなので、やはり問題領域そのものが複雑で、まだまだがんばる余地があるというところです。

分量の正規化

次に分量の正規化です。「大さじ1」などですね。これもなかなか単純ではなくて、いくつかのパターンがあります。

シンプル系は本当に解析が簡単で、おおさじ1、1個とか。数値と単位だけしかないものですね。

少し複雑系は、ひとつかみ半とか、2から4人、10g(15g)……不思議でよね。どっち!? みたいな。

(会場笑)

これ、レシピ見るとわかるんです。何人分のところに2人前(3人前)って書かれてあるんですね。ですので、カッコ内は3人前のことだと思うんですけど、分量だけ与えられてもどう正規化するのかよくわかりません。あと、約大さじ1杯半ほどなども、ちょっと複雑系です。

そして本当に複雑というかもう無理系。「かぶるくらい」とか、「ウィスパージバニャン」とか(笑)。たぶんキャラ弁だと思うんですけど、もはや、なんですかね? これはどういう単位? 1ウィスパージバニャン単位なんですかね?

(会場笑)

ちょっとよくわからないんですが、まあそういうものもあるわけです。さすがにウィスパージバニャンは諦めるとしても、シンプル系と少し複雑系くらいは対応しないといけないので、これらを解析していきます。

しかもこれらは非常に種類が多いわけです。種類が多いから正規表現なんかでは対応し切れないんですけど、とはいえ機械学習に頼るほどの種類はありません。

BNFを用いて分量を解析

というわけで僕たちはどう対応しているかと言うと、BNFです。

バッカス・ナウアフォームかな? ご存知の方はこれで伝わると思いますが、要は分量を一種のプログラミング言語だと考えて、そのプログラミング言語をどう解析するかというテクノロジーがBNFや文脈自由文法と呼ばれる技術です。今回は。それを適応してあげることにします。

どういうことかと言うとquantity、分量というのはprefixとbodyとpostfixとendですよと。bodyというのはq1、q2、q3みたいなのがあって、q1、q2、q3というのはこういうパターンがあって。pre_unitは大さじ、中さじ、小さじみたいな。こういうパターンに分解できれば、数値でなにが単位かがわかります。

具体例でいくと、「約おおさじ1杯半ほど」これ全体がquantityだったとしたら、これはprefixとq3とpostfixに分けられますよね。

prefixとpostfixというのがここですね。prefix=約とか、postfix=ほどと書いてある。このように分けることができます。

q3はどうなるのか言うと、pre_unitとnumberとpost_unitとまたnumberが来ているパターン。

こうすると、どれが単位でどれが数値かが分解できるので、あとはこれをいい感じの表現にしてあげれば解析ができます。

この結果、どれくらいの解析ができているかと言うと、正答率95.2パーセントですね。

特徴的なのはPrecisionが99.9パーセント……(小さく拍手を促すジェスチャーをする)。

(会場拍手)

ありがとうございます! いやぁ、まさか拍手が起こるとは思わなかったですねぇ(笑)。

(会場笑)

正答率は95.2パーセントなんですけど、Precisionが99.9パーセントというのが非常に良いところです。Precisionというのは、解析できたときにそれをどれくらい信じていいかという割合です。

ちなみに下のRecallは解析できる範囲のうちどれくらいカバーしているのかです。全体の95.1パーセントをカバーしていて、カバーできた部分は99.9パーセントの確率で信じていい。というわけで、分量は制覇しました。

夢の技術を実現するために

MRRのまとめです。

MRRは、お話したように僕は夢があるテクノロジーだと思っています。ですが名寄せで見たように難しいことも多いですし、今日は発表しませんでしたが、Action情報の抽出はすごく難しいです。

今は任意のActionは取れなくて、狙ったActionだけを取りに行くみたいなことをやって取り出しています。本当に、先ほどのようなきれいなグラフはまだ作れていません。

ですが、すごくおもしろいところなのでやっていくしかない。可能性しか感じないという話です。以上です。ありがとうございました。

(会場拍手)