第 7 章 · 01 Smart Farmers 导论与凸优化建模


文档摘要

第 7 章 · 01 Smart Farmers 导论与凸优化建模 本节摘要:本节是 Smart Farmers 项目的开篇——quant-trading 全书学术性最强的一章。我们先拆解 README 那种"几乎可直接改写成 working paper"的论文式结构(Assumption / Theoretical Framework / Data Specification / Empirical Result / Discussion / Further Reading),再把整个项目的核心思想翻译成一句话:把马来西亚农民的种植决策建模成一个凸优化(二次规划)问题。农民被假设为追求利润最大化的 Homo Economicus,在轮作、多年生作物寿命、可耕地约束下做决策。

第 7 章 · 01 Smart Farmers 导论与凸优化建模

本节摘要:本节是 Smart Farmers 项目的开篇——quant-trading 全书学术性最强的一章。我们先拆解 README 那种"几乎可直接改写成 working paper"的论文式结构(Assumption / Theoretical Framework / Data Specification / Empirical Result / Discussion / Further Reading),再把整个项目的核心思想翻译成一句话:把马来西亚农民的种植决策建模成一个凸优化(二次规划)问题。农民被假设为追求利润最大化的 Homo Economicus,在轮作、多年生作物寿命、可耕地约束下做决策。最关键的一步是定价机制——价格不是外生给定的,而是由供需缺口内生决定(Alfred Marshall 均衡的线性近似),这使目标函数对产量天然呈现二次型,完美匹配 CVXOPT 的 QP 接口。本节还会把农民作物配置与 Markowitz 投资组合做类比,并导读 7 篇文献(含 Marshall 1890 与 Ricardo 1817 两本百年经典)。

涉及源码:原项目 Smart Farmers project/README.md(约 43KB,论文式结构),Smart Farmers project/forecast.py(约 618 行,目标函数与 QP 求解的最终落点)。

⚠️ 注意:本节是全章"概念地基"——目标函数为什么是二次型、约束怎么拼成块矩阵、为什么需要工具变量和合成控制法,这些"为什么"全在这里讲清。如果不吃透本节,后面三节的代码精读会变成无源之水。建议先通读 README 原文再读本节。

学习目标

阅读完本节,你应当能够:

  1. 复述 README 的六段论文式结构,并说清每一段对应量化研究的哪一环。
  2. 用一句话讲清"Smart Farmers 的核心思想是凸优化建模"。
  3. 推导出目标函数为何对产量呈二次型(关键是价格内生 P=P_eq+α(D−S)+ε)。
  4. 列出四类约束(政府干预 / 轮作 / 多年生寿命 / 可耕地)各自的数学形式。
  5. 解释 Markowitz 投资组合类比(多样化 vs 集中)为何适用于作物配置。
  6. 对 7 篇文献(Marshall / Ricardo / Abadie / Angrist / Komarek / Louhichi×2)各讲一句 takeaway。

金融/数学原理

一个不寻常的量化研究对象:农民

读到第 7 章,我们已经看过外汇突破、动量均线、统计套利、期权波动率、石油货币。这一章的对象最"反直觉"——农民。README 开篇就用一段近乎布道的话点题:

🍊 🍍 🍈 🌽 and 🍠 are something we have been taking for granted. Up until COVID-19, we finally come to senses that farmers are one of the low-paid essential workers. This project is dedicated to the optimal allocation of agricultural resources.

作者的赌注是:如果我们能近似模拟一群理性农民的种植决策,就能在农产品期货(棕榈油、橡胶、可可)上取得先手。注意这个推理链——农民决定产量,产量决定供需缺口,供需缺口决定价格,价格决定期货方向。整条链条的源头是"农民怎么种地"。这和第 6 章石油货币的"油价→汇率"是同一种 quantamental 思路:从基本面因果链上游找信号。

论文式 README:六段结构

Smart Farmers 的 README 不像代码文档,更像一篇 working paper 的提纲。它按以下顺序展开:

段落 论文对应 这一段在做什么
Intro 引言 点题:为何建模农民决策,与农产品交易的关系
Assumption 模型假设 6 条简化假设(EMH / 无极端天气 / 无需求突变 / 无农技升级 / 无套利 / 无物流瓶颈)
Theoretical Framework 理论框架 目标函数 + 4 类约束 + 定价机制 + 矩阵形式
Data Specification 数据说明 FAO 14GB 数据、马来西亚 30 类作物、合成控制法补缺失价格、mapping.csv 寿命表
Empirical Result 实证结果 6 种作物(甘蓝 / 可可 / 椰子 / 芒果 / 橡胶 / 油棕)的回测图
Discussion 讨论 前向测试失败、Ricardian 推广、COVID W 型复苏
Further Reading 参考文献 7 篇文献(两本百年经典 + 5 篇论文)

这套结构几乎可以直接改写成一篇 10 页的 working paper。这是 quant-trading 全书唯一一个把研究流程"论文化"的项目——其他章节更偏交易笔记。

核心假设:Homo Economicus 与 Pareto Optimal

整个模型的地基是 Efficient Market Hypothesis(EMH)。README 原话:

The core of this project is Efficient Market Hypothesis. As faulty as it sounds, there is only one way to be rational (call it Pareto Optimal as you may) but one thousand ways to be irrational.

翻译成操作语言:我们把一国所有农民聚合成一个"大农民工会",假设他们是追求利润最大化的理性人。这样,原本无数个体七嘴八舌的决策,就被压缩成了"一个理性人在约束下求最大利润"的标准优化问题。这是典型的"代表性主体"建模 trick——宏观经济学里到处都是,只是这里挪到了农业。

目标函数:利润 = (价格 − 成本) × 产量

农民的目标函数直白得不能再直白:

Maximize Σ [ ( P_i − C_i ) × Q_i ] 作物 i

其中 P_i 是作物 i 的价格,C_i 是单位成本,Q_i 是产量(决策变量)。乍看这是关于 Q_i 的线性函数,似乎不值得动用凸优化。但作者随即抛出关键转折:价格 P_i 不是外生常数,而是由供需缺口内生决定

定价机制:价格内生(关键转折)

作者借 Alfred Marshall 1890 年《Principles of Economics》的供需均衡图,给出价格的线性近似:

P_i = P_eq,i + α_i × ( D_i − S_i ) + ε_i
符号 含义
P_eq,i 作物 i 的均衡价格(去年的价格做近似)
α_i 定价系数(把"吨"的供需差换算成"美元/吨"的价格压力)
D_i 国内需求(由人口 + 人均 GDP 决定,下两节详谈)
S_i 国内供给 = 产量 Q_i
ε_i 随机扰动(force majeure,如天气、疫情)

图: 定价机制

这里供给 S_i = Q_i 恰好就是目标函数里的决策变量。把定价机制代入目标函数:

利润_i = ( P_eq,i + α_i × (D_i − Q_i) − C_i ) × Q_i = (P_eq,i + α_i·D_i − C_i)·Q_i − α_i·Q_i²

看到了吗?目标函数里冒出了 −α_i·Q_i² 这一项——一个关于产量的二次型。把所有作物加起来,目标函数就是一个标准的凹的二次型(因为 α_i > 0),最大化它等价于最小化一个凸的二次型。这就是为什么整个项目天然适合二次规划(QP)。

💡 核心心法:这是全书最优雅的一步数学操作——"价格内生"是 QP 形式的源头。如果价格是外生常数,目标函数就是线性的,解会退化到边界(全种一种利润最高的作物);正因为价格随供给上升而下降,农民才被迫分散种植,目标函数才呈现"中间隆起"的凹性,QP 才有非平凡的内部解。下一节会用 Markowitz 投资组合做类比,你会看到这和"不要把鸡蛋放一个篮子"是同一种数学。

四类约束

目标函数搞定后,约束决定可行域的形状。README 列了 4 类约束,我们逐一翻译。

约束① 政府干预(不等式,下界):某些战略作物(粮食)有强制最低产量(防止饥荒),某些有补贴。落到数学上就是 Q_i ≥ Q_min,i,转换成 QP 标准形式是 −Q_i ≤ −Q_min,i(CVXOPT 要求 ≤)。

约束② 一年生作物轮作(不等式,上下界):同一块地连续种同一种作物会退化(病虫害累积)。轮作的数学表达是"今年种作物 i 的面积 ≤ 去年总可耕地 − 去年种作物 i 的面积"。同时引入惯性系数 ψ(默认 0.8):农民不会一年内换掉超过 20% 的种植面积,所以下界是 ψ × 去年面积。代码里 upperbound=1.2lowerbound=−0.8(用 −1 实现 ≥)就是这两个数。

约束③ 多年生作物寿命(不等式,上下界):橡胶树、油棕、椰子、可可这些多年生作物,寿命动辄几十年,不可能一年全砍掉重种。设寿命为 L,经济生命周期系数 ω(农学家朋友建议 0.7),则:

下界: 每年只有 1/(ωL) 比例的树到寿,只能砍这么多 上界: 最多新增 (ωL+1)/(ωL) 比例(受生长缓慢限制)

cleanse data.py 里那行 perennial = ... apply(lambda x: (x*eco_coeff − 1)/(x*eco_coeff)) 就是在算这个下界。

约束④ 可耕地总量(等式):所有作物占用的地加起来必须等于总可耕地面积(假设封闭系统自给自足)。每吨作物所需面积 = 1/单产(产量逆),所以等式约束是:

Σ ( Q_i × yield_i_inverse ) = 总可耕地

forecast.py 里 equality_coeff=cvxopt.matrix(D[currentyear]['yield_i']).T 这行就是这个等式的系数。

Markowitz 投资组合类比

文献导读里有 Louhichi 2010 的 FSSIM 论文,作者明确指出"its objective function is similar to Markowitz portfolio optimization"。这个类比非常贴切:

Markowitz Smart Farmers
资产权重 w_i 作物种植份额(产量 / 面积)
资产预期收益 μ_i 作物单位利润 P_i − C_i
协方差矩阵 Σ 价格对供给的敏感度 α_i(把"风险"换成"供给冲击")
目标:最大化收益 − λ×风险 目标:最大化利润(价格内生带二次惩罚)
约束:Σw = 1, w ≥ 0 约束:ΣQ = 总地, Q ≥ Q_min

两者都是凹的二次目标 + 线性约束 = 凸 QP。差别在 Markowitz 的"二次项"来自收益方差(风险厌恶),Smart Farmers 的"二次项"来自价格对供给的负反馈。直觉上:Markowitz 说"不要把鸡蛋放一个篮子,因为篮子之间相关性不为 1";Smart Farmers 说"不要只种一种作物,因为种得越多价格被砸得越狠"。同一种数学,两种语义。

7 篇文献导读

README 的 Further Reading 列了 7 篇,两本百年经典 + 五篇现代论文:

  1. Marshall A (1890) Principles of Economics——供需均衡模型的鼻祖。Book 5 Ch 3 是"市场均衡"概念的起源地,本节的定价机制图就来自这里。
  2. Ricardo D (1817) On the Principles of Political Economy and Taxation——Ricardian 比较优势模型。Ch 7 讲比较优势,是 Discussion 里"多国推广版"的理论依据。
  3. Abadie & Gardeazabal (2003)——合成控制法的奠基作(巴斯克恐怖主义对经济的影响)。下一节用它来补缺失价格。
  4. Angrist & Krueger (2001)——工具变量综述。下下节用人口 + GDP 作工具变量(2SLS)。
  5. Komarek et al. (2017)——马拉维小农户化肥价格弹性的生物经济模型。
  6. Louhichi et al. (2010) FSSIM——欧盟农场生物经济模型,目标函数类似 Markowitz 投资组合优化
  7. Louhichi & Gomez y Paloma (2013) FSSIM-Dev——FSSIM 推广到发展中国家,多年生作物的 NPV 约束受这篇启发。

两本百年经典(Marshall / Ricardo)告诉我们:农业经济学的数学骨架,200 年前就立好了

算法与代码精读

本节聚焦"建模",代码细节留给后三节。这里只点出 forecast.py 里把上述理论翻译成 CVXOPT 标准形式的两个关键函数,先建立"理论 → 矩阵"的映射直觉。

get_production:把理论翻译成 P/q/G/h/A/b

forecast.py 同时定义了两个 get_production(线性版 + 二次版,后者覆盖前者)。二次版(实际使用)是整个项目的"理论落点":

#forecast.py:93-150(节选) def get_production(initial_guess): price_hist = np.mat(D[currentyear-1]['price']).T # P_eq 近似 alpha = np.diag(D[currentyear]['alpha']) # 定价系数对角阵 production_hist = np.mat(D[currentyear-1]['production']).T # 去年产量 delta_pop = ... # Δ人口 beta = np.mat(D[currentyear]['beta']).T # 人口系数 delta_gdp = ... # ΔGDP gamma = np.mat(D[currentyear]['gamma']).T # GDP 系数 # 线性项(目标函数里的 q) linear_coeff = (-price_hist + (alpha*production_hist*-1) - delta_pop*beta - delta_gdp*gamma + np.mat(initial_guess).T) # 二次项(目标函数里的 P,正是 α 对角阵!) quadratic_coeff = cvxopt.matrix(alpha) ...

这里最值得盯着看的一行是 quadratic_coeff = cvxopt.matrix(alpha)——目标函数的二次项矩阵恰好就是定价系数 α 的对角阵。这直接印证了前文的推导:价格内生 P=P_eq+α(D−Q) 代入利润后,二次项系数就是 α。整本 quant-trading 里,理论与代码的对应关系没有比这更紧的了。

三处转换(CVXOPT 的脾气)

CVXOPT 的 QP 标准形式是 min (1/2)xᵀPx + qᵀx s.t. Gx≤h, Ax=b。Smart Farmers 模型需要做三处转换才能塞进去:

  1. 最大化 → 最小化负目标:利润最大化等价于最小化 −利润。CVXOPT 只接受 min,所以符号整体取反。
  2. ≥ 不等式 → ≤:轮作下界 Q_i ≥ ψ·去年面积 转成 −Q_i ≤ −ψ·去年面积。forecast.py 里 lowerblock=np.diag(...apply(lambda x:-1*x)) 就是用 −1 翻号。
  3. 多段约束 → 块矩阵拼接:轮作上界、轮作下界要拼成一个 G 矩阵:inequality_coeff=cvxopt.matrix(np.append(upperblock,lowerblock,axis=0))。这是 CVXOPT 要求"单一不等式约束"的副作用。

这三步转换在 forecast.py 的 130-143 行密集出现,是本项目的工程核心之一,第 04 节会逐行精读。

🎯 反直觉发现:整个项目"为什么必须用 QP"这件事,完全源自一个看似无害的假设——价格由供需内生决定。如果作者像大多数农产品模型那样把价格当外生常数,目标函数就是线性的,最优解永远是"全部种利润率最高的那一种作物",模型退化成平凡边界解。正是"种多了价格会跌"这一条负反馈,把线性目标掰弯成了凹的二次型,迫使农民分散种植,这才有了非平凡的最优解、有了 Markowitz 类比、有了整章 Smart Farmers。一行公式 P = P_eq + α(D−S) + ε,撑起了全章 618 行代码。

关键技巧

  1. 先写 README 再写代码:这个项目的 README 是论文骨架,代码是填肉。读这种项目要倒着读——先吃透 README 的 Theoretical Framework,代码细节自然浮现。
  2. 代表性主体假设:把"成千上万农民"压缩成"一个理性大农民",是简化建模的标准 trick。代价是丢失了异质性(README 的"No premium for heterogenous crop quality"假设就是在补这个洞)。
  3. 价格内生 → 二次型:这是全书最具教学价值的一步数学推导。记住套路——只要目标函数里某项的系数本身是决策变量的线性函数,目标就会自动变成二次型
  4. 约束分类法:政府(下界)、生物(上下界)、资源(等式)。这三类几乎覆盖了所有农业优化问题的约束形态。
  5. Markowitz 类比的边界:类比只在"目标函数二次 + 线性约束"这一层成立;Markowitz 的"二次"是风险厌恶,Smart Farmers 的"二次"是价格负反馈,经济含义完全不同,只是数学同构。

本节要点

  1. Smart Farmers 是 quant-trading 学术性最强的一章,README 按论文六段结构(Assumption / Framework / Data / Result / Discussion / Reading)组织,几乎可直接改写 working paper。
  2. 核心思想一句话:把农民决策建模为凸优化(QP),农民是追求利润最大化的 Homo Economicus
  3. 目标函数利润 = Σ(P−C)·Q 看似线性,但价格内生 P=P_eq+α(D−Q)+ε 代入后产生 −α·Q² 二次项,目标自动变成凹二次型,天然适合 QP。
  4. 四类约束:政府干预(下界)、轮作(上下界,惯性系数 ψ=0.8)、多年生寿命(ω=0.7,L=作物寿命)、可耕地总量(等式)。
  5. Markowitz 投资组合类比:作物配置 = 资产权重,价格负反馈 = 风险厌恶,数学同构但经济含义不同。
  6. 7 篇文献含两本百年经典(Marshall 1890 供需均衡 / Ricardo 1817 比较优势)+ Abadie(合成控制)+ Angrist(工具变量)+ Louhichi(FSSIM,Markowitz 类比)。

下一节,我们进入 Data Specification——看 cleanse data.py 怎么从 FAO 14GB 数据里捞出马来西亚 30 类作物,以及怎么用合成控制法(Abadie 2003)给姜、生菜、玉米等缺失价格作物"造"出价格。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U