读《反脆弱》,塔勒布最反直觉的一句话是:有些东西不仅不怕波动,反而靠波动活着。风会吹灭蜡烛,却能让火越烧越旺——蜡烛是脆弱的,火是反脆弱的。
大多数人读完当鸡汤。我不一样——既然讲的是「波动和收益的关系」,那这个关系到底长什么样,我直接上 Python 跑 10 万次。下面四个实验,把书里最硬的四个概念变成能跑的代码。
实验一:凸性 = 反脆弱的本质
书里最核心的数学其实就一个字:凸。系统对扰动的反应如果是「凹」的(越波动越亏),就是脆弱;如果是「凸」的(越波动越赚),就是反脆弱。我把三种反应写成函数,跑一遍:
def 收益(x): return {"脆弱(凹)": -x*x, "强韧(线性)": x, "反脆弱(凸)": x*x} print("=== 实验一:同一扰动下,三种系统的反应 ===") for 扰动 in (-2, -1, 0, 1, 2): r = 收益(扰动) print(f"扰动 x={扰动:>3} -> 脆弱:{r['脆弱(凹)']:>5} 强韧:{r['强韧(线性)']:>3} 反脆弱:{r['反脆弱(凸)']:>5}") import random N = 100_000 期望 = {"脆弱(凹)": 0.0, "强韧(线性)": 0.0, "反脆弱(凸)": 0.0} for _ in range(N): x = random.gauss(0, 1) for k, v in 收益(x).items(): 期望[k] += v for k in 期望: 期望[k] /= N print("\n随机扰动下的期望收益(波动白送的午餐):") for k, v in 期望.items(): print(f" {k}: {v:+.3f}")
跑出来:
扰动 x= -2 -> 脆弱: -4 强韧: -2 反脆弱: 4 扰动 x= -1 -> 脆弱: -1 强韧: -1 反脆弱: 1 扰动 x= 0 -> 脆弱: 0 强韧: 0 反脆弱: 0 扰动 x= 1 -> 脆弱: -1 强韧: 1 反脆弱: 1 扰动 x= 2 -> 脆弱: -4 强韧: 2 反脆弱: 4 随机扰动下的期望收益(波动白送的午餐): 脆弱(凹): -1.005 强韧(线性): +0.002 反脆弱(凸): +1.005
关键在最后那行期望值:在均值 0 的随机扰动下,脆弱系统期望亏 1.0,反脆弱系统期望赚 1.0。波动对脆弱是毒药,对反脆弱是免费午餐。这就是 Jensen 不等式——凸函数的期望大于期望的凸函数。一句话:反脆弱不是「抗打击」,是「靠打击变强」。
实验二:杠铃策略
书里给反脆弱者的实操建议是「杠铃策略」:一头极安全(保命),一头极冒险(吃尾部红利),中间的全不要。为什么不要中间?因为中间那种「看起来稳、其实会腰斩」的资产最危险。我用 2 万条随机路径模拟 20 年:
def 模拟组合(年数, 路径数=20000): 杠铃, 集中 = [], [] for _ in range(路径数): b, m = 1.0, 1.0 for _ in range(年数): 安全 = 1.03 if random.random() < 0.12: # 12% 年份踩中幂律大肉 风险 = random.paretovariate(1.4) * 0.7 else: 风险 = 1.0 + random.gauss(0.04, 0.03) b *= 0.9 * 安全 + 0.1 * 风险 if random.random() < 0.05: # 5% 年份遭遇腰斩 m *= 0.5 else: m *= 1.15 杠铃.append(b); 集中.append(m) return 杠铃, 集中 def 分位(xs, q): return sorted(xs)[int(len(xs) * q)] 杠铃, 集中 = 模拟组合(20) print(f"杠铃策略 均值:{sum(杠铃)/len(杠铃):8.2f}x 最差:{min(杠铃):6.2f}x 5%分位:{分位(杠铃,0.05):6.2f}x") print(f"集中押注 均值:{sum(集中)/len(集中):8.2f}x 最差:{min(集中):6.2f}x 5%分位:{分位(集中,0.05):6.2f}x")
跑出来:
杠铃策略 均值: 2.59x 最差: 1.58x 5%分位: 1.76x 集中押注 均值: 9.21x 最差: 0.11x 5%分位: 1.35x
有意思的是:集中押注的平均收益(9.21 倍)比杠铃(2.59 倍)高。但看最差情况——集中押注最差只剩 0.11 倍,接近归零;杠铃最差还有 1.58 倍,永远死不了。再看 5% 分位(最惨的 5% 年份),杠铃 1.76 倍也高于集中的 1.35 倍。
杠铃牺牲的是平均收益,买回来的是「永远在场」。而投资里最重要的事,不是某年赚多少,是你别在最低点被迫离场。能穿越危机的底盘,比漂亮的平均数値钱得多。
实验三:肥尾下,大数定律会失效
书里另一句警告:我们活在「肥尾世界」,却用「高斯世界」的脑子做决策。高斯分布(钟形)里极端事件几乎不可能;幂律分布(肥尾)里,极端事件是常态。我用同一套样本量,对比两种分布下均值是否收敛:
def 样本均值(分布, n): return sum(分布() for _ in range(n)) / n 高斯 = lambda: random.gauss(0, 1) 幂律 = lambda: random.paretovariate(1.16) - (1.16 / (1.16 - 1)) for n in (100, 1000, 10000, 100000): print(f"样本量 {n:>7} 高斯均值:{样本均值(高斯, n):+.3f} 幂律均值:{样本均值(幂律, n):+.3f}")
跑出来:
样本量 100 高斯均值:+0.050 幂律均值:-3.590 样本量 1000 高斯均值:-0.020 幂律均值:-3.448 样本量 10000 高斯均值:+0.002 幂律均值:-1.918 样本量 100000 高斯均值:+0.003 幂律均值:-1.397
高斯分布的均值随着样本增大稳稳收敛到 0;幂律分布的均值从 -3.59 跳到 -1.40,死活不肯安定。这意味着:在肥尾世界里,你收集再多历史数据,也算不准「平均风险」——因为下一次极端事件,就能把前面所有统计掀翻。这就是「过去十年没崩过」不代表「明天安全」的数学原因。
实验四:反脆弱式「期权」收益结构
反脆弱系统在收益结构上长这样:小亏常有,大赚罕见,但大赚那一下足以覆盖所有小亏。像一张免费期权——downside 有限,upside 无限。我模拟一下这种结构随试错次数增加的变化:
def 期权式(次数): 资产, 胜场 = 1.0, 0 for _ in range(次数): if random.random() < 0.08: # 8% 概率大赚 资产 *= 1.6; 胜场 += 1 else: 资产 *= 0.99 # 其余小亏 1% return 资产, 胜场 def 人类可读(x): return f"{x:.2e}x" if x >= 1e6 else f"{x:.2f}x" for t in (12, 120, 1200): 资产, 胜场 = 期权式(t) print(f"运行 {t:>5} 次 胜率 {胜场/t*100:4.1f}% 资产变为 {人类可读(资产)}")
跑出来:
运行 12 次 胜率 0.0% 资产变为 0.89x 运行 120 次 胜率 5.8% 资产变为 8.62x 运行 1200 次 胜率 7.1% 资产变为 3.04e+12x
12 次时你可能运气差到一单没中(0.89 倍);但跑 1200 次,资产翻了 3e12 倍。重点是:波动越频繁、试错越多,反脆弱系统越赚。脆弱系统相反——波动越多死得越快。
对程序员来说,这就是「多写小项目、敢发半成品」的数学依据:每个项目是一张廉价期权,成了就吃尾部,不成亏的只是点时间。你亏得起,但市场给的惊喜你接得住。
写在最后
把《反脆弱》跑成代码,结论很硬:
- 凸性:反脆弱不是抗打击,是靠波动变强,凸函数即正义;
- 杠铃:放弃中间档的假稳定,用「极安全+极冒险」换永远在场;
- 肥尾:历史统计在极端世界里会失灵,别被「从未崩过」骗了;
- 期权:小亏常、大赚罕,但试错越多越赚——这本事程序员天生有。
设计一个对自己有利的概率结构,然后让时间替你打工。
代码和概率,是咱们这行最被低估的两件武器。
需要完整可跑的四实验源码?后台回复「反脆弱」自取。
欢迎打赏!!!