生成AIのアシストを使用して複雑なSQLクエリを作成する

生成AIを使用して複雑なSQLクエリを作成する

イントロダクション

ChatGPTの登場は、AIの歴史において前例のない瞬間を迎えました。ChatGPTや他の多くの生成型AIツールは、驚異的な能力を持っており、私たちの働き方を劇的に変える可能性があります。AI革命に続いて、データサイエンスにおけるSQLの記述は既に変化しています。この記事では、自然言語を使用してSQLデータベースと接続し、対話する具体的な例を提供します。PythonのオープンソースパッケージであるVannaを使用します。ノートブックへのリンクはこちらです。Generative AIを使用して複雑なSQLクエリの作成方法をマスターしましょう。この洞察に富んだガイドでは、自然言語のプロンプトを使用してデータベースの相互作用を効率化する方法を学びます。

学習目標

この記事では、以下のことを学びます:

  • データ駆動型プロジェクトにおいて、なぜSQLの記述が一般的な課題となるのか
  • 生成型AIがSQLをより簡単かつアクセスしやすくする可能性
  • 自然言語のプロンプトを使用してSQLを記述するためにLLMをどのように実装できるか
  • PythonのパッケージであるVannaを使用してSQLデータベースと接続し、対話する方法
  • Vannaやより広範な意味でのLLMがSQLの記述において抱える制約

この記事は、データサイエンスのブログマラソンの一環として公開されました。

データ駆動型プロジェクトにおけるSQL:一般的な課題

SQLは最もポピュラーで広く使用されているプログラミング言語の一つです。ほとんどの現代企業は、エンタープライズデータの格納と分析にSQLアーキテクチャを採用しています。しかし、会社内の全員がそのデータを活用する能力を持っているわけではありません。技術的なスキルが不足しているか、データベースの構造やスキーマに馴染みがないかもしれません。

どんな理由であれ、これはデータ駆動型プロジェクトにおいてしばしばボトルネックとなります。ビジネスの質問に答えるためには、SQLデータベースの使用方法を知っているごく少数の人々の存在に依存しています。 会社の全員が、SQLの専門知識にかかわらず、一度にいつでもどこでもデータを活用できたら素晴らしいですよね?

これは、生成型AIの助けを借りれば、近いうちに実現することができるかもしれません。開発者や研究者は、SQLの目的でトレーニングされた大規模言語モデル(LLM)の異なるアプローチを既にテストしています。たとえば、LLMベースのアプリケーションを開発するための人気フレームワークであるLangChainは、自然言語のプロンプトに基づいてSQLデータベースと接続し、対話することができます。

しかし、これらのツールはまだ初期段階にあります。大規模で複雑なデータベースで作業する場合、精度の低い結果を返したり、いわゆるLLM幻覚を経験することがよくあります。また、非技術的なユーザーにとって直感的に理解しにくい場合もあります。したがって、改善の余地はまだ大いにあります。

Vannaの概要

Vannaは、SQLの使用を民主化するために設計されたAIエージェントです。OpenAIとGoogleのサードパーティLLMの組み合わせに基づいた事前学習モデルを元に、データベースに特化したカスタムモデルを微調整することができます。

モデルが準備できたら、自然言語でビジネスの質問を投げかけると、モデルがそれをSQLクエリに変換します。また、クエリを対象のデータベースに対して実行したい場合もあります。モデルに尋ねるだけで、クエリと結果のpandas DataFrame、plotlyのチャート、および追加の質問のリストが返されます。

カスタムモデルを作成するためには、VannaはSQLの例、データベースのドキュメント、およびデータベーススキーマ(データ定義言語(DDL))など、文脈に関連する情報をトレーニングデータとして使用する必要があります。モデルの精度は、トレーニングデータの品質と量に最終的に依存します。良いニュースは、モデルが使用されるたびに生成されたSQLクエリが自動的にトレーニングデータに追加されるため、モデルが以前のミスから学び、徐々に改善していくことです。

全体のプロセスは、以下のイメージで示されています:

LLMの技術的な詳細や他の種類のニューラルネットワークについて詳しくは、この記事をご覧ください。

理論を知ったので、実際の操作に入りましょう。

始めるには

Pythonのパッケージと同様に、まずはVannaをインストールする必要があります。このパッケージはPyPIで利用可能であり、数秒でインストールできます。

Vannaをコンピュータにインストールしたら、エイリアス「vn」を使用して作業環境にインポートしてください:

# 必要な場合はvannaをインストールする
%pip install vanna

# パッケージをインポートする
import pandas as pd
import vanna as vn

Vannaを使用するには、ログインを作成し、APIキーを取得する必要があります。これは簡単なプロセスです。「vn.get_api_key()」関数をメールアドレスとともに実行すると、コードがメールで送信されます。コードを入力し、「vn.set_api_key()」を実行すると、Vannaを使用する準備ができます。

# ログインを作成し、APIキーを取得する
api_key = vn.get_api_key('[email protected]')
vn.set_api_key(api_key)

Vannaでモデルはどのように機能するのですか?

Vannaでは、必要な数だけカスタムモデルを作成することができます。たとえば、あなたが会社のマーケティング部門のメンバーであるとしましょう。通常、チームは会社のSnowflakeデータウェアハウスと部門固有のPostgreSQLデータベースを使用しています。そのため、データベースの特性やアクセス許可が異なる2つの異なるモデルを作成することができます。

モデルを作成するには、「vn.create_model(model, db_type)」関数を使用します。名前とデータベースの種類を指定します。Vannaは、SQLite、PostgreSQL、Snowflake、BigQuery、Amazon Athenaを含む、Pythonを介して接続できる任意のデータベースで使用することができます。

2つのデータベース

チームが使用する2つのデータベースに対して2つのモデルを作成したいと考えてください:

# モデルを作成する
vn.create_model(model="data_warehose", db_type="Snowflake")
vn.create_model(model="marketing_db", db_type="Postgres")

作成したモデルには、「vn.get_model()」関数を使用してアクセスできます。この関数は利用可能なモデルのリストを返します。

['data_warehose',
 'marketing_db',
 'my-dataset2',
 'demo-tpc-h',
 'tpc',
 'chinook']

作成したばかりのモデルよりも多くのモデルがあることに気付いたかもしれません。それはVannaがテスト目的で使用できる事前トレーニング済みのモデルのセットを持っているためです。

このチュートリアルの残りの部分では、「chinook」モデルで遊びます。これは、音楽ストアに関する情報を含む架空のSQLiteデータベースでトレーニングされたモデルです。明確にするために、データベースを構成するテーブルと関係性を以下に示します:

モデルを選択する

そのモデルを選択するには、次のコードを実行してください:

# モデルを設定する
vn.set_model('chinook')

この関数は、Vanna APIで使用するモデルを設定します。トレーニングデータの能力を活用して、自然言語での質問をSQLクエリに変換するために、エージェントにプロンプトを送信することができます。

ただし、生成されたSQLクエリをデータベースに対して実行するためには、エージェントを接続する必要があります。データベースのタイプによって、異なる接続関数が必要です。SQLiteデータベースを使用しているため、「vn.connect_to_sqlite(url)」関数を使用して、データベースがホストされているURLを指定します:

# データベースに接続する
url= """https://github.com/lerocha/chinook-database/raw/master
/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite"""
vn.connect_to_sqlite(url=url)

Chinookモデル

前述のように、Chinookモデルは既にコンテキストに関連する情報で事前にトレーニングされています。Vannaの最も素晴らしいことの1つは、常にトレーニングプロセスを完全に制御できることです。いつでもモデルにどのようなデータが含まれているかを確認することができます。これは「vn.get_training_data()」関数を使用して行われ、トレーニングデータを含むpandas DataFrameが返されます:

# トレーニングデータをチェックする
training_data = vn.get_training_data()
training_data

このモデルは、質問とそれに対応するSQLクエリ、DDL、データベースのドキュメントの混合でトレーニングされています。さらにトレーニングデータを追加したい場合は、vn.train() 関数を使用して手動で追加することができます。使用するパラメータによって、さまざまなタイプのトレーニングデータを収集することができます:

  • vn.train(question, sql): 新しい質問-SQLクエリのペアを追加します。
  • vn.train(ddl): モデルにDDL文を追加します。
  • vn.train(documentation): データベースのドキュメントを追加します。

例えば、質問「売上トップ5のストアはどれですか?」とその関連するSQLクエリを追加してみましょう:

# 質問-クエリのペアを追加
vn.train(question="売上トップ5のストアはどれですか?", 
         sql="""SELECT BILLINGCITY, SUM(TOTAL) 
         FROM INVOICE 
         GROUP BY 1 
         ORDER BY 2 DESC 
         LIMIT 5;""" )

モデルを手動でトレーニングすることは困難で時間がかかることがあります。また、Vannaエージェントにデータベースをクロールしてメタデータを取得するように指示してモデルを自動的にトレーニングすることもできます。ただし、この機能はまだ実験的な段階であり、Snowflakeデータベースのみで利用可能ですので、試す機会はありませんでした。

質問する

モデルの準備ができたので、最も面白い部分に入ってみましょう: 質問することです。

質問するには、vn.ask(question) 関数を使用する必要があります。簡単な質問から始めてみましょう:

vn.ask(question='売上トップ5のジャズアーティストは何ですか?')

Vannaはデフォルトで、SQLクエリ、結果のPandas DataFrame、plotlyで作成されたチャート、およびフォローアップ質問のリストを返そうとします。この行を実行すると、結果は正確に見えます:

SELECT a.name, sum(il.quantity) as total_sales
FROM artist a 
INNER JOIN album al 
  ON a.artistid = al.artistid 
INNER JOIN track t 
  ON al.albumid = t.albumid 
INNER JOIN invoiceline il 
  ON t.trackid = il.trackid 
INNER JOIN genre g 
  ON t.genreid = g.genreid
WHERE g.name = 'Jazz'
GROUP BY a.nameORDER 
BY total_sales DESC
LIMIT 5;

結果の保存

結果を印刷する代わりに保存したい場合は、print_resultsパラメータをFalseに設定し、結果を異なる変数に展開して後で必要な形式でダウンロードするなど、通常の手法を使用することができます。たとえば、DataFrameの場合はpandasの.to_csv()メソッド、可視化の場合はplotlyの.write_image()メソッドを使用することができます:

sql, df, fig, followup_questions = vn.ask(question='売上トップ5のジャズアーティストは何ですか?', 
                                          print_results=False)

# データフレームと画像を保存する
df.to_csv('top_jazz_artists.csv', index=False)
fig.write_image('top_jazz_artists.png')

関数には、auto_trainという別のパラメータもあり、デフォルトでTrueに設定されています。これは、質問が自動的にトレーニングデータセットに追加されることを意味します。以下の構文を使用して確認することができます:

training_data = vn.get_training_data()
training_data['question'].str.contains('売上トップ5のジャズアーティストは何ですか?').any()

vn.ask(question) 関数の印象的な機能にもかかわらず、実際の世界でのパフォーマンスや、より大きく複雑なデータベースに対するパフォーマンスについては疑問があります。また、強力な基盤となるLLMであっても、トレーニングプロセスが高い精度につながる鍵となります。どれくらいのトレーニングデータが必要で、どのような表現を持つ必要があるのでしょうか?トレーニングプロセスを高速化して実用的かつ運用可能なモデルを開発することはできるのでしょうか?

一方で、Vannaはまだ新しいプロジェクトであり、改善の余地があります。例えば、plotlyの可視化はあまり魅力的ではなく、カスタマイズするためのツールも存在しないようです。また、ドキュメンテーションは明確化され、具体的な例で充実させることができるでしょう。

さらに、いくつかの技術的な問題も見つけましたが、修正するのは難しくないはずです。例えば、データポイントを知りたいだけの場合、グラフを構築しようとすると関数が壊れてしまいます。これは意味があることです。なぜなら、そのようなシナリオでは可視化は意味をなさないからです。しかし、問題は、フォローアップの質問を見ることができず、さらに重要なことは、タプルを展開することができないことです。

例えば、最も年配の従業員を知りたい場合、以下のコードを実行してください。

vn.ask(question='最も年配の従業員は誰ですか')

結論

Vannaは、技術的な知識に関係なく、SQLを誰にでもアクセス可能にするためにLLMの力を活用しようとする多くのツールの1つです。結果は有望ですが、正確なSQLクエリに対してビジネスの質問に答えることができるAIエージェントを開発するにはまだ長い道のりがあります。このチュートリアルで見てきたように、強力なLLMは方程式において重要な役割を果たしますが、秘密はトレーニングデータにあると言えます。SQLの普及度の高さを考えると、クエリの書き込みタスクの自動化はゲームチェンジャーとなる可能性があります。そのため、VannaのようなAIパワードSQLツールが将来どのように進化するか注目する価値があります。

要点

  • 生成AIとLLMは従来のデータサイエンスを急速に変革しています。
  • SQLの書き込みは難しく、時間がかかるタスクであり、データ駆動型プロジェクトにおいてボトルネックとなることがよくあります。
  • 次世代のAIツールにより、SQLはより簡単でアクセス可能になるかもしれません。
  • Vannaは、LLMの力を活用してこの問題に取り組もうとする多くのツールの1つです。

よくある質問

この記事に表示されているメディアは、Analytics Vidhyaの所有ではなく、著者の裁量で使用されています。

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