ロコガイド テックブログ

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

ふつうの開発にデータ整備を添えて

買い物事業部の小椋です。トクバイのバックエンド開発をしています。 トクバイにはお店が投稿している商品を利用して作れるレシピを紹介する機能があります。

クックパッド時代はクックパッドユーザーさんが投稿されていたレシピを紹介していましたが、サービス分離してからはトクバイ独自に管理栄養士の方に作成いただいたレシピを紹介するようになっています。 日々の生活の中でスーパーでの生鮮食料品の買い物はレシピと親和性が高いことが多いと考えられます。そのため現状よりも様々な形で活用すべく、まずWeb上で機能拡張をすることになりました。本記事ではこのレシピ機能拡張を通して当社での普通の開発を紹介したいと思います。

初手を検討する

まずは今現在トクバイで公開しているレシピを一覧できるページが必要です。 既存でまとめに使えそうなデータがあるかというと、レシピに本日発売されている商品を紹介する食材タグというものがあります。しかし食材タグは少々細かすぎるところがあり、そのままカテゴリーとして利用するには難しそうという判断もありました。どのように見せると見やすいかを検討した結果、階層化されたカテゴリーを新設することになりました。 パーティ料理やお弁当といったテーマで分ける、価格別に分けるといったことも検討されましたが、まずは既存の食材タグをカテゴリーにまとめられるようにすることが初手としてよいだろうと判断しました。

食材カテゴリーを整備する

既に存在している食材タグをどういうカテゴリーに分類するかを決めなければなりません。こちらはどう分けたいかの検討をしながらやることになるので、ディレクターにお任せすることになりました。

この階層化データをどう管理していくかを並行して検討します。

子どもの階層が固定であれば普通に関連定義をしてモデルを作ることも可能そうです。一旦は3階層までにしようという話になりましたが、今後の運用がどうなるかははっきりしません。単一の親に紐付く構造ということだけは仕様上の制約にしたいですが、階層の深さは自由度を持たせておいた方がいいでしょう。このような不特定階層の木構造はいくつかの方法で実現可能ですが、比較的直感的で簡単かなと思えるのはmaterialized paths patternでしょうか。ancestry gemが定番のようなので、今回はこれを採用することにしました。

ベースデータをancestryの構造に基づいてどのように初期設定するかも悩ましいところです。 いただいたデータは上記のように列で階層化を表現していたので、CSVで右のカラムにデータがなければ親、2番目まであれば子、といった具合で登録するワンショットバッチを作ることにしました。

このデータに基づき、カテゴリー一覧のページが出来ました。

また、このタイミングで一律だったmetaのtitleやdescriptionも動的に変更をかけました。 レシピを集約したページの大枠が整ってきたところで、トクバイの節約感があるレシピというのをもう少し押し出したいという点に注力しようという話になりました。

目安価格を整備する

節約感のあるレシピというのは材料費がお得であるということでもあるので、一食分の材料費が目安として出せると節約感がより出せるのではないかということになりました。では個々の材料費はどのように出すのがよいか、という点を考えることになります。トクバイとしてはチラシや商品を投稿していただいているのでそういった価格を読み込んで基準価格を求めるみたいなことが出来るとよいのですがまだ実用化はされていません。一旦は人手で調べて算出した基準価格を作ることにしました。

重量を整備する

問題は各材料と基準価格との比重です。 じゃがいも(小) などは小さめの分少し安くなっているはずですし、大きさ、重量に基づいて価格が異なるケースにどう対応するかが検討事項になりました。基準価格と基準重量から材料ごとのグラム単価を求められるので、基準重量を整備することで相対的に各材料の重量比を求められるか検討してみました。すぐに 適量少々 といった表現にぶつかりましたが、一旦はグラム表記があるところだけでも抽出してみます。また、手入力されているために前後に空白が入っていたり、約いくつといった概数表記も目立ちます。算数の学習以来なかなか目にすることもなかった カップ1と1/2 のような帯分数表記もありました。途中までは正規表現でスクリーニング頑張るぞ、という感じでしたが、さじの登場によって文字通りさじを投げる結果になりました。そうです、同じ大さじ1杯(15ml)でも材料によって重量が異なるので機械的に変換できなかったのです。適量なら仕方ないと思っていたものの、こちらは計算可能と思っていたのでなかなか衝撃的でした。また、標準的とする予定の 1本 などでも 1本(200g) のように重量表記されている場合もあり、基準を作ろうとしてもあってないところがありました。 重量をできるだけ抽出できるようにしてみましたが、約5500件あった主要食材のうち、1500件ほどしか機械的に抽出できませんでした。何らかの形で計算用の重量がわかればよいので、表記全てに手を入れるよりは計算用重量を個別に設定するようにした方がシンプルではないかと判断してカラム追加するようにしました。前述の機械抽出と組み合わせて約4000件ほど手動設定したのですが、なかなかしんどかったです。この辺は機械に乗っけられるところは出来るだけ乗っけた方がよいですが、下手に難しくなるくらいなら手で頑張ると割り切った方がよいのかもしれません。

さて、そんなことを経て一人分、あるいは全量でのレシピ価格が表示されるようになりました。レシピを見てお得感を感じてもらえるかどうかはまだこれからの反応次第ですが、Webに限らずアプリにも展開できるようにしていきたいですね。商品との連携も今まで以上に進めていきたいと思います。

ふりかえり

この時点でふりかえってみると、開発自体は普通で、ひたすらデータ整備している感じでした。分析や分類をする時の初手はだいたいこういったものかなとも思いますが、もう少しクレンジング部分で頑張りたかったですね。根性とかは最後の最後まで使わずにおきたいものですし。データ整備にAI活用などできないかなと思ったりもしますが、データの確からしさの確認は人間がやるしかなさそうかなとも思います。当社でもAI活用を模索していますが、諸々の精度向上が期待されるところです。

今後に向けて

まだまだ動き始めたばかりのレシピ機能拡張ですが、予定されている拡充も控えています。 実現方法はまだわかりませんが、その時々に合った方法論を模索していきたいと思います。