Skip to content

Instantly share code, notes, and snippets.

@akiniwa
Last active November 27, 2023 02:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akiniwa/0251987701a6f3700cbc68a91af95ffb to your computer and use it in GitHub Desktop.
Save akiniwa/0251987701a6f3700cbc68a91af95ffb to your computer and use it in GitHub Desktop.

最強の英単語帳

Anki & 生成AIで最強の英単語帳を作る。

  • やりたいこと
  • 英単語を効率的に学習したい。

Ankiとは

https://apps.ankiweb.net/

anki2

単語カード(リングカード)のアプリ版で、苦手な単語は頻繁に、覚えてる単語はときどきしか出ない。 個人的には、英単語帳の中で覚えきれなかった単語(100~200個くらい)をAnkiに入れている。

Ankiの説明、ChatGPTの要約:
Ankiは、暗記のための認知科学技術を用いた無料のオープンソースフラッシュカードプログラムで、
内容に依存せず、HTMLを使って様々なメディアを含むカードを提示します。
このプログラムは、1980年代に開発されたSM-2アルゴリズムに基づく間隔反復法を採用しており、
カードの優先度や緊急度に応じて表示を調整します。
データはSQLite形式で保存されます。
  • メリット -> 科学的に効率よく英単語を覚えられるらしい。

  • デメリット -> 自分でカードを作るのがめんどくさい。単語カードの表裏をcsvファイルで作成する。

  • 英単語帳に必要な要素

    • MUST
      • 覚えたい英単語 -> 手動で頑張る
      • 英単語の日本語の意味 -> ChatGPT
    • WANT
      • 例文 -> ChatGPT
      • 音声 -> Ankiの拡張機能(内部的にはオンライン辞書やGCPのText-to-Speechなど利用)
      • 画像 -> Stable Diffusion

単語の意味、例文、例文の翻訳をChatGPTで作成する。

anki

  • 以下の3つをChatGPTで作成。
    • 単語の意味
    • 例文
    • 例文の翻訳
  • 例文と例文の翻訳をまとめて依頼すると、結果が安定しなかった。
  • 普通に回答させると、Certainly! Here's the requested informationとか余計なことを返すので、Function Callingを使う。
  • gpt-4-1106-previewでは、結果が安定しなかったので、gpt-3.5-turboを使った。
  • 例文の翻訳を返すときに、"Japanese sentence"だと、空が返ったり、英語例文がそのまま入ってしまったりした。"Translated Japanese"が一番安定した。Google Translate使ったほうが無難?
  • 単語の意味は、該当しない品詞を勝手に返すことがよくある。cooperativeは動詞の意味はない。関連語のcooperateの意味をとってる?
import argparse
import csv
import html
import os
import json
from openai import OpenAI

from google.cloud import translate_v2 as translate


# APIキーを設定. OPENAI_API_KEYを自動的に読み込む。
client = OpenAI()
TARGET_LANG = "ja"

parser = argparse.ArgumentParser()
parser.add_argument("--csv_file_path", type=str, required=True,
                    help="英単語ファイルのパス. csvファイルの第一列目にある英単語から例文を生成します.")
parser.add_argument("--output_file_path", type=str, required=True,
                    help="出力ファイルパス. 元のファイルの右側に例文を追加します.")
args = parser.parse_args()



def translate_text(target: str, text: str) -> dict:
    """Translates text into the target language.

    Target must be an ISO 639-1 language code.
    See https://g.co/cloud/translate/v2/translate-reference#supported_languages
    """
    translate_client = translate.Client(target_language=target)

    if isinstance(text, bytes):
        text = text.decode("utf-8")

    # Text can also be a sequence of strings, in which case this method
    # will return a sequence of results for each text.
    result = translate_client.translate(text)

    return result


def generate_sentence_from_word(word):
    # APIへのクエリを作成
    template = f"Please Create an English sentence using the word {word}?"
    # template = f"Please Ceate an English sentence using the word {word} and translate the created English sentence into Japanese."
    response = client.chat.completions.create(
            # model="gpt-4-1106-preview",
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": template},
                ],
            functions=[
                {
                    "name": "get_english_sentence",
                    "description": "Show an English sentense",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "sentence": {
                                "type": "string",
                                "description": "Created English sentence",
                                },
                            },
                        },
                    }
                ],
            function_call={"name": "get_english_sentence"},
            )
    return json.loads(response.choices[0].message.function_call.arguments)


def generate_translation_from_sentence(sentence):
    # APIへのクエリを作成
    template = f'次の英文を日本語に翻訳してください。"{sentence}"'
    response = client.chat.completions.create(
            # model="gpt-4-1106-preview",
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": template},
                ],
            functions=[
                {
                    "name": "get_japanese_translation",
                    "description": "Show translated Japanese sentence",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "translation": {
                                "type": "string",
                                "description": "Translated Japanese",
                                },
                            },
                        },
                    }
                ],
            function_call={"name": "get_japanese_translation"},
            )
    return json.loads(response.choices[0].message.function_call.arguments)


def generate_jp_words_from_english(word):
    # APIへのクエリを作成
    template = f"{word}という英単語の日本語での意味を、名詞、動詞、形容詞、副詞の品詞ごとに教えてください。該当しない品詞は回答する必要がありません。"
    response = client.chat.completions.create(
            # model="gpt-4-1106-preview",
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": template},
                ],
        functions=[
            {
                "name": "get_json",
                "description": "英単語の日本語の意味を品詞ごとに示す",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "noun": {
                            "type": "string",
                            "description": "日本語の名詞の意味",
                        },
                        "verb": {
                            "type": "string",
                            "description": "日本語の動詞の意味",
                        },
                        "adjective": {
                            "type": "string",
                            "description": "日本語の形容詞の意味",
                        },
                        "adverb": {
                            "type": "string",
                            "description": "日本語の副詞の意味",
                        },
                    },
                },
            }
        ],
        function_call={"name": "get_json"},
            )
    return json.loads(response.choices[0].message.function_call.arguments)



# CSVファイルを開く
with open(args.csv_file_path, 'r') as csv_file, open(args.output_file_path,
                                                     'w') as w_file:
    reader = csv.reader(csv_file)
    writer = csv.writer(w_file)

    # 各行を読み込む
    for row in reader:
        word = row[0]
        sentence = generate_sentence_from_word(word)
        translation = generate_translation_from_sentence(sentence["sentence"])
        jp_words = generate_jp_words_from_english(word)
        # jp_text = translate_text(TARGET_LANG, sentence)["translatedText"]
        # jp_text = html.unescape(jp_text)
        # writer.writerow([row[0], row[1] + "<br>" + sentence + "<br>" + jp_text])
        
        print(jp_words)
        w = f"<ul>"
        if "verb" in jp_words:
            w += f"<li>[V]: {jp_words['verb']}</li>"
        if "verb" in jp_words:
            w += f"<li>[N]: {jp_words['noun']}</li>"
        if "adverb" in jp_words:
            w += f"<li>[adv]: {jp_words['adverb']}</li>"
        if "adjective" in jp_words:
            w += f"<li>[adj]: {jp_words['adjective']}</li>"
        w += "</ul>"
        s = f"<ul><li>{sentence['sentence']}</li><li>{translation['translation']}</li></ul>"
        writer.writerow([row[0], w + s])


生成されたcsvの一部

solitary,<ul><li>[adv]: 孤独に</li><li>[adj]: 孤独な</li></ul><ul><li>She enjoys spending long solitary walks in nature.</li><li>彼女は自然の中で長い一人散歩をすることを楽しんでいます。</li></ul>
needy,<ul><li>[adj]: 助けを必要とする</li></ul><ul><li>The organization provides assistance to the needy individuals in the community.</li><li>組織は地域の困窮者に支援を提供します。</li></ul>
attentive,<ul><li>[adv]: 注意深く</li><li>[adj]: 注意深い</li></ul><ul><li>She was very attentive during the meeting.</li><li>会議中、彼女はとても注意深かったです。</li></ul>
denote,<ul><li>[V]: 示す</li><li>[N]: 示すこと</li><li>[adv]: 示して</li><li>[adj]: 示された</li></ul><ul><li>The red color is often used to denote danger.</li><li>赤色は危険を示すためによく使われます。</li></ul>
tribunal,<ul><li>[V]: 審理する</li><li>[N]: 審問所、裁判所</li><li>[adv]: 審法により</li><li>[adj]: 審判の</li></ul><ul><li>The tribunal was tasked with overseeing the legal proceedings.</li><li>裁判所は、法的手続きの監督を担当しました。</li></ul>

Stable Diffusionで画像生成

英単語に関連したイメージと一緒に覚えると記憶に残りやすいので、単語(と例文)から画像生成する。 AnkiはHTMLが使えるので、画像も埋め込むことができる。

https://www.rarejob.com/englishlab/column/20210914/

みなさんは英単語やイディオムを覚える際、どうしても覚えられないものにでくわしたことはありませんか?
何度も声に出したり、書いたりしても覚えられないものがあるかもしれません。

そんな時、その単語を絵や写真などのイメージとともに覚えると記憶に残りやすいという側面があります。

以下、生成したイメージ。 例文のほうがそれっぽい画像ができてそう。

  • solitary

  • cooperative

  • attentive

  • denote

  • tribunal

  • She was very attentive during the meeting

  • The organization provides assistance to the needy individuals in the community.

  • She enjoys spending long solitary walks in nature.

  • The tribunal was tasked with overseeing the legal proceedings.

  • The team members are working in a cooperative manner to achieve their goals.

  • The red color is often used to denote danger.

スクリーンショット 2023-11-27 11 22 45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment