📑

LangGraph × scikit-learnで作る『状態を持つMLエージェント』入門

に公開

こんにちは、リーディング・エッジ社でAIエンジニアをしている和泉です。
今回は LangGraph を使って、データの読み込みからモデル選択・学習・評価・最終出力までを エージェント(ノード)として繋いだMLパイプライン を作るサンプルプログラムをご紹介したいと思います。
機械学習は分かるけど、LangGraphは初めて…という方に向けた解説です。

🗂 リポジトリ & 前提

  • リポジトリ: ml_and_langgraph
  • 技術スタック: LangGraph / LangChain / scikit-learn
  • 目的: 状態(State)を持つMLワークフローを、LangGraphのノードでつなぐ
.
├── data/iris.csv
├── src/
│   ├── analysis/analysis_data_loader.py
│   ├── analysis/ml_analysis.py
│   ├── main.py
│   └── models/*.py
└── requirements.txt

セットアップ:

pip install -r requirements.txt
# OpenAI APIキーを環境変数で設定

🌐 全体像(何が起きる?)

  1. プロンプト中のファイルパス(例: data/iris.csv)を抽出
  2. LLMツール呼び出しでCSV読込→train/test分割→AnalysisData生成
  3. LLMが使うべきモデル名を1つ選択
  4. scikit-learnモデルで学習/評価(回帰=MSE、分類=Accuracy)
  5. 最終結果文字列を生成して出力

ノード遷移図


🛠 グラフ設計(src/main.py

LangGraphでは、ノードエッジでワークフローを定義します。

workflow = StateGraph(AnalysisState)
workflow.add_node("load_data", self._load_data)
workflow.add_node("execute_ml_analysis", self._execute_ml_analysis)
workflow.add_node("check_sufficient", self._check_sufficient)
workflow.add_node("generate_final_result", self._generate_final_result)
workflow.set_entry_point("load_data")
workflow.add_edge("load_data", "execute_ml_analysis")
workflow.add_edge("execute_ml_analysis", "check_sufficient")
workflow.add_edge("check_sufficient", "generate_final_result")
workflow.add_edge("generate_final_result", END)

状態(AnalysisState)で、analysis_dataanalysis_resultis_sufficientfinal_resultを持ち回ります。


📥 データロード(src/analysis/analysis_data_loader.py

LLMツール呼び出しでCSV読込

@tool
def load_data(file_path: str) -> pd.DataFrame:
    if file_path.endswith(".csv"):
        return pd.read_csv(file_path)
    raise ValueError("Unsupported file type")

LLMにツールをバインドして、「プロンプトからパス抽出→ツールで読込」を促します。

読込後はtrain/test分割+メタ情報AnalysisDataに格納します。

X_train, X_test, y_train, y_test = train_test_split(
    df.drop(columns=["target"]), df["target"], test_size=0.2, random_state=42
)
training_data = pd.concat([X_train, y_train], axis=1)
test_data = pd.concat([X_test, y_test], axis=1)
AnalysisData(... features=X_train.columns.tolist(), target_column="target")

🤖 モデル選択と学習/評価(src/analysis/ml_analysis.py

LLMでモデル選択

prompt_template = ChatPromptTemplate.from_messages([
  ("system", "…(選択肢: 線形回帰/ロジスティック回帰/決定木/…)結果のみを出力"),
  ("user", "プロンプト: {prompt}")
])
result = (prompt_template | self.llm | StrOutputParser()).invoke({...})

scikit-learnで実行

if result == "線形回帰":
    model = LinearRegression()
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    mse = mean_squared_error(y_test, y_pred)
    return AnalysisResult(model=model, mse=mse)

他の分類モデル(ロジスティック回帰、決定木、ランダムフォレスト、SVM、GBDT)も同様に分岐実装されています。


📦 データモデル(src/models/*.py

  • AnalysisState: プロンプト、analysis_dataanalysis_resultis_sufficientfinal_result
  • AnalysisData: 訓練/テストDataFrame、特徴量リスト、目的変数名
  • AnalysisResult: モデル本体とMSEまたはAccuracy

▶ 実行と出力例

python -m src.main

出力例:

モデル: RandomForestClassifier(...)
Accuracy: 0.93

🚀 拡張ポイント

  • 画像解析や統計分析への応用
  • 解析結果のレポート作成
  • 機械学習を行う際の前処理やハイパーパラメータチューニングの追加
  • DBとの連携
  • RAG連携でデータソース自動選択

✅ まとめ

今回、LangGraphを用いて、機械学習のモデル構築をAIエージェントで自動で行うサンプルプログラムを作成しました。
今後は、画像解析や統計分析、解析結果のレポート作成など様々な応用が可能かと思いますので、ご興味がある方は、参考にして頂けると幸いです。

Discussion