Andrej Karpathy's AutoResearchに触発されて、Claude Codeが表形式の2値分類タスク(チャーン、コンバージョンなど)における自律的なMLリサーチャーとして振る舞うシステムを構築しました。
データセットを渡します。すると永遠に回り続けます。データを分析し、仮説を立て、コードを編集し、実験を実行し、時間窓を拡張しながら(過去で学習し、未来を予測する――リークなし)評価します。そして、gitで保持するか元に戻します。編集するのは3つのファイルだけ――特徴量エンジニアリング、モデルのハイパーパラメータ、分析コードです。それ以外はすべてロックされています。
追記:いくつかのコメントに基づいて明確化すると、私はこれを使って、モデルに追加する新しいシグナルを見つける問題を解くために取り組んでおり、限られたデータセットに対して過剰適合(オーバーフィット)しようとしているわけではありません。-end 追記-
主要な設計上の決定:
- 実験ループに加えて分析ループを導入し、より良い振り返りと実験を可能にしています。
- 実験のスループットを最大化するために、さまざまな判断をしています:デフォルトモデルとしてLightGBMを使用し、特徴量数と木の数を制限し、学習実行が完了するまでトレーニングをロックします。
- 編集可能範囲を制約:編集できるのは3ファイル+ログのみ。インフラ変更なし、パッケージのインストールなし。これをしないと、エージェントは最終的に評価コードを変更して「スコアを良くする」ことを試みます。
- Dockerサンドボックス――エージェントはフルのシェルアクセスを使って実行します(--dangerously-skip-permissions)。コンテナによって閉じ込められています。
- k-foldに対して時間窓を拡張――複数の時系列のtrain/test分割におけるスコアの平均。
- 強制ログ出力――すべての実験にLOG.mdエントリを作成します(仮説、結果、要点)。重要な洞察はLEARNING.mdに書き込みます。事後にエージェントの推論を読むことができます。
- 組み込み済みの分析プリミティブ――単変量AUC、相関ペア、ヌル率、特徴量重要度、誤り分析。エージェントはこれらを使って分析コードを書き、時間を節約します。また、最初のいくつかの分析に対する初期の提案としても機能します。
これを作って学んだこと:
- 本当の改善に不可欠なのは、きっちりした評価です――この教訓は2度刺さりました:
- 初期版では、エージェントが編集できるファイルを制約していませんでした。その結果、最終的に自分にとって「改善しやすい」ように評価コードを変更してしまいました。
- 当初はk-fold検証を用いていましたが、エージェントが見つけた改善は実際にはデータリークであり、アウトオブタイム(時系列の外側)では成立しませんでした。つらい手動の検査の末、時間窓を拡張する方式に切り替えました。
- 実験のスループットを守るためにできることは全部やる――これも2度刺さりました:
- 最初はモデルに好きに走らせていたのですが、夜通しで20回程度しか実験できない状況ではあまり感心しませんでした。実際には、エージェントが何千もの新しい特徴量を作り出して学習を遅くし、さらにRAM制限のためにいくつかの実行をクラッシュさせていました。そこで学習時間が妥当になるように、特徴量数の上限と木の数の上限を追加しました。
- それでも、エージェントは多数の実験を同時にバックグラウンドプロセスとして投入することで、依然として学習をクラッシュさせたり遅くしたりできてしまいました。-> 2つの実験が同時に走らないようにするためのロック機構を実装しました。これ以降、1日あたり何百回もの実験に進む速度が上がりました。
- 永続的なメモリは重要:強制ログ出力がないと、エージェントはすでに試した実験を繰り返してしまいます。LOG.mdとLEARNING.mdの仕組みにより、イテレーションをまたいでメモリが維持されます。
コードはオープンソース(サニタイズ版): https://github.com/trantrikien239/autoresearch-tabularもちろんClaude Codeを使って作っていますが、手動での編集を含む複数ラウンドのイテレーションを経て大きく改善されているので、共有する価値があると思い投稿しました。
[link] [comments]




