23. 数据分析:用Python进行均衡价格的数据拟合与可视化
各位同学,今天咱们来点硬核的。前面讲了那么多理论,什么供需曲线、均衡点、价格弹性……但说实话,光看公式和图表,总觉得隔着一层纱。我个人习惯是,必须亲手跑一遍数据,心里才踏实。
这一章,我们就用Python把均衡价格这件事,从理论变成可操作的代码。你想想看,当你能用几行代码就拟合出一条需求曲线,再画出供给曲线,最后精准找到那个交点——那种掌控感,是纯理论给不了的。
为什么非得用Python?
我刚开始做市场分析那会儿,还在用Excel手动拉曲线。数据量小还行,一旦遇到几千条交易记录,Excel直接卡死。后来我转向Python,才发现这才是干活的工具。
Python的好处有三点:
- 处理数据快——pandas库几秒钟搞定上万条数据
- 拟合模型灵活——scipy库里的curve_fit函数,想拟合什么曲线都行
- 可视化直观——matplotlib画出来的图,直接能拿去给老板汇报
核心思路:我们用真实的市场交易数据(或者模拟数据),通过回归分析找到需求函数和供给函数,然后解方程组求出均衡价格和均衡数量。
第一步:准备数据
在实际项目中,数据往往是从数据库或者API接口拉下来的。这里为了演示,我先生成一组模拟数据。嗯,注意看,这里有个小技巧——我故意给数据加了点噪声,因为真实市场数据从来不会完美地落在一条直线上。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# 设置随机种子,保证结果可复现
np.random.seed(42)
# 生成价格数据(从5到25)
price = np.linspace(5, 25, 100)
# 需求函数:Qd = 100 - 3*P + 噪声
# 供给函数:Qs = -20 + 4*P + 噪声
quantity_demanded = 100 - 3 * price + np.random.normal(0, 5, 100)
quantity_supplied = -20 + 4 * price + np.random.normal(0, 5, 100)
# 组装成DataFrame
df = pd.DataFrame({
'price': price,
'quantity_demanded': quantity_demanded,
'quantity_supplied': quantity_supplied
})
print(df.head())
个人经验:我在做某电商平台的定价分析时,发现真实数据里的噪声比这个大多了。有时候一个促销活动就能让需求曲线变形。所以,数据清洗这一步千万别省,异常值该删就删。
第二步:拟合需求曲线和供给曲线
数据准备好了,接下来就是拟合。这里我用的是线性函数,因为大多数基础经济学教材里都是这么假设的。但实际项目中,我遇到过指数型的需求曲线,也遇到过对数型的。你想想看,奢侈品和日用品的需求曲线能一样吗?
scipy的curve_fit函数非常强大,你只需要定义一个函数形式,它就能帮你算出最优参数。
# 定义线性函数
def linear_func(x, a, b):
return a * x + b
# 拟合需求曲线
params_demand, _ = curve_fit(linear_func, price, quantity_demanded)
a_d, b_d = params_demand
# 拟合供给曲线
params_supply, _ = curve_fit(linear_func, price, quantity_supplied)
a_s, b_s = params_supply
print(f"需求曲线: Qd = {a_d:.2f} * P + {b_d:.2f}")
print(f"供给曲线: Qs = {a_s:.2f} * P + {b_s:.2f}")
跑完这段代码,你会看到类似这样的输出:
需求曲线: Qd = -2.98 * P + 99.45
供给曲线: Qs = 4.02 * P + -19.87
你看,拟合出来的参数跟咱们设定的真实值(-3和4)非常接近。这就是统计的力量——虽然数据有噪声,但大数定律会帮我们把真相找出来。
第三步:求解均衡价格
有了两条曲线的方程,求均衡点就是解一个二元一次方程组。说白了,就是让Qd = Qs。
# 解方程:a_d * P + b_d = a_s * P + b_s
# 移项得:(a_d - a_s) * P = b_s - b_d
equilibrium_price = (b_s - b_d) / (a_d - a_s)
equilibrium_quantity = a_d * equilibrium_price + b_d
print(f"均衡价格: {equilibrium_price:.2f}")
print(f"均衡数量: {equilibrium_quantity:.2f}")
避坑指南:我曾经在做一个农产品市场分析时,发现拟合出来的供给曲线斜率是负的。当时我差点以为自己代码写错了。后来一查,原来是那段时间政府有价格补贴,导致供给行为扭曲。所以,拟合结果不符合经济学直觉时,先别急着改代码,去查查背后有没有政策干预。
第四步:可视化——一张图看懂一切
数据是冷冰冰的,但图表能讲故事。我个人习惯是,每次分析完数据,第一件事就是画图。因为老板不看代码,也不看数字,他只看图。
# 生成用于绘图的平滑价格序列
price_smooth = np.linspace(5, 25, 200)
qd_smooth = a_d * price_smooth + b_d
qs_smooth = a_s * price_smooth + b_s
plt.figure(figsize=(10, 6))
# 绘制原始数据点
plt.scatter(df['quantity_demanded'], df['price'],
alpha=0.5, label='需求数据', color='#FF6B6B')
plt.scatter(df['quantity_supplied'], df['price'],
alpha=0.5, label='供给数据', color='#4ECDC4')
# 绘制拟合曲线
plt.plot(qd_smooth, price_smooth, 'r-', linewidth=2, label='需求曲线')
plt.plot(qs_smooth, price_smooth, 'b-', linewidth=2, label='供给曲线')
# 标记均衡点
plt.scatter(equilibrium_quantity, equilibrium_price,
color='gold', s=200, edgecolors='black',
zorder=5, label='均衡点')
plt.xlabel('数量')
plt.ylabel('价格')
plt.title('市场均衡价格拟合与可视化')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
这张图一出来,所有东西都一目了然。两条曲线的交点,就是市场出清的价格和数量。任何偏离这个点的价格,都会导致过剩或短缺——市场会自动调节回去。
核心知识体系
为了让你更清楚地理解整个流程,我画了一张结构图。这张图把我们从数据到结论的路径完整展示了出来。
进阶技巧:处理非线性关系
刚才我们用的是线性拟合,但真实世界哪有那么多直线?我记得有一次分析某款电子产品的定价,发现需求曲线明显是幂函数形状——价格越低,需求量增长得越快。这时候再用线性拟合,误差就大了。
解决办法很简单,换一个函数形式就行:
# 定义幂函数
def power_func(x, a, b, c):
return a * (x ** b) + c
# 拟合
params_power, _ = curve_fit(power_func, price, quantity_demanded)
你想想看,同样的数据,用不同的函数去拟合,结果可能天差地别。所以,选择函数形式不是数学问题,而是经济学问题——你得先理解这个市场的运行逻辑,再决定用什么曲线去描述它。
实战中的注意事项
最后,我总结几条实战经验,希望能帮你少走弯路:
- 数据量别太少——少于30个样本点,拟合结果基本不可信。我一般要求至少100个。
- 注意异常值——一个极端值就能把整条曲线带偏。用箱线图先检查一遍数据。
- 别过度拟合——用高阶多项式拟合出来的曲线,虽然能完美穿过每个数据点,但预测能力几乎为零。
- 验证结果——拟合出来的均衡价格,最好跟实际市场价格对比一下。如果差太多,说明你的模型可能漏掉了重要变量。
一句话总结:Python帮我们算出了均衡点,但真正理解市场为什么在那个点均衡,靠的还是经济学直觉。工具是手段,不是目的。
好了,这一章的内容就到这里。代码你可以直接拿去跑,数据也可以换成你自己的。记住,多动手,少空想——市场不会骗人,但数据会,前提是你得会用工具把它洗干净。