关于产品如何定价的模型探讨

引言

昨天跟人聊到这个问题,但是从经验上说,定价似乎需要考虑很多,但也好像不需要考虑一样。定价格有一些已有的规律,比如产品独领风骚然后按毛利去定的、红海市场跟随友商打价格的、为了扩张亏本卖的等等。经验这种东西会很有效,但它也是阻止破圈的罪魁祸首。所以这篇文章尝试建立一个代理人模型从尽可能多的角度去探索,毕竟这是一个系统性的问题,我们不讲经验,一两条经验不足以适配所有问题,干了40年的老板也不一定解决新场景遇到的问题,要不然百年老店不是又比现在多了一些。

当然,我仍然会建立一个合适的动态模型来模拟尽可能多的情况,如果是沙盘推演也没有问题,只是可能局限性比较大,不能把一些极端的变量组合考虑进去。设计的时候尽量遵循ODD原则(overview, design, detail),以保证覆盖现实情况的同时模拟出更多意外。

这里我们抛开单个产品差异化定价策略,即可以把产品拆成很细的定价策略,比如一块盘按照不同iops和容量租出去最大化利益,只讨论一块固有iops和容量的情况,因为这种拆分算利益的话,更适合用最优解公式而不是建模分析,况且现在差异化定价你会别人也会,最后难免都是同质竞争。

设计

以我熟悉的云计算为例,首先我们尽可能多的列出agent,最明显的就是产品、客户、厂商、供应商,但是这还不够,有些过度抽象了。(我们暂且忽略渠道,主要是因为渠道与云厂商体量在实际情况中基本保持一致,所以这点确实可以忽略)

那接下来我们加入更多agent,产品嘛单纯一些只有一类,客户这一类金融行业客户、游戏行业客户、制造行业客户,厂商的话主要考虑外部竞争和内部团队(云计算部门的集团投入政策、销售体系等),即会有几个体量、质量、策略等不同的厂商agent,厂商除了考虑同类供应商,也要考虑它的上下游,比如代工厂、圆晶厂、渠道商这些(方便实现简化保留下游,仅为防止泰国又洪水产品生命周期有影响)。

梗概

至此,我们已经在这个世界里已经可以描述一个完整的故事了,某个客户(可控数量)向某个云厂商(可控数量)购买最多N个产品(有生命周期),客户会根据自己的偏好选择厂商,厂商提供的产品受限于供应商(价格极低),如果客户技术能力强或者价格敏感度高可能会直接向供应商下单(供应商参与竞争,适用于OEM产品),最后我们的输出是某个厂商在未来一段时间内的市场表现变化,包括收益和客户占有率。

属性与动作

客户

列出尽可能多的agent以后,我们开始构建每个agent的属性和行为。由于我不想写那么多一个个解释,所以列几个意思一下,以金融客户为例(属性值和动作来源于市场销售记录统计,无法确定的值没关系,模拟的时候机器可以范围内随机探索)。

产品价格敏感性:低(0.2)
产品质量要求:中(0.5)
服务质量要求:高(0.8)
客户直销忠诚度:中(0.0-1)
客户渠道销售忠诚度:中(0.0-1)
IT技术能力:中(0.5)
受他人影响程度:高(0.7)

然后是动作,这些动作暂且适用于所有客户agent。

- 客户的属性随着时间的增长保持不变
- 客户会根据自己的属性偏好选择厂商产品,各个属性加权值决定产品,比如质量要求高的会喜欢产品综合质量好一些的、渠道忠诚度高的会喜欢渠道多的、IT技术能力低的会喜欢厂商服务好的
- 客户的购买行为除了在与云厂商直接,也可以发生在与供应商之间
- 客户的某属性超过一定阈值的时候(比如忠诚度),虽然所有属性加权值不是最佳,但会导致其这次仍然选择上一家
- 客户的忠诚度会随着历年选择厂商的变化而变化

产品

列出产品的属性,这里可以先定义这么几个。

产品价格:可控变量,即客户每天使用需要付出的价格
产品状态:在厂、待售、使用、结束(这里假设每个产品从售出便不会再次回到产品池)
产品用户:产品用户 已经销售:是否已经销售到客户 产品成本:与供应链相关 产品质量:随时间、客户增加而增加,有一个逐步完善的过程 产品销售厂商:产品销售厂商
产品生产厂商:产品生产厂商 生命周期:产品从售出开始则开始消耗

厂商

然后是厂商的属性。

销售策略:盈利、求同、激进
产品最大数量:对应厂商体量
产品成本:与供应商有关

供应商

最后就是供应商的属性,为了减少复杂度,这里我们只有两类供应商,即可直接面向客户以及不可直接面向客户。

销售策略:盈利(供应商不赚就是亏)
产品供应周期:每天能够生产的产品数量
产品生产成本:可变量
可直销:是、否

再加一些全局变量进去,比如从Gartner的趋势报告里把云计算、各类产品的每年增长也算进去,主要操控的变量是某个或多个厂商的定价范围(0-100)。

周期事件

TBD 一个周期内,会发生哪些事件呢?

产品:
客户:
厂商:
供应商:

模拟

预期

在开始之前,我们根据经验应该是对这个世界有一些经验预期的,包括:

一定范围内,定价不能直接决定市场占有率;
产品做的晚的厂商即使定价再低也只能抢得一定份额的市场;
供应商供货不足时,体量大的厂商更能抗住黑天鹅事件从而保证客户产品交付,从而获得更高的客户忠诚度;
动态选择灵活的定价(销售)策略即使起步晚,也可以抢夺一部分可观的市场;
价格敏感、技术能力强、忠诚度低的客户更容易从供应商处买;
集团策略影响云厂商定价策略选择;
在没被针对的情况下,小厂商初期可以打价格战争夺部分客户后,不会赚甚至是亏,但获取一定客户后再改变价格策略是可以盈利的;
因为不同阶段采取不同的定价策略会影响市场表现,那么作为云厂商在期间的前端销售和供应商谈判策略也不尽相同,比如产品初期的时候很难从供应商要低价,平价甚至亏本抢占市场后可以再向供应商谈判出更低成本价;

行为空间模拟

最后我们来看看模拟的动态情况。

tbd model simulation

tbd 由结果我们先看到几种现象。。。

tbd 然后我们把自己的实际情况带入进去。。。

tbd

tbd 看的多了,再结合dikw模型,结论就是直觉可能就是对的。但是要给人展示数字,我们可以从各种渠道快速填充数字,从数字到推论,只是让人觉得你可信,至于你自己信或不信,就是另外一码事儿了。。。最后我们要把数字与经验结合起来,就是出几个概率数字,即未来几年内我们应该采取怎样的定价策略(保持毛利、争夺市场、自动动态调整)然后有百分之多少的概率占去多少这个产品的市场获得多少利益,根据概率做选择,虽然无法确信,但也不会犯错,平平淡淡才是真。

TensorFlow in NetLogo, Make Your Agent More Intelligent

0. Background

NetLogo is a very useful tools for ABM, and Python is also a handful language for building proof of concept.

In this post I will show you how to call python language in NetLogo. For more information please follow here.

1. NetLogo version

breed [data-points data-point]
breed [centroids centroid]

globals [
  any-centroids-moved?
]

to setup
  clear-all
  set-default-shape data-points "circle"
  set-default-shape centroids "x"
  generate-clusters
  reset-centroids
end

to generate-clusters
  let cluster-std-dev 20 - num-clusters
  let cluster-size num-data-points / num-clusters
  repeat num-clusters [
    let center-x random-xcor / 1.5
    let center-y random-ycor / 1.5
    create-data-points cluster-size [
      setxy center-x center-y
      set heading random 360
      fd abs random-normal 0 (cluster-std-dev / 2) ;; Divide by two because abs doubles the width
    ]
  ]
end

to reset-centroids
  set any-centroids-moved? true
  ask data-points [ set color grey ]

  let colors base-colors
  ask centroids [die]
  create-centroids num-centroids [
    move-to one-of data-points
    set size 5
    set color last colors + 1
    set colors butlast colors
  ]
  clear-all-plots
  reset-ticks
end

to go
  if not any-centroids-moved? [stop]
  set any-centroids-moved? false
  assign-clusters
  update-clusters
  tick
end

to assign-clusters
  ask data-points [set color [color] of closest-centroid - 2]
end

to update-clusters
  let movement-threshold 0.1
  ask centroids [
    let my-points data-points with [ shade-of? color [ color ] of myself ]
    if any? my-points [
      let new-xcor mean [ xcor ] of my-points
      let new-ycor mean [ ycor ] of my-points
      if distancexy new-xcor new-ycor > movement-threshold [
        set any-centroids-moved? true
      ]
      setxy new-xcor new-ycor
    ]
  ]
  update-plots
end

to-report closest-centroid
  report min-one-of centroids [ distance myself ]
end

to-report square-deviation
  report sum [ (distance myself) ^ 2 ] of data-points with [ closest-centroid = myself ]
end


; Copyright 2014 Uri Wilensky.
; See Info tab for full copyright and license.

 

2. TensorFlow version

TensorFlow version: 1.14

import numpy as np
import tensorflow as tf

num_points = 100
dimensions = 2
points = np.random.uniform(0, 1000, [num_points, dimensions])

def input_fn():
  return tf.compat.v1.train.limit_epochs(
      tf.convert_to_tensor(points, dtype=tf.float32), num_epochs=1)

num_clusters = 5
kmeans = tf.contrib.factorization.KMeansClustering(
    num_clusters=num_clusters, use_mini_batch=False)

# train
num_iterations = 10
previous_centers = None
for _ in xrange(num_iterations):
  kmeans.train(input_fn)
  cluster_centers = kmeans.cluster_centers()
  if previous_centers is not None:
    print 'delta:', cluster_centers - previous_centers
  previous_centers = cluster_centers
  print 'score:', kmeans.score(input_fn)
print 'cluster centers:', cluster_centers

# map the input points to their clusters
cluster_indices = list(kmeans.predict_cluster_index(input_fn))
for i, point in enumerate(points):
  cluster_index = cluster_indices[i]
  center = cluster_centers[cluster_index]
  print 'point:', point, 'is in cluster', cluster_index, 'centered at', center

 

3. NetLogo with Python Extension version

Here’s the snapshot.

And here’s the code.

extensions [ py ]

breed [data-points data-point]
breed [centroids centroid]

data-points-own [
  cluster-id
]

centroids-own [
  cluster-id
  centx
  centy
]

globals [
  testoutput
  centroid-list
]

to setup
  clear-all
  py:setup py:python
  (py:run
    "import tensorflow as tf"
    "import numpy as np"
  )
  set testoutput py:runresult "1"
  py:set "testoutput" testoutput
  set-default-shape data-points "circle"
  set-default-shape centroids "x"
  generate-clusters
  ; For python
  py:set "num_points" num-clusters
  py:set "points" [list xcor ycor] of data-points
  py:set "num_clusters" num-clusters
  py:set "num_round" num-round
  if debug = True
  [
    py:run "print('Points Cordinates:', points)" ;for debug
  ]
  ;reset-centroids
end

to generate-clusters
  set testoutput py:runresult "testoutput + 1"
  let cluster-std-dev cluster-range
  let cluster-size num-data-points / num-clusters
  repeat num-clusters [
    let center-x random-xcor / 1.5
    let center-y random-ycor / 1.5
    create-data-points cluster-size [
      setxy center-x center-y
      set heading random 360
      fd abs random-normal 0 (cluster-std-dev / 2)
    ]
  ]
end

to train
  ; Cluster center
  (py:run
    "points = np.asarray(points)"
    "def input_fn():"
    "    return tf.compat.v1.train.limit_epochs(tf.convert_to_tensor(points, dtype=tf.float32), num_epochs=1)"
    "kmeans = tf.contrib.factorization.KMeansClustering(num_clusters=num_clusters, use_mini_batch=False)"
    "num_iterations = num_round"
    "previous_centers = None"
    "for _ in range(num_iterations):"
    "    kmeans.train(input_fn)"
    "    cluster_centers = kmeans.cluster_centers()"
    "    if previous_centers is not None:"
    "        print(('delta:', cluster_centers - previous_centers))"
    "    previous_centers = cluster_centers"
    "    print(('score:', kmeans.score(input_fn)))"
    "print(('cluster centers:', cluster_centers))"
    "# map the input points to their clusters"
    "cluster_indices = list(kmeans.predict_cluster_index(input_fn))"
    "print('cluster indices: ', cluster_indices)"
    "for i, point in enumerate(points):"
    "    cluster_index = cluster_indices[i]"
    "    center = cluster_centers[cluster_index]"
    "    print(('point:', point, 'is in cluster', cluster_index, 'centered at', center))"
  )
end

to show-shape
  set centroid-list py:runresult "cluster_centers"
  foreach centroid-list [
    x -> create-centroids 1 [
      set xcor ( item 0 x )
      set ycor ( item 1 x )
      set size 3
      set color white
    ]
  ]
end

 

Ref:

[1] https://www.altoros.com/blog/using-k-means-clustering-in-tensorflow/

[2] https://www.tensorflow.org/api_docs/python/tf/contrib/factorization/KMeansClustering

基于ARM(NVIDIA-JETSON-NANO)编译NetLogo

本文主要目的为测试这块板子的性能,看看其是否有作为边缘节点的能力。

Env

Ubuntu 18.04(jetson-nano-sd-r32.1-2019-03-18)

Prepare

$ sudo set -i 's/ports.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
$ sudo apt install -y curl x11vnc openjdk openjfx libopenjfx-jni libopenjfx-java

Build

$ git clone https://github.com/NetLogo/NetLogo
$ cd NetLogo
$ git submodule update --init
$ ./sbt netlogo/compile

Run and Package

$ ./sbt netlogo/run
$ ./sbt dist/buildNetLogo

Addon: Add VNC server to your board

$ sudo apt install -y x11nvc
$ x11vnc # to generate ~/.vnc files
$ echo 'x11vnc --loop &' >> ~/.xsessionrc

Ref

https://github.com/NetLogo/NetLogo/wiki/Building

https://github.com/NetLogo/NetLogo/wiki/Releasing

Agent based modeling Strategy in forex trading market

PREFACE

Since I’ve tested S1, S2, and S3 from the DATANOTE. However, it was not so good or in other words, identical with expectation. It’s time to make a change.

BASIC MODEL AND ARCHITECTURE

As you can see from my last articles, the architecture’s infrastructure is about to go and the agent’s protocol is well defined. Now what we should do is to combine them together.

In the first phase, the simulation will JUST be a Netlogo program. If the performance is just like S1-3, then it goes to phase 2 —- treating the agents as the real from the data gained and strategy trained from the real world. And if NOT, less probable, the program must be corrected.

PRACTICAL GUIDE

1. FAKE WORLD, FAKE AGENT

2. REAL WORLD, FAKE AGENT

3. REAL WORLD, REAL AGENT

World3 Model is a choice.(System Dynamics)

https://insightmaker.com/insight/1954/The-World3-Model-A-Detailed-World-Forecaster

基于外汇市场技术指标的ABM建模

本模型的最终模拟期望是随机,我想试试。

货币对作为agent,这样仅需要个位数以内;

货币对本身不拥有市场价值,初始值为此货币对相对于eurusd的比值;

agent拥有自己的技术指标,这个指标尽量在一定范围内震荡;

agent行动时,随之变化的指标会影响其他agent的行动;

patch横向分层,高中低区,agent的行动只在patch间行动;

tbd

ABM建模导读

本文算是一个读书笔记吧,就是最近刚买的那几本书,相较于之前Scott的几本,这几本学术意味比较浓。中间发现这些作者确实有比较有意思的观点和坚实的理论基础,在此记录以用来随时回忆。

1. Introduction to Agent Based Modeling

c0. & c1. 简介

反正ABM应用范围与可观察性相比EBM(基于公式,也就是我们常说的数学建模)更好,但EBM更容易系统集成。

c2. 入门

蚂蚁模型(也就是寻食模型)、网格自动机(复杂科学,在Wolfram之前就有人总结了相当一部分,另外它与有限状态机都属于自动机的一个特例)、英雄与懦夫模型(如果再加上人可以受他人感染的属性那就可以解释为什么某些人领袖特征还有人买账)、简单经济模型(只要人人都奉献,那么穷的越来越穷,富的越来越富,真不是正态分布,开源届或许也是如此^_^)

c3. 继续入门

四个特性:简单规则组成复杂现象,个体随机性导致一致行为,复杂模式可以“自组织”(飞鸟群、大雁群),不同模型反应世界的不同方面;森林大火模型(即渗透模型,可以用来测试系统的鲁棒性,能适用于很多领域,比如IT、经济、社会等);有限分形聚合模型(化学与自然物理模型);谢林模型(求同存异,人以群分啊);EL Farol模型(学习并预测去酒馆)

c4. 进入正题

开篇就遇到一个我十分认同并曾经也说过(哈哈)的话,来自物理学家费曼先生。

我不能理解我造不出来的东西。
OK进入正题,本章是将如何创建模型,有基于现象(模拟)和探索型(比如网格自动机)两种基本模型,但没有明显边界。然后接下来为了让我们快速上手ABM,作者一步步地使用NetLogo构建出了草-羊-狼模型,从而让你理解ABM建模的一般思路。建模运行以后,为了发现或验证规律,我们需要多次运行这个模型,为此NetLogo提供了行为空间(Behavior Space)方便我们多次运行并收集数据。本章末尾,作者提出了ABM与面向对象编程(OOP)异同点的思考,刚接触这个ABM的时候我就发现它俩很像,但以我短浅的经验来看,两者区别不太大,因为它俩的历史出处有非常惊人的相似或相同,要说有的话,ABM是一种思考方法,即一切从代理出发(agent),不必关心代理之间的复杂影响关系(说实话作者这个描述我是反对的,但作为一种思想而言细想又是对的,复杂的模型,复杂的关系,提纲挈领后也非常简单),而OOP。。OK我编不下去了。

c5. 哈哈,实践篇

这章终于讲了个正经模型,红绿灯模型。这不是重点,重点是为了节省汽油,作者引入了最佳速度,并且为控制这个最佳速度,使用了简单的比例控制,然后又说了一下机器学习的作用。敢情我大学几年都在学习机器学习啊。。本章结尾也较为系统地介绍了NetLogo的特性,比如3D、GIS等,其中这个GIS我在建模世界历史时应该会用到。总之本章非常精彩,至少我很满意。

后面6789章就不写出来了,速读了一下,暂时用不到,但很快就用到。

ABM-based Automatic System for OpenStack(VMWare/oVirt/maybe container…)

这篇文章可以写一篇论文。

注意,这里的controller不是指OpenStack的controller,而是整个平台过程控制的controller,也就是Automatic System。

好吧,这个问题不大,但也不小。好在我会建模会模拟,嘿哈。(这里不用EBM建模的原因是这个系统有些复杂,公式不足以直观发现问题,但为了提升一下本文的友好度,所以我会加几个公式^_^)

如果你不熟悉ABM建模可以参考我之前的文档,DataNote

那么首先我们要确认模型的目的,即是控制整个虚拟化(容器)在一定条件下的行为,这些条件有存储、网络、计算等资源,直观的条件简单来说就是用户需求(杂项比较多)。然后确定代理人(agent, turtles)、关系连接(link)、控制规则(rules)、代理人行为(actions)等。

在公交车上想出了一个模型,factory-server-client模型,可以的,然后我再收集点主流平台的规则就可以模拟了,非常容易唬人。

最近改为了网格-细菌-食物模型。

先来个粗犷的图吧。

图中,细菌代表虚拟机,食物代表负载,网格代表物理机,食物会一直生成,其速度可控,也就是可以控制负载的变化速度。比如,当负载变化加快时,即食物增长,虚拟机的平均负载会增高,甚至会增加新的虚拟机(也就是细菌繁殖),当然,物理机总数保持不变。

那么这个模型中我们可以得到什么信息,从而达到最高的性价比呢,即虚拟机的变化量最小?

1. 选择合适的繁殖参数(什么时候创建新虚拟机);

2. 可以尝试将细菌固定在一个或者一些网格中,即虚拟机的亲和性,可以观察影响;

3. 课以观察物理机宕机状态下的虚拟机承载与变化能力;

基于这个模型,我们可以搞个controller独立运行,会通过平台API获取资源的即时信息,然后再去做优化动作。

国家、行业、人物、现象与总结的历史知识降维方法

知识太多,如何归纳。

有行业历史、人物历史、世界(国家)历史,统统降维划到世界历史中,降级元素视作代理,尝试使用ABM建模。

降至平面图形中,形似“蝌蚪头(蝌蚪头(蝌蚪头拖着长长的尾巴)拖着长长的尾巴)拖着长长的尾巴”,蝌蚪头是领域,尾巴是历史,蝌蚪头可以是另一个蝌蚪头的拷贝,蝌蚪头的扩展可以向大可以向小。当遇到这些元素的交集再升维至球形,往中心聚拢。

笔者以国家为最外层蝌蚪头,假如发现外星文化,同样可以再加蝌蚪头将其吃掉。