献立を考えるのがめんどくさい？シェフLLMと翻訳APIで解決してみた！

# はじめに...

⚠ ちゃんとした解説記事ではないので、おにぎり片手に読んでくださいな。

# 献立を考えるのって本当にめんどくさい！

毎日のご飯、どうしてますか？

僕はもう、考えるのがめんどくさすぎてつらいんですよね。

<img width="25%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522500/da2157bf-9c57-405a-0861-ddb9d55f08b5.png" >

冷蔵庫を開けて、「これで何作れるんだっけ？」と悩む時間、無駄に感じませんか？

そんなとき、ある考えがひらめきました。

「これ、AIに丸投げできないかな？」と。

<img width="25%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522500/a3e27dad-5996-865c-095b-42934d3a4532.png" >

# AIシェフ登場！

探してみたら、ありましたよ！

その名も シェフLLM（Chef Transformer（T5）**[参考文献 : 2]**）。

<img width="50%" src="https://huggingface.co/flax-community/t5-recipe-generation/resolve/main/chef-transformer.png" >

冷蔵庫にある材料を入力すると、メニューとレシピを提案してくれる夢のようなAIです。

「これで献立から解放される～！」と期待に胸を膨らませながら使ってみたんですが...。

# おい、英語しか対応してないやん！

なんと、シェフLLMは 英語専用。

私の冷蔵庫にいる「卵」「キャベツ」「豚肉」たちが、見事に「Egg」「Cabbage」「Pork」に変身しないとAIが理解してくれないんです。

![スクリーンショット 2024-12-12 181445.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522500/846b0516-e2a4-f8f9-5d52-62da52863583.png)

材料とは関係ないレシピを提案してきた...

これ、ハードル高くないですか？

でもここで諦めたらダメだと思った僕、さらなる方法を模索します。

# Google翻訳APIでパイプラインを作成！

「日本語で書いた材料を自動で英語に翻訳して、シェフLLMに投げたら良くない？」

というわけで、Google翻訳APIを導入 **[参考文献 : 1]** 。

これで冷蔵庫の材料を日本語で入力すると、自動的に英語に変換され、英語の材料データがシェフLLMに渡される仕組みを作りました！

# 📄 プログラムだよ

使用言語：Python
実行環境：Google Colaboratory
シェフ LLM：[t5-recipe-generation](https://huggingface.co/flax-community/t5-recipe-generation)
翻訳 API：[Google 翻訳 API](https://cloud.google.com/translate/?hl=ja)

## ⚙ セットアップ

### 1️⃣リクエスト送る用のモジュールのセットアップ

```python
# リクエスト送る用のモジュールをインストールする
pip install requests

# リクエスト送る用のモジュールをインポートする
import requests
```

### 2️⃣レシピ作成LLMのセットアップ

[t5-recipe-generation](https://huggingface.co/flax-community/t5-recipe-generation) の「How To Use」のセットアップコードを実行してシェフLLMを準備する。

### 3️⃣ヘルパー関数を定義する

```python
# 英語のレシピを辞書に変換するメソッド
# 引数：generated：生成された英語レシピ
# 戻り値：parsed_recipes：成形された英語レシピ
def convert_recipes_to_recipe_data(generated):

    parsed_recipes = []

    for text in generated:
        recipe = {}
        sections = text.split("\n")
        for section in sections:
            section = section.strip()
            if section.startswith("title:"):
                title = section.replace("title:", "").strip().capitalize()
                recipe["title"] = title
            elif section.startswith("ingredients:"):
                ingredients = section.replace("ingredients:", "").strip()
                recipe["ingredients"] = [ing.strip().capitalize() for ing in ingredients.split("--")]
            elif section.startswith("directions:"):
                directions = section.replace("directions:", "").strip()
                recipe["directions"] = [step.strip().capitalize() for step in directions.split("--")]

        if recipe:
            parsed_recipes.append(recipe)

    return parsed_recipes

# レシピデータを表示する関数
# 引数：recipes：成形したレシピデータ
# 出力：レシピ（料理区切り）
def show_recipe(recipes):

  for recipe in recipes:

    print("=" * 130)

    print("Title : {0}".format(recipe['title']))

    print("-" * 130)

    print("Ingredients : ")
    for ing in recipe['ingredients']:
      print(ing)
    print("-" * 130)

    print("Directions : ")
    for i, ing in enumerate(recipe['directions']):
      print(i+1, ':', ing)

    print("=" * 130)

# 翻訳関数

import json

# 引数：text：翻訳したい文章
# 引数：source_lang：翻訳前の言語
# 引数：target_lang：翻訳後の言語
# 戻り値：翻訳された文章
def translate(text, source_lang, target_lang):
      params = {'text': text, 'source': source_lang, 'target': target_lang}
      respons = requests.get('ここはGoogle翻訳APIのURLを入力してね', params=params)
      return json.loads(respons.text)['text']

# 日本語の材料データを英語の材料データに翻訳する
# 引数：text：翻訳したい文章
# 引数：source_lang：翻訳前の言語
# 引数：target_lang：翻訳後の言語
# 戻り値：翻訳された文章
def translate_ingredient_data(ingredient_data, source_lang="ja", target_lang="en"):

    translated_ingredients = []

    for ingredient_line in ingredients:
        # スペースで分割
        japanese_items = ingredient_line.split()

        # 各アイテムを英語に翻訳
        english_items = [translate(item, source_lang, target_lang) for item in japanese_items]

        # カンマ区切りで結合
        translated_ingredients.append(", ".join(english_items))

    return translated_ingredients

# 英語のレシピデータを日本語に変換する
# 引数：recipe_data：翻訳したいレシピデータ
# 引数：source_lang：翻訳前の言語
# 引数：target_lang：翻訳後の言語
# 戻り値：translated_recipes：翻訳されたレシピデータ
def translate_recipe_data(recipe_data, source_lang="en", target_lang="ja"):
    translated_recipes = []

    for recipe in recipe_data:
        translated_recipe = {}

        # タイトルの翻訳
        translated_recipe['title'] = translate(recipe['title'], source_lang, target_lang)

        # 材料の翻訳
        translated_recipe['ingredients'] = [
            translate(ingredient, source_lang, target_lang) for ingredient in recipe['ingredients']
        ]

        # 手順の翻訳
        translated_recipe['directions'] = [
            translate(direction, source_lang, target_lang) for direction in recipe['directions']
        ]

        translated_recipes.append(translated_recipe)

    return translated_recipes
```

## 🧑‍🍳アプリケーション側

### 1️⃣ 日本語で材料を入力する

```python
# ※ 材料は半角スペース区切りで入力する
# ※ 材料は料理ごとに入力する
ingredients = [
    "マカロニ バター 塩 ベーコン 牛乳 小麦粉 コショウ クリームコーン",
    "プロヴォローネチーズ ベーコン パン 生姜"
]
print(ingredients) # 確認用
```

### 2️⃣ 材料を日本語から英語に翻訳する

```python
translated_ingredients = translate_ingredient_data(ingredients, source_lang="ja", target_lang="en")
print(translated_ingredients)  # 確認用
```

### 3️⃣ 英語の材料から英語のレシピをシェフLLMに考えてもらう

```python
generated_recipe = generation_function(translated_ingredients)
print(generated_recipe)  # 確認用
```

### 4️⃣ シェフLLMが考えた英語のレシピを英語のレシピデータに変換する

```python
recipe_datas = convert_recipes_to_recipe_data(generated_recipe)
print(recipe_datas)  # 確認用
```

### 5️⃣ 英語のレシピデータを日本語のレシピデータに変換する

```python
translated_recipes = translate_recipe_data(recipe_datas, "en", "ja")
print(translated_recipes)  # 確認用
```

### 6️⃣ 日本語のレシピデータをいい感じ（!?）に表示する

```python
show_recipe(translated_recipes)
```

# 実際に使ってみたら... おお、これは便利！

「キャベツ, 卵, 豚肉, コショウ, ケチャップ, マヨネーズ, お米」を入力してみたら、出てきたメニューがこれ👇

![スクリーンショット 2024-12-12 182300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522500/5b8e4e16-d258-0a67-b86a-6b965cb39601.png)

しかも、ちゃんとしたレシピもセットで出てきます！

翻訳機を２個通しているから翻訳が微妙なところはあるけど...

手順ごとのレシピとか、ちゃんと実用的な内容。

これ、普通に使えるかも...？

# 終わりに

今回、献立をAIに考えさせる試みをやってみた結果、**メニューを考えることに関しては**めちゃくちゃ楽になりました。

しかも、翻訳APIを組み込むことで、AIシェフも多言語に対応！問題なく(笑) 使えるように。

「今日のご飯どうしよう...」と悩む時間を削減したい方、ぜひ試してみてください！



# 参考文献

1. [Google翻訳APIを無料で作る方法](https://qiita.com/satto_sann/items/be4177360a0bc3691fdf), [さっと](https://qiita.com/satto_sann, "@satto_sann") 様, 
Qiita, 投稿日：2019年07月27日
1. [t5-recipe-generation](https://huggingface.co/flax-community/t5-recipe-generation), [Flax Community](https://huggingface.co/flax-community) 様, 
Hugging Face, 公開日：2021年07月02日
1. [PythonのrequestsライブラリでHTTPリクエストを送信する方法](https://shanai-se.blog/python/library-requests/), [しゃちく](https://shanai-se.blog/) 様, 
社内SE 〜しゃちくによる社内IT化計画〜, 公開日：2023年03月18日
1. [【Python入門】splitlinesで文字列を改行で分割する方法](https://www.sejuku.net/blog/74435), [侍テック編集部](https://www.sejuku.net/blog/author/samurai-tech?utm_source=blog&utm_medium=blog&utm_campaign=blog__74435) 様, 
SAMURAI ENGINEER Blog, 投稿日：2024年5月6日