GPTモデルを活用して、自然言語をSQLクエリに変換する

GPTモデルを活用して、自然言語をSQLクエリに変換する方法

 

自然言語処理(Natural Language Processing、NLP)は大きく発展しており、GPTモデルはこの革命の最前線にあります。

今日、LLMモデルはさまざまなアプリケーションで使用できます。

不必要なタスクを回避し、ワークフローを向上させるために、私はGPTをトレーニングしてSQLクエリを作成する可能性を探り始めました。

そして、素晴らしいアイデアが浮かびました。

GPTモデルの力を利用して、自然言語を解釈し構造化されたSQLクエリに変換することです。

これは可能なのでしょうか?

一緒にすべてを発見しましょう!

それでは最初から始めましょう…

 

「フューショットプロンプティング」という概念

 

「フューショットプロンプティング」という概念は、ある人にはすでにおなじみのものかもしれませんが、他の人はこれを聞いたことがないかもしれません。

では、それは何でしょうか?

基本的なアイデアは、いくつかの明示的な例(またはショット)を使用してLLMを特定の方法で応答するように誘導することです。

これが「フューショットプロンプティング」と呼ばれる理由です。

単純に言えば、ユーザーの入力のいくつかの例(サンプルプロンプト)と望ましいLLMの出力を示すことによって、モデルに、私たちの好みに沿った向上した出力を提供することを教えることができます。

これにより、「モデルの知識を拡大し、特定のドメインにおいて望ましいタスクとより一致した出力を生成する」ということができます。

それでは、具体例を示しましょう!

このチュートリアルでは、GPTモデルにプロンプトを与えるためにchatgpt_call()という定義済みの関数を使用します。詳細を理解したい場合は、次の記事を参照してください。

例えば、「楽観主義」という用語をChatGPTに説明してもらいたいとします。

単にGPTに説明を求めると、真面目で退屈な説明を得ることになります。

## コードブロックresponse = chatgpt_call("楽観主義について教えてください。簡潔にしてください。")print(response)

 

対応する出力は次のとおりです。

  

ただし、もっと詩的なものが欲しい場合を想像してみてください。プロンプトに詩的な定義を求めるように詳細を追加することができます。

## コードブロックresponse = chatgpt_call("楽観主義について教えてください。簡潔にしてください。詩的な定義を作成してください。")print(response)

 

しかし、この2番目の出力はただの詩のようで、私が望んでいる出力とは全く関係ありません。

  

どうすればいいでしょうか?

もっとプロンプトを詳細にし、良い出力が得られるまで反復することができます。ただし、これには多くの時間がかかります。

その代わりに、モデルに自分の好みに合った詩的な説明の種類を示すことで、モデルに見せることができます。

## コードブロックprompt = """以下のスタイルに合致するよう一貫したスタイルで答えることがあなたのタスクです。
「忍耐力について教えてください。」
「忍耐力は風に対してしなやかに曲がる木のようなもので、決して折れません。逆境から立ち直り、前進し続ける能力です。」
「楽観主義について教えてください。」"""
response = chatgpt_call(prompt)print(response)

 

すると、出力はまさに私が求めていたものです。

  

それでは、このアプローチをSQLクエリの具体的なケースにどのように適用するかを考えてみましょう。

 

NLPを使用したSQL生成の方法

 

ChatGPTは、自然言語のプロンプトからSQLクエリを生成することがすでに可能です。モデルにテーブルを示さなくても、仮想の計算を行い、クエリを生成することができます。

<pre><code>## コードブロック user_input = """製品と注文のテーブルがあると仮定して、どの製品の情報がすべて含まれ、それがいくつ売れたかを表す単一のテーブルを生成できますか?"""prompt = f"""次の自然言語のプロンプトで、SQLで必要なタスクを達成するための仮想クエリを生成してください。 {user_input}"""response = chatgpt_call(prompt)print(response)</code></pre><p> </p><p>しかし、ご存知の通り、<strong>モデルに与えるコンテキストが多ければ多いほど、より良い結果が生成されます。</strong> </p><p> <img src="//www.kdnuggets.com/wp-content/uploads/ferrer_leveraging_gpt_models_transform_natural_language_sql_queries_5.png"/> </p><p>このチュートリアルでは、入力プロンプトをユーザーの要求の具体化とモデルの高レベルの動作に分割しています。これは、GPTとの相互作用を改善し、プロンプトをより簡潔にするための良い慣行です。<a href="https://www.voagi.com/benefits-of-using-linkedin-for-data-scientists.html">次の記事で詳しく調べることができます。</a></p><p>では、2つの主要なテーブル(PRODUCTSとORDERS)で作業していると想像しましょう</p><p> <img src="//www.kdnuggets.com/wp-content/uploads/ferrer_leveraging_gpt_models_transform_natural_language_sql_queries_12.png"/> </p><p>単純なクエリをGPTに問い合わせると、モデルはすぐに解決策を提供します。最初のクエリと同じように、私の場合、特定のテーブルが使用されます。</p><pre><code>## コードブロック user_input = """店舗で最も売れたテレビモデルはどれですか?"""prompt = f"""次のSQLテーブルが与えられた場合、必要なSQLクエリを提供するための仕事があなたに割り当てられています。テーブル:<{sql_tables}>ユーザーの要求:```{user_input}```"""response = chatgpt_call(prompt)print(response)</code></pre><p> </p><p>sql_tablesは、この記事の最後にあることができます!</p><p>そして、出力は次のようになります!</p><p> <img src="//www.kdnuggets.com/wp-content/uploads/ferrer_leveraging_gpt_models_transform_natural_language_sql_queries_2.png"/> </p><p>ただし、前の出力にいくつかの問題があることがわかります。</p><ol type="1"><li>計算が部分的に間違っています。すでに納品されたテレビのみを考慮しているため、発行された注文(納品されたものであろうとなかろうと)はすべて販売として考慮する必要があります。 </li><li>クエリの形式が望んでいる形式ではありません。 </li></ol><p>まず、モデルに必要なクエリの計算方法を示しましょう。 </p><p> </p><h2 id="fixing-some-misunderstandings-of-the-model">#1. モデルの誤解を修正する</h2><p> </p><p>この最初の場合では、モデルは納品された製品のみが販売されたと考えていますが、これは事実ではありません。<strong>私たちは、同様のクエリを計算する二つの異なる例を表示することで、この誤解を簡単に修正できます。</strong></p><pre><code>## Few_shotの例fewshot_examples = """-------------- FIRST EXAMPLEUser: 店舗で最も売れたテレビモデルはどれですか? System: まず、注文と製品の両方のテーブルを結合し、テレビに対応する注文のみをフィルタリングして、発行された注文の数を数えます。SELECT P.product_name AS model_of_tv, COUNT(*) AS total_soldFROM products AS PJOIN orders   AS O ON P.product_id = O.product_idWHERE P.product_type ='テレビ' GROUP BY P.product_nameORDER BY total_sold DESCLIMIT 1;-------------- SECOND EXAMPLEUser: すでに納品済みで最も多く販売されている商品は何ですか?System: 注文と製品の両方のテーブルを結合し、すでに納品された注文の数を数えて、最初のものだけを保持します。SELECT P.product_name AS model_of_tv, COUNT(*) AS total_soldFROM products AS PJOIN orders   AS O ON P.product_id = O.product_idWHERE P.order_status = '納品済み' GROUP BY P.product_nameORDER BY total_sold DESCLIMIT 1;"""</code></pre><p> </p><p>これでもう一度モデルにプロンプトを表示して、前の例を含めると、対応するクエリは正しいだけでなく(前のクエリはすでに機能していましたが)、望むように販売も考慮されることがわかります!</p><pre><code>## コードブロック user_input = """店舗で最も売れたテレビモデルはどれですか?"""prompt = f"""次のSQLテーブルが与えられた場合、必要なSQLテーブルを提供するための仕事が与えられています。テーブル:<{sql_tables}>。前の例に従って回答を生成し、クエリの構造化方法と形式に注意してください:<{fewshot_examples}>ユーザーの要求:```{user_input}```"""response = chatgpt_call(prompt)print(response)</code></pre>

 

以下の出力を使用する:

 私のJupyterノートブックのスクリーンショット。GPTのプロンプト。

さて、対応するクエリを確認しましょう…

## コードブロックpysqldf("""SELECT P.product_name AS model_of_tv, COUNT(*) AS total_soldFROM PRODUCTS AS PJOIN ORDERS AS O ON P.product_id = O.product_idWHERE P.product_type = 'TVs'GROUP BY P.product_nameORDER BY total_sold DESCLIMIT 1;""")

 

完璧に機能します!

 私のJupyterノートブックのスクリーンショット。GPTのプロンプト。

 

#2. SQLクエリの書式設定

 

フューショットのプロンプティングは、モデルを自分自身の目的やスタイルにカスタマイズする方法の1つでもあります。

前の例に戻ると、クエリはまったく書式設定されていませんでした。そして、私たちはSQLクエリをよりよく読むためのいくつかの良いプラクティスと、私たち自身の奇妙さがいくつかあります。

これはなぜフューショットのプロンプティングを使用して、自分がクエリしたい方法をモデルに示すことができるのです – 私たちの良いプラクティスまたはただの奇妙さを持って- そしてモデルをトレーニングして、要求された形式のSQLクエリを提供してもらうのです。

したがって、今度は以前と同じ例を準備しますが、私のスタイルの好みに従います。

## コードブロックfewshot_examples = """---- 例 1ユーザー:店舗で最も多く販売されたテレビモデルは何ですか? システム:まず、注文と製品のテーブルを結合し、テレビに対応する注文のみをフィルタリングし、発行された注文の数をカウントします:SELECT        P.product_name AS model_of_tv,        COUNT(*)       AS total_soldFROM products AS PJOIN orders   AS O  ON P.product_id = O.product_id  WHERE P.product_type = 'TVs'GROUP BY P.product_nameORDER BY total_sold DESCLIMIT 1;---- 例 2ユーザー:最新の注文は何ですか? システム:まず、注文と製品のテーブルを結合し、最新の注文作成日時でフィルタリングします:SELECT       P.product_name AS model_of_tvFROM products AS PJOIN orders AS O   ON P.product_id = O.product_id  WHERE O.order_creation = (SELECT MAX(order_creation) FROM orders)GROUP BY p.product_nameLIMIT 1;"""

 

例が定義されたら、それらをモデルに入力して、モデルが示されたスタイルを模倣できるようにします。

以下のコードボックスで観察できるように、GPTに期待する出力を示した後、与えられた例のスタイルを再現して、新しい出力を生成します。

## コードブロックuser_input = """店舗で最も人気のある製品モデルは何ですか?"""prompt = f"""次のSQLテーブルが与えられた場合、ユーザーの要求を満たすために必要なSQLテーブルを提供することがあなたの仕事です。テーブル: <{sql_tables}>。これらの例に従って、クエリの構造や書式に注意して回答を生成してください:<{fewshot_examples}>ユーザー要求: ```{user_input}```"""response = chatgpt_call(prompt)print(response)

 

以下の出力で観察できるように、機能しました!

 私のJupyterノートブックのスクリーンショット。GPTのプロンプト。

 

#3. 特定の変数を計算するためにモデルをトレーニングする

 

具体的なシナリオに深く入りましょう。最も時間がかかる製品を計算したいとします。 私たちはモデルに自然言語でこの質問を投げかけ、正しいSQLクエリを期待しています。

## コードブロックuser_input = """最も時間がかかる製品は何ですか?"""prompt = f"""次のSQLテーブルが与えられた場合、ユーザーの要求を満たすために必要なSQLテーブルを提供することがあなたの仕事です。テーブル: <{sql_tables}>。これらの例に従って、クエリの構造や書式に注意して回答を生成してください:<{fewshot_examples}>ユーザー要求: ```{user_input}```"""response = chatgpt_call(prompt)print(response)

しかしながら、私たちが受け取った答えは正確とは程遠いものでした。

Jupyter Notebookのスクリーンショット。GPTをプロンプト。

何が間違っているのでしょうか?

GPTモデルは、二つの日時のSQL変数の差を直接計算しようとします。 この計算方法は、ほとんどのSQLバージョンと互換性がありません。特にSQLiteユーザーにとっては問題が生じます。

この問題をどのように修正すればよいのでしょうか?

解決策は私たちの鼻先にあります – 私たちはフューショットプロンプティングに戻るのです。

モデルに通常どのように時刻変数を計算するかを示すことで、この場合は配送時間をトレーニングして、同様の変数型に遭遇した場合にはそのプロセスを複製するようにトレーニングします。

例えば、SQLiteユーザーはjulianday()関数を使用することがあります。この関数は、ユリウス暦の初期エポックから経過した日数に日付を変換します。

これにより、GPTモデルがSQLiteデータベース内の日付の差をより良く処理できるようになります。

## もう一つの例を追加しますfewshot_examples += """------ EXAMPLE 4User: Compute the time that it takes to delivery every product?System: You first need to join both orders and products tables, filter only those orders that have been delivered and compute the difference between both order_creation and delivery_date.: SELECT     P.product_name AS product_with_longest_delivery,    julianday(O.delivery_date) - julianday(O.order_creation) AS TIME_DIFF    FROM     products AS PJOIN     orders AS O ON P.product_id = O.product_idWHERE     O.order_status = 'Delivered';"""

この方法をモデルの例として使用すると、モデルは配送時間の計算方法を学びます。これにより、モデルは特定の環境にカスタマイズされた機能的なSQLクエリを生成するために適しています。

前の例を入力として使用すると、モデルは配送時間の計算方法を複製し、今後は具体的な環境に対する機能的なクエリを提供するでしょう。

## コードブロックuser_input = """What product is the one that takes longer to deliver?"""prompt = f"""Given the following SQL tables, your job is to provide the required SQL tablesto fulfill any user request.Tables: <{sql_tables}>. Follow those examples the generate the answer, paying attention to boththe way of structuring queries and its format:<{fewshot_examples}>User request: ```{user_input}```"""response = chatgpt_call(prompt)print(response)

Jupyter Notebookのスクリーンショット。GPTをプロンプト。

要約

結論として、GPTモデルは自然言語をSQLクエリに変換する優れたツールです。

しかしながら、完全なものではありません。

モデルは、適切なトレーニングがなければコンテキストに応じたクエリや特定の操作を理解できないかもしれません。

フューショットプロンプティングを使用することで、モデルを私たちのクエリスタイルと計算の好みを理解するように導くことができます。

これにより、データサイエンスのワークフローでGPTモデルの力を最大限に活用し、モデルを私たちの独自のニーズに適応させることができます。

フォーマットされていないクエリから完全にカスタマイズされたSQLクエリまで、GPTモデルはパーソナライズの魔法を私たちの手元にもたらします!

直接私のGitHubでコードを確認できます。

## SQLテーブルsql_tables = """CREATE TABLE PRODUCTS (    product_name VARCHAR(100),    price DECIMAL(10, 2),    discount DECIMAL(5, 2),    product_type VARCHAR(50),    rating DECIMAL(3, 1),    product_id VARCHAR(100));INSERT INTO PRODUCTS (product_name, price, discount, product_type, rating, product_id)VALUES    ('UltraView QLED TV', 2499.99, 15, 'TVs', 4.8, 'K5521'),    ('ViewTech Android TV', 799.99, 10, 'TVs', 4.6, 'K5522'),    ('SlimView OLED TV', 3499.99, 5, 'TVs', 4.9, 'K5523'),    ('PixelMaster Pro DSLR', 1999.99, 20, 'Cameras and Camcorders', 4.7, 'K5524'),    ('ActionX Waterproof Camera', 299.99, 15, 'Cameras and Camcorders', 4.4, 'K5525'),    ('SonicBlast Wireless Headphones', 149.99, 10, 'Audio and Headphones', 4.8, 'K5526'),    ('FotoSnap DSLR Camera', 599.99, 0, 'Cameras and Camcorders', 4.3, 'K5527'),    ('CineView 4K TV', 599.99, 10, 'TVs', 4.5, 'K5528'),    ('SoundMax Home Theater', 399.99, 5, 'Audio and Headphones', 4.2, 'K5529'),    ('GigaPhone 12X', 1199.99, 8, 'Smartphones and Accessories', 4.9, 'K5530');CREATE TABLE ORDERS (    order_number INT PRIMARY KEY,    order_creation DATE,    order_status VARCHAR(50),    product_id VARCHAR(100));INSERT INTO ORDERS (order_number, order_creation, order_status, delivery_date, product_id)VALUES    (123456, '2023-07-01', 'Shipped','', 'K5521'),    (789012, '2023-07-02', 'Delivered','2023-07-06', 'K5524'),    (345678, '2023-07-03', 'Processing','', 'K5521'),    (901234, '2023-07-04', 'Shipped','', 'K5524'),    (567890, '2023-07-05', 'Delivered','2023-07-15', 'K5521'),    (123789, '2023-07-06', 'Processing','', 'K5526'),    (456123, '2023-07-07', 'Shipped','', 'K5529'),    (890567, '2023-07-08', 'Delivered','2023-07-12', 'K5522'),    (234901, '2023-07-09', 'Processing','', 'K5528'),    (678345, '2023-07-10', 'Shipped','', 'K5530');"""

  Josep Ferrer はバルセロナ出身のアナリティクスエンジニアです。彼は物理工学を卒業し、現在は人間の移動に応用されたデータサイエンスの分野で働いています。彼はデータサイエンスとテクノロジーに特化したパートタイムのコンテンツクリエイターでもあります。彼にはLinkedInTwitter、またはVoAGIで連絡することができます。 

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI研究

複雑なAIモデルの解読:パデュー大学の研究者が、ディープラーニングの予測を位相マップに変換

複雑な予測モデルの高度なパラメータ化の性質により、予測戦略の説明と解釈が困難です。研究者たちは、この問題を解決するた...

機械学習

「埋め込みを使った10の素敵なこと!【パート1】」

「クラシックな機械学習(ML)から一歩踏み出して、埋め込みはほとんどのディープラーニング(DL)のユースケースの中核です...

AIニュース

開発者や企業のためのジェミニAPIとさらに新しいAIツール

「ジェミニAPIおよびそれ以外にも4つのAIツール、Imagen 2、MedLM、開発者向けのDuet AI、セキュリティオペレーション向けのD...

機械学習

「DAE Talking 高忠実度音声駆動の話し相手生成における拡散オートエンコーダー」

今日は、新しい論文と、私が出会った中で最高品質の音声駆動ディープフェイクモデルについて話し合いますマイクロソフトリサ...

AI研究

Google DeepMindの研究者がSynJaxを紹介:JAX構造化確率分布のためのディープラーニングライブラリ

データは、その構成要素がどのように組み合わさって全体を形成するかを説明するさまざまな領域で構造を持っていると見なすこ...

人工知能

チャットGPT vs Gemini:AIアリーナでのタイタン同士の激突

はじめに 人工知能の世界では、GoogleのGemini AIとOpenAIのChatGPTの2つの巨人の間で魅惑的な一戦が繰り広げられています。C...