PandasAIとPythonでAIデータアナリストを構築する:自然言語でCSV・Excelデータをクエリする方法

AI tutorial - IT technology blog
AI tutorial - IT technology blog

問題:誰もがデータを求めているが、pandasを書きたい人はいない

こんな場面を想像してみてほしい。金曜の午後5時、上司から5万行のExcelファイルが届き、「先四半期で返品率が最も高かった地域を、製品カテゴリ別に教えてもらえるか?」と聞かれる。答えはそのスプレッドシートのどこかにあるはずだ。だが、実際の質問に取りかかる前に、pandasとgroupby、matplotlibを使った十数行のコードを書かなければならない。

これは、データと意思決定者の間に立つ誰もが経験する日常だ。インサイトを最も必要としている人たち——営業リード、プロダクトマネージャー、経営幹部——はPythonを使えないことが多い。そして、あらゆるデータの質問でエンジニアがボトルネックになる状況は、スケールしない。

根本原因:データ分析にはいまだ多くの構文知識が必要

核心的な問題はpandasが難しいことではない。データの質問は会話的なのに、ツール側ではそれをコードに翻訳することが求められる点だ。「月次売上のトレンドを見せて」という一言が、こうなる:

df['date'] = pd.to_datetime(df['date'])
monthly = df.groupby(df['date'].dt.to_period('M'))['revenue'].sum()
monthly.plot(kind='line', title='Monthly Revenue')
plt.show()

このコード自体に問題はない。しかし、毎回ゼロから書いていたら——あらゆる質問のあらゆるバリエーションごとに——データについて本質的に考える時間よりもDataFrame操作の時間の方が長くなってしまう。

TableauやPower BIといったBIツールはこの問題の一部を解決してくれる。しかし高額で、セットアップとトレーニングが必要であり、事前にダッシュボードを構築しておかないと生のCSVファイルへの任意の自然言語クエリには対応できない。

解決策の比較:本当の選択肢は何か?

選択肢1:手動でpandasスクリプトを書く

最大の柔軟性があり、魔法のような仕掛けはない。pandasに精通していれば完璧に機能する。しかし、技術的でないチームメンバーがセルフサービスで使おうとすると破綻する。新しい質問が来るたびにチケットが増える。

選択肢2:BIツール(Tableau、Power BI、Metabase)

定期的なダッシュボードや構造化されたレポートには向いている。生ファイルへのアドホックな質問には不向き。スキーマのマッピングとデータコネクタが必要で、ダッシュボードの構築・保守のために専任のアナリストが必要になることが多い。

選択肢3:ChatGPT Code Interpreter / Claude Artifacts

ファイルをアップロードして質問すれば、コードとグラフが返ってくる。一度きりの探索には有効だ。問題は、手動の対話形式のループになる点。自分のアプリケーションやパイプラインに組み込めない。プログラムからのアクセスも自動化も不可能だ。

選択肢4:PandasAI

PandasAIはLLM(OpenAI、Anthropic、Google Geminiなど)をpandasのDataFrameの周りにラップするオープンソースのPythonライブラリだ。自然言語で質問を渡すと、内部でpandasのコードを生成・実行し、結果を返してくれる。Python環境のまま使え、完全なコントロールを保てる。インターフェースはただの平易な言葉だ。

これは私が本番環境でも採用したアプローチで、技術的でないステークホルダーがターミナルを開かずに自分のデータファイルをクエリできるようにした。結果は一貫して安定していた——ビジネスレポートとして十分な精度があり、PandasAIが生成コードを表示できるため監査もしやすい。

最善のアプローチ:実践的なPandasAI

ステップ1:ライブラリのインストール

pip install pandasai
pip install pandasai[openai]   # OpenAIを使う場合
pip install pandasai[google]   # Geminiを使う場合

PandasAIは複数のLLMバックエンドをサポートしている。OpenAI GPT-4oとGoogle Geminiはどちらも良く動作する。このガイドではOpenAIを使用する。

ステップ2:CSVファイルを使った基本的なセットアップ

カラムが dateregionproductrevenueunits_sold の売上CSVがあるとする。

import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI

# データを読み込む
df = pd.read_csv("sales_data.csv")

# LLMを接続する
llm = OpenAI(api_token="your-openai-api-key")

# DataFrameをラップする
sdf = SmartDataframe(df, config={"llm": llm})

セットアップはこれだけだ。SmartDataframeはLLMが付いたpandasのDataFrameに過ぎない。すべての標準的なpandas操作は引き続き使える。

ステップ3:自然言語でクエリする

# シンプルな集計
result = sdf.chat("What is the total revenue by region?")
print(result)

# フィルタリング
result = sdf.chat("Show me all transactions where revenue exceeded 10000")
print(result)

# 時系列分析
result = sdf.chat("What was the best performing product in Q3?")
print(result)

PandasAIは各質問をpandasコードに翻訳し、DataFrameに対して実行して、質問の性質に応じて値・フィルタリングされたDataFrame・グラフのいずれかを返す。

ステップ4:Excelファイルを読み込む

複数シートのExcelファイルも同様に使える:

import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI

# 特定のシートを読み込む
df = pd.read_excel("quarterly_report.xlsx", sheet_name="Q3_Sales")

llm = OpenAI(api_token="your-openai-api-key")
sdf = SmartDataframe(df, config={"llm": llm})

result = sdf.chat("Which salesperson had the highest close rate?")
print(result)

ステップ5:グラフを自動生成する

データを求めるのと同じように、可視化をリクエストする:

# グラフを生成して保存する
sdf.chat("Plot monthly revenue as a bar chart")

# より具体的に
sdf.chat("Create a line chart showing units sold per region over time")

# カスタムスタイルのヒント付き
sdf.chat("Show a pie chart of revenue split by product category")

PandasAIは内部でmatplotlibを使用する。グラフはデフォルトでcharts/ディレクトリに保存される。出力パスは設定可能だ:

sdf = SmartDataframe(df, config={
    "llm": llm,
    "save_charts": True,
    "save_charts_path": "/var/www/output/charts"
})

ステップ6:複数のDataFrameを扱う

実際のデータセットが単一のテーブルであることはめったにない。PandasAIはSmartDatalakeを通じて複数のDataFrameの結合をサポートしている:

from pandasai import SmartDatalake

orders_df = pd.read_csv("orders.csv")
customers_df = pd.read_csv("customers.csv")
products_df = pd.read_csv("products.csv")

lake = SmartDatalake(
    [orders_df, customers_df, products_df],
    config={"llm": llm}
)

result = lake.chat("Which customer segment generates the most revenue per order?")
print(result)

LLMはカラム名とコンテキストに基づいて、どのテーブルをどう結合するかを判断する。

ステップ7:生成されたコードを確認する

本番環境の設定では、コードロギングを有効にすることを常に実践している。PandasAIが実際に実行したコードを確認できる——エッジケースの監査やデバッグに不可欠だ:

sdf = SmartDataframe(df, config={
    "llm": llm,
    "verbose": True,       # 生成されたコードを標準出力に表示
    "enable_cache": True   # 同じ質問をキャッシュする(API呼び出しを節約)
})

result = sdf.chat("What is the average revenue per transaction?")
# 標準出力に結果とともに生成されたpandasコードが表示される

本番環境利用のための実践的なヒント

  • カラム名を整理する:PandasAIはカラム名から意味を推測する。col_Aのような不明瞭なカラム名はmonthly_revenueのような説明的な名前に変更してからSmartDataframeに渡す。
  • 積極的にキャッシュを使う:同じLLM呼び出しの繰り返しを避けるためにキャッシュを有効にする(enable_cache: True)。同じデータセットへの繰り返し質問はキャッシュにヒットし、コストはゼロだ。
  • システムプロンプトを設定する:「これはUSD建ての売上データを含むeコマースのデータです」といったドメインコンテキストをPandasAIに与えることで、曖昧な質問への回答品質を向上させられる。
  • コスト管理にはGeminiを使う:Google Gemini Flashは、単純な集計クエリではGPT-4oより大幅に安価だ。一つのバックエンドに固定する前に、実際の質問タイプで両方をベンチマークしてみること。
  • ログを記録して監視する:複数のユーザーが質問できる共有環境では、すべてのクエリと生成されたコードをログに残す。誰かが出力に疑問を呈したとき、この証跡が必要になる。

オープンソースLLMを使う(APIコストなし)

データをサードパーティのAPIに送りたくない場合、PandasAIはLangChainやOllamaを通じてローカルモデルもサポートしている:

ollama pull llama3
pip install pandasai[langchain]
from pandasai.llm.langchain import LangchainLLM
from langchain_community.llms import Ollama

ollama_llm = Ollama(model="llama3")
llm = LangchainLLM(llama_llm)

sdf = SmartDataframe(df, config={"llm": llm})
result = sdf.chat("Summarize the top 5 products by revenue")
print(result)

ローカルモデルは複雑な複数ステップのクエリでは遅く精度が低いが、データを完全にオンプレミスに保てる——機密性の高いビジネスデータにとって重要な点だ。

PandasAIが苦手とするケース

率直な評価をすると:PandasAIは完璧ではない。ドメインコンテキストが重要な非常に曖昧な質問(「成功した注文とはどれを指す?」——LLMはビジネスルールを知らない)では苦戦する。また、複雑なタイムゾーン処理やカスタムカテゴリカル順序を含むエッジケースでは、誤ったpandasコードを生成することもある。

実用的な解決策:PandasAIを第一段階のレイヤーとして扱うことだ。生成されたコードをパワーユーザーに公開し、誤解釈を発見・修正できるようにする。100%の精度が必要な定期レポートの場合は、PandasAIが動作する初稿を生成した後、pandasのロジックを手動で固定する。

自然言語で生成して、人間がレビューして検証する——このハイブリッドなワークフローこそ、本当の生産性向上が得られると実感した部分だ。アナリストを置き換えるのではなく、彼らのスピードを落とす繰り返しの構文作業を取り除くのだ。

Share: