<< 返回本书主页<< Back to the afterword page
Jan. 2022
6 网络效应6.1 背景问题均衡求解市场动力学:达成均衡的动态过程6.2 计算实践:网络效应下的价格策略比较6.2.1 作业描述与算法思路6.2.2 编程实现与要点说明定价函数市场模拟6.2.3 结果与分析固定价格策略贪心策略规模价格策略耐心策略和固定高价策略均衡情况下的最佳定价策略
经济学中最经典的讨论中,市场没有网络效应。也就是说,每个人评估一个物品的价值不受他人影响。每个人只需要根据价格和自己的估值决定是否购买。但无网络效应的假设不是普遍适用的。对于某些产品,例如传真机、微信,如果使用的人不多,一个人会觉得这个产品没什么价值;随着参与人增多,其他人也纷纷被其价值吸引而参与。这就是“网络效应”。对于有网络效应的产品,产品推广、扩大用户规模具有特殊意义。
为了进一步分析有网络效应的市场,我们定义如下三个变量:
为了分析用户的购买行为,我们定义如下两个函数:
那么,
在这个市场里,均衡在何处达成?
为了简化分析,设
考虑
当
假设人们用上一轮的实际规模更新自己的预期,新一轮的预期规模则为
当预期规模
时,市场的供需情况不会再发生变化,此时达成均衡。设
联立
这一方程的解就是市场均衡。如下图所示,它一般存在两个解,不稳定均衡点
在这一分析过程中,我们看到,预期规模超过
现在我们更详细地考虑达成均衡的过程,在此过程中,人们根据市场情况调整预期,实际规模又随之变化,循环往复。
达成均衡的过程中,市场处在不均衡状态。在等式
此外,
根据上一节的假设,同时不妨假设人们以月为单位来观察市场并做出预测,人们对于下月市场规模的预期等于上月的实际规模
那么,市场规模的动态变化就如下图所示。
(由于人们根据上月实际规模调整预期,我们得到上月实际规模以后平行于
上图的例子中,市场的动态发展趋向
那么,什么样的定价行为能最大化卖家利润呢?我们发现,当定价足够低,不稳定均衡点可能不复存在。
这种情况下,消费者的行为将推动市场自动成长,直到高端稳定均衡点。这种定价策略打开了一个市场自动成长的通道!
在背景问题中,我们看到,对于有网络效应的产品,不同定价策略会影响市场的动态变化、影响商家的利润。本次作业,我们就是要模拟不同定价策略的效果。
考虑你开发了一个具有网络效应的信息服务产品,有如下特点
试模拟这个市场运行
我的算法思路如下:
在老师提示的三种策略中,贪心策略的算法相对复杂。
首先,我们根据市场保留价函数
我们要最大化当月利润(设为第
来表示,再代入
这一函数求导,我们可以得到当
除此以外,我提出了两个新的策略。
一个策略是固定高价策略,即每个月的定价固定在
另一个策略是耐心策略,作为对贪心策略的改良。贪心策略目光短浅,仅仅致力于最大化当月利润,却可能因此减小市场规模,导致长期利润大幅减少。为了避免追求最大利润时提价太多,我在确定当月价格时,计算该价格
首先,次月(第
由于
其中,
贪心策略的过幅提价在这一策略中不会发生,因为过幅提价会导致次月利润大幅减小。
此外,我还把初始阶段的价格设为
xxxxxxxxxx
21def stable_price(p0, z1, z2, rnd):
2 return 0.5
p0
、上月规模z2
、上上月规模z1
,按照题目要求、根据两个月之间规模的变化调整价格。xxxxxxxxxx
91def scaled_price(p0, z1, z2, rnd):
2 if z1 == None:
3 return 0.5
4 elif z1 < z2:
5 return 1.2 * p0
6 elif z1 > z2:
7 return 0.8 * p0
8 else:
9 return p0
z2
,返回一个能够最大化当月利润的价格。根据上文的分析,这一价格应为0.1 + (1 + z2 * z2) / 2
。xxxxxxxxxx
31def venal(p0, z1, z2, rnd):
2 k = 1 + 4 * z2 * z2
3 return 0.1 + k / 2
xxxxxxxxxx
11def patience(p0, z1, z2, rnd):
在市场发展初期,固定价格为
xxxxxxxxxx
41 if z1 == None:
2 return 0.9
3 elif z2 > z1 and p0 == 0.9:
4 return 0.9 # let the market grow
当市场规模达成稳定,亦即z2 == z1
时,我开始提价。
这一过程中,我用到了scipy
库的优化函数minimize_scalar
。假定价格p
保持两个月,我们可以计算出次月利润W
,它的表达式如上所示。调用minimize_scalar
,得到W
最大时的定价res.x
。
xxxxxxxxxx
61 elif z2 == z1 and p0 == 0.9:
2 ...
3 else:
4 W = lambda p: -1 * (p - 0.2) * (1 - p / (1 + 4 * (1 - p / (1 + 4 * z2 * z2))**2))
5 res = minimize_scalar(W, bounds = (0,5), method='bounded')
6 return res.x
除此以外,我还考虑了一个特殊情况:由于定价在res.x
和p0
的均值。
xxxxxxxxxx
51 elif z2 == z1 and p0 == 0.9:
2 W = lambda p: -1 * (p - 0.2) * (1 - p / (1 + 4 * (1 - p / (1 + 4 * z2 * z2))**2))
3 from scipy.optimize import minimize_scalar
4 res = minimize_scalar(W, bounds = (0,5), method='bounded')
5 return (res.x + p0) / 2
xxxxxxxxxx
21def stable_high_price(p0,z1,z2):
2 return 0.9
为了把策略名称和定价函数整合在同一个对象中,定义一个类PriceFunc
:
xxxxxxxxxx
71class PriceFunc(object):
2 def __init__(self, name, function, num):
3 self.name = name
4 self.function = function
5 self.num = num
6 def __str__(self):
7 return self.name
在定制类PriceFunc
下,定义五个实例,分别对应五个策略。
xxxxxxxxxx
51funcList = [stable, scaled, venal, patient, stable_high]
2titles = ['stable pricing','scaled pricing','venal pricing', 'patient pricing', 'stable high']
3
4for i in range(len(funcList)):
5 priceFunc = PriceFunc(titles[i], funcList[i], i+1)
定义一个函数profit_monthly
,模拟市场每个月的动态变化,便于在采取不同策略时重复调用。
xxxxxxxxxx
11def profit_monthly(priceFunc):
根据定价函数返回的每个月的定价p
和上个月的规模z2
,计算每月实际规模z
,从而计算每月利润profit_mon
和截止当月的累积利润profit_sum
。
xxxxxxxxxx
211 profit_sum = 0
2 n = 0
3 p = None
4 z1 = None
5 z2 = 0
6 z_list = []
7 p_list = []
8 profit_mon_list = []
9 profit_sum_list = []
10 while True:
11 n += 1
12 p = priceFunc.function(p, z1, z2, n) # price of this month
13 p_list.append(p)
14 z = 1 - p / (1 + 4 * z2 * z2) # scale of this month
15 z_list.append(z)
16 profit_mon = (p - 0.2) * z
17 profit_mon_list.append(profit_mon)
18 profit_sum += profit_mon
19 profit_sum_list.append(profit_sum)
20 z1 = z2 # scale of the month before the last month
21 z2 = z # scale of the last month
把当前定价策略下对市场的模拟输出到结果文件output.csv
和控制台中。
xxxxxxxxxx
71 if n % 10 == 0: # output the profit so far
2 f.write('%.3f,' % profit_sum)
3 print('%.3f' % profit_sum, end = '\t')
4 if n == 100:
5 break
6 f.write('\n')
7 print()
根据数据结果,调用matplotlib库画图,展示每月利润和累积利润逐月变化的趋势(ax1
和ax2
),以及规模和定价的变化(ax3
和ax4
)。
xxxxxxxxxx
331 fig, (ax1,ax3) = plt.subplots(1,2)
2 fig.suptitle(priceFunc.name)
3 ax1.set_title('profit')
4 ax3.set_title('scale')
5 # the graph of how monthly profit and profit sum change over time
6 color1 = 'tab:red'
7 color2 = 'tab:blue'
8 xPoints = np.array(list(range(1,101)))
9 yPoints = np.array(profit_mon_list)
10 ax1.plot(xPoints, yPoints, color=color1)
11 ax1.set_xlabel('month')
12 ax1.set_ylabel('profit mon', color=color1)
13 ax1.tick_params(axis='y', labelcolor=color1)
14 ax2 = ax1.twinx()
15 ax2.set_ylabel('profit sum', color=color2)
16 yPoints2 = np.array(profit_sum_list)
17 ax2.plot(xPoints, yPoints2, color=color2)
18 ax2.tick_params(axis='y', labelcolor=color2)
19 # the graph of how the scale of the market and the price change over time
20 yPoints3 = np.array(z_list)
21 ax3.plot(xPoints, yPoints3, color=color1)
22 ax3.set_xlabel('month')
23 ax3.set_ylabel('scale', color=color1)
24 ax3.tick_params(axis='y', labelcolor=color1)
25 ax4 = ax3.twinx()
26 ax4.set_ylabel('price', color=color2)
27 yPoints4 = np.array(p_list)
28 ax4.plot(xPoints, yPoints4, color=color2)
29 ax4.tick_params(axis='y', labelcolor=color2)
30 # fig.tight_layout()
31 fig.set_size_inches(6,3)
32 fig.tight_layout()
33 fig.savefig('output%i_%s.png' % (priceFunc.num, priceFunc.name), dpi=300)
在逐策略调用profit_monthly
之前,先在结果文件output.csv
和控制台中输出表头。
xxxxxxxxxx
81f = open('output.csv', 'w', encoding = 'utf-8-sig')
2f.write('模拟进行月数,')
3print('模拟进行月数', end = '\t')
4for i in range(10,101,10):
5 f.write('%i,' % i)
6 print('%i' % i, end = '\t')
7f.write('\n')
8print()
逐策略调用profit_monthly
函数,模拟每一定价策略下的市场变化,并输出到结果文件output.csv
和控制台中。
xxxxxxxxxx
71for i in range(len(funcList)):
2 priceFunc = PriceFunc(titles[i], funcList[i], i+1)
3 f.write('%s,' % titles[i])
4 print('%s' % titles[i], end = '\t')
5 profit_monthly(priceFunc)
6
7f.close()
控制台的输出结果如下:
xxxxxxxxxx
61>>> 模拟进行月数 10 20 30 40 50 60 70 80 90 100
2>>> stable pricing 2.469 5.101 7.733 10.366 12.998 15.630 18.263 20.895 23.527 26.160
3>>> scaled pricing 3.810 7.312 9.984 11.901 13.160 13.858 14.083 13.914 13.417 12.650
4>>> venal pricing 3.294 6.822 10.350 13.878 17.406 20.934 24.463 27.991 31.519 35.047
5>>> patient pricing 1.590 5.737 10.562 15.394 20.226 25.058 29.890 34.722 39.517 44.125
6>>> stable high 1.590 5.737 10.562 15.394 20.226 25.058 29.890 34.722 39.554 44.387
规模价格策略的表现最为糟糕。在市场规模扩大时,价格提高
耐心策略的逻辑如6.2.1 作业描述与算法思路所述。耐心策略的总利润比固定价格
班上一位同学的定价策略最为成功。如果我们只考虑最终会把市场引向均衡的定价策略,那么存在一个最佳定价策略。他在数学上做出了证明。
根据均衡求解部分的等式
均衡情况下,每月利润最大,总利润就最大。每月利润
那么,第一轮的时候,我们只需要设置
此时,
最后一轮,我们可以再调用贪心策略。不用顾忌未来的用户规模了,就可以最后再捞一把。
具体的代码如下
xxxxxxxxxx
71def best(p0, z1, z2, rnd):
2 if rnd == 1:
3 return 0.325
4 elif rnd == 100:
5 return venal(p0, z1, z2, rnd)
6 else:
7 return 0.918
输出结果为
xxxxxxxxxx
31>>> 模拟进行月数 10 20 30 40 50 60 70 80 90 100
2>>> ...
3>>> best pricing 4.443 9.285 14.127 18.968 23.810 28.652 33.494 38.336 43.178 48.144
这一策略的总利润确实是最大的。