1. はじめに(リンゴとミカンの話はやめませんか?)
「リンゴ2個とミカン3個を消費したときの効用は…」
経済学部で最初に効用関数を習うとき、大体こういう例から入ります。そしてその次に待っているのが、無差別曲線と予算制約線を手描きし、ラグランジュ未定乗数法で最適消費点を求めるという、あの試験です。
正直、ずっと苦手でした。数学自体が苦手というより、私は左利きで多汗症持ちなので、紙の上に図を描いたり数式を手で書き殴ったりする行為そのものが苦痛だったんです。インクは滲むし、消しゴムをかければ紙は湿るし、時間内に綺麗な無差別曲線を描き切る余裕なんてありませんでした。ペーパー試験全般が本当に苦手でした。
もし学生時代に、数式変形とグラフ描画を正確にやってくれるコードがあったら——そんな昔からの原体験が、今回のライブラリ開発のきっかけです。統計学をゴリゴリ使った計量経済学向けのライブラリは世の中にいくつもあるようですが、今回作ったのはそういう方向性ではなく、もっと基礎的なミクロ経済学の「計算と可視化」に振り切ったものです。
2. 作ったもの:microecon
microecon は、ミクロ経済学の基礎理論(今回の v0.1.0 ではコブ=ダグラス型効用関数のみ)を、型安全かつ直感的に計算・可視化できることを目指した Python ライブラリです。
- コブ=ダグラス型効用関数 $U(x,y)=x^\alpha y^\beta$ のもとでの効用最大化問題を、閉形式解(Closed-form solution)で確実に解く
- 最適消費量 $x^, y^$、最適効用 $U^$、ラグランジュ乗数(影の価格)$λ^$、限界代替率 $MRS を一括で算出
- ラグランジアンの立式から一階条件の導出までのプロセスを、KaTeX/Markdown形式の途中式として自動生成
- 予算制約線・無差別曲線・最適点をMatplotlibでPNG画像として出力
リポジトリはこちらです。
https://github.com/HiHiroyoshi/microecon
まだ v0.1.0 で、対応しているのはコブ=ダグラス型のみです。CES型や準線形型、レオンチェフ型などは今後の拡張予定として抽象基底クラス(BaseUtilityFunction)だけ用意してあります。
3. インストールと簡単な使い方
インストール(PyPI未公開のため、リポジトリを直接指定するかクローンして利用してください)。
pip install git+[https://github.com/HiHiroyoshi/microecon.git](https://github.com/HiHiroyoshi/microecon.git)
# もしくはgit clone [https://github.com/HiHiroyoshi/microecon.git](https://github.com/HiHiroyoshi/microecon.git)
# cd microecon
# poetry install
最小限のサンプルコードはこんな感じです。
from microecon.consumer.models import CobbDouglasUtility, BudgetConstraint
from microecon.consumer.solver import ConsumerProblem
from microecon.consumer.plotter import save_plot
# 効用関数と予算制約を定義
utility = CobbDouglasUtility(alpha=0.5, beta=0.5)
budget = BudgetConstraint(price_x=2, price_y=4, income=100)
# 効用最大化問題を解く
problem = ConsumerProblem(utility, budget)
result = problem.solve()
print(result.optimal_x) # 25.0
print(result.optimal_y) # 12.5
print(result.optimal_utility) # 17.67766...
print(result.mrs) # 0.5 (= price_x / price_y)
# 途中式(KaTeX/Markdown)を確認
print(result.markdown_steps)
# グラフをPNGとして保存
save_plot(result, budget, "optimal.png")
markdown_steps には、ラグランジアン $L(x, y, \lambda) = U(x, y) + \lambda(M - P_x x - P_y y)$ の立式から一階条件 $\frac{\partial L}{\partial x} = 0$ 等を経て解に至るまでの過程がKaTeX記法で格納されているので、そのままQiitaやNotionに貼り付ければ授業ノートっぽい解説が出来上がります。optimal.png には予算線・無差別曲線・最適点が描かれた図が出力されます。
4. 開発プロセス:AI同士を戦わせる「プロンプト熟成法」
今回一番書きたかったのはここです。自分はプログラミングの知識が浅く、正直Claude Codeにいきなり「ミクロ経済学のライブラリを作って」と投げても、そこそこのものは出てきても細部の詰めは甘くなると思っていました。そこで、コードを書く前にプロンプト自体をAI同士でひたすら磨く、というプロセスを踏みました。
ステップ1[Gemini]
プロンプトのたたき台を作成。要件・ディレクトリ構成・各ファイルの仕様をひとまず言語化してもらいました。
ステップ2[Claude Desktop]
「100点満点中何点か、厳しいレビューアーとして採点してください」という指示で、Claude自身にプロンプトを添削させ続けました。最初のC#/.NET版のたたき台は72点からスタートし、Python版に切り替えてからも80点台を行き来しながら、最終的に90点台後半まで持っていきました。このラリーの中で、実際に見つかった不具合はこんなものです。
-
数式自体の間違い
ラグランジュ乗数 λ の閉形式解の数式そのものが間違っていた($\frac{\alpha U^}{(\alpha+\beta)I}$ ではなく正しくは $\frac{(\alpha+\beta)U^}{I}$) -
変数・シンボルの衝突
SymPyの虚数単位Iと、所得を表すつもりだった変数名Iがサイレントに衝突するバグの芽(所得のシンボル名をMに変更して回避) -
フレームワーク仕様による不具合
Pydantic v2の@field_validatorはカスタム例外をそのまま外に伝播させずpydantic.ValidationErrorにラップしてしまう問題 $\rightarrow$@dataclass(frozen=True)+__post_init__のガード節方式に設計変更 -
ライセンスリスクの発見
テストフレームワークのライセンスリスク(FluentAssertions v8以降が商用有償化されている等)を発見し、無償版・代替ライブラリへの切り替えを指示
自分自身のプログラミング知識だけでは気づけなかった部分(特にライブラリのライセンス変更や、言語・フレームワーク特有の「あるある」な落とし穴)は、自分でもドキュメントを確認しながら、プロンプトをベタ書きで修正していきました。AI同士のやり取りに全部委ねるのではなく、自分の目でも一つずつ潰していった、というのが実態に近いです。
ステップ3[Claude Code]
90点を超えた完成版プロンプトをClaude Codeに一発投入。ディレクトリ構成からコードの実装、テストの実行まで通しでお願いし、pytest が全件パスするところまで確認して完成としました。
5. おわりに & フィードバックのお願い
「リンゴとミカンの図」を卒業して、コードで完結するミクロ経済学の教材ツールを目指しています。v0.1.0はコブ=ダグラス型のみの対応ですが、今後はCES型や準線形型、レオンチェフ型、さらには生産者理論やゲーム理論あたりまで広げていきたいと思っています。
経済学のバックグラウンドがある方で、「学部レベルのあの図・あの式変形がコード化・可視化されたら嬉しい」というテーマがあれば、ぜひコメントで教えてください。エッジワースボックス、独占の死荷重、IS-LM分析あたりは個人的に候補として気になっています。