> 用于决策分析的模拟
首先,从 “模拟(Simulate)” 标签页的 “选择类型(Select types)” 下拉菜单中选择模拟中使用的变量类型。可用类型包括二项分布(Binomial)、常数(Constant)、离散分布(Discrete)、对数正态分布(Log normal)、正态分布(Normal)、均匀分布(Uniform)、数据(Data)、网格搜索(Grid search)和序列(Sequence)。
### 二项分布(Binomial)
使用 “二项分布变量(Binomial variables)” 输入框添加二项分布随机变量。首先指定名称(`crash`)、试验次数(n)(例如 20)和成功概率(p)(0.01),然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`crash 20 .01`)。
### 常数(Constant)
在 “常数变量(Constant variables)” 输入框中列出分析中要包含的常数。你可以直接在文本区域输入名称和值(例如`cost 3`),或者分别在 “名称(Name)” 和 “值(Value)” 输入框中输入名称(`cost`)和值(5),然后点击图标。点击图标可删除条目。注意,只有(较大的)文本输入框中列出的变量才会包含在模拟中。
### 离散分布(Discrete)
使用 “离散分布变量(Discrete variables)” 输入框定义离散分布随机变量。首先指定名称(`price`)、取值(6 8)及其相关概率(.3 .7),然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`price 6 8 .3 .7`)。注意,概率之和必须为 1,否则会显示错误信息,模拟无法运行。
### 对数正态分布(Log Normal)
要在分析中包含对数正态分布随机变量,从 “选择类型(Select types)” 下拉菜单中选择 “对数正态分布(Log Normal)”,并使用 “对数正态分布变量(Log-normal variables)” 输入框。更多信息见下文 “正态分布(Normal)” 部分。
### 正态分布(Normal)
要在分析中包含正态分布随机变量,从 “选择类型(Select types)” 下拉菜单中选择 “正态分布(Normal)”,并使用 “正态分布变量(Normal variables)” 输入框。例如,输入名称(`demand`)、均值(Mean)(1000)和标准差(St.dev.)(100),然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`demand 1000 100`)。
### 泊松分布(Poisson)
泊松分布适用于模拟特定时间范围内事件发生的次数,例如晚上 10 点到 11 点急诊室的就诊人数。要在分析中包含泊松分布随机变量,从 “选择类型(Select types)” 下拉菜单中选择 “泊松分布(Poisson)”,并使用 “泊松分布变量(Poisson variables)” 输入框。例如,输入名称(`patients`)和事件发生次数的参数 “Lambda” 值(20),然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`patients 20`)。
### 均匀分布(Uniform)
要在分析中包含均匀分布随机变量,从 “选择类型(Select types)” 下拉菜单中选择 “均匀分布(Uniform)”,在 “均匀分布变量(Uniform variables)” 输入框中提供参数。例如,输入名称(`cost`)、最小值(Min)(10)和最大值(Max)(15),然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`cost 10 15`)。
### 数据(Data)
要在 “模拟公式(Simulation formulas)” 输入框指定的计算中包含来自其他数据集的变量,从 “计算输入数据(Input data for calculations)” 下拉菜单中选择数据集。这与 “网格搜索(Grid search)” 功能结合使用时,对投资组合优化非常有用。但与其他输入结合使用时,必须确保不同计算返回的值数量相同,否则会出现如下错误:
`Error: arguments imply differing number of rows: 999, 3000`
### 网格搜索(Grid search)
要包含值序列,从 “选择类型(Select types)” 下拉菜单中选择 “网格搜索(Grid search)”,在 “网格搜索(Grid search)” 输入框中提供最小值、最大值和步长。例如,输入名称(`price`)、最小值(Min)(4)、最大值(Max)(10)和步长(Step)(0.01)。如果在 “网格搜索(Grid search)” 中指定多个变量,模拟会生成并评估所有可能的取值组合。例如,假设在 “网格搜索(Grid search)” 文本输入框中定义第一个变量为`x 1 3 1`,第二个为`y 4 5 1`,则会生成以下数据:
| x |
y |
| 1 |
4 |
| 2 |
4 |
| 3 |
4 |
| 1 |
5 |
| 2 |
5 |
| 3 |
5 |
注意,如果选择了 “网格搜索(Grid search)”,生成的值数量将覆盖 “模拟次数(# sims)” 或 “重复次数(# reps)” 中指定的数量。如果不希望如此,请使用 “序列(Sequence)”。然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`price 4 10 0.01`)。
### 序列(Sequence)
要包含值序列,从 “选择类型(Select types)” 下拉菜单中选择 “序列(Sequence)”,在 “序列变量(Sequence variables)” 输入框中提供最小值和最大值。例如,输入名称(`trend`)、最小值(Min)(1)和最大值(Max)(1000)。注意,“步数” 由模拟次数决定。然后点击图标。或者,直接在文本输入区域输入(或删除)内容(例如`trend 1 1000`)。
### 公式(Formulas)
要使用生成的变量执行计算,在主面板的 “模拟公式(Simulation formulas)” 输入框中创建公式(例如`profit = demand * (price - cost)`)。公式用于向模拟添加(计算得到的)变量或更新现有变量。必须在`=`左侧指定新变量的名称。变量名称可包含字母、数字和`_`,但不能包含其他字符或空格。可以输入多个公式。例如,如果还想计算每次模拟的边际利润,在第一个公式后按回车,输入`margin = price - cost`。
“数据> 转换” 标签页中 “创建(Create)” 功能和 “数据 > 查看” 标签页中 “筛选数据(Filter data)” 功能使用的许多函数也可包含在公式中。可以使用`>`和`<`符号并组合它们。例如,`x > 3 & y == 2`在变量`x`的值大于 3**且**变量`y`的值等于 2 时,结果为`TRUE`。注意,在 R 和大多数其他编程语言中,`=`用于**赋值**,`==`用于判断变量值是否**恰好等于**某个值。相反,`!=`用于判断变量值**不等于**某个值。也可以使用包含**或(OR)** 条件的表达式。例如,要判断 “Salary” 小于 100,000 美元**或**大于 20,000 美元,使用`Salary > 20000 | Salary < 100000`。`|`是**或(OR)** 的符号,`&`是**且(AND)** 的符号(另见 “数据> 查看” 的帮助文件)。
下面展示几个公式示例:
- 创建新变量 z,为变量 x 和 y 的差值
```r
z = x - y
```
- 创建新的逻辑变量 z,当 x > y 时取值为 TRUE,否则为 FALSE
```r
z = x > y
```
- 创建新的逻辑变量 z,当 x 等于 y 时取值为 TRUE,否则为 FALSE
```r
z = x == y
```
- 上面的命令与下面使用`ifelse`的命令等效。注意与 Excel 中的`if`语句类似
```r
z = ifelse(x < y, TRUE, FALSE)
```
- `ifelse`语句也可用于创建更复杂的(数值)变量。在下面的示例中,如果 x 小于 60,z 取值为 0;如果 x 大于 100,z 取值为 1;最后,当 x 为 60、100 或介于 60 到 100 之间时,z 取值为 2。**注意:** 确保包含适当数量的左括号`(`和右括号`)`!
```r
z = ifelse(x < 60, 0, ifelse(x > 100, 1, 2))
```
- 创建新变量 z,为变量 x 的转换,且均值为 0:
```r
z = x - mean(x)
```
- 创建新变量 z,为 x 的绝对值:
```r
z = abs(x)
```
- 要找到使`profit`最大化的`price`值,使用`find_max`命令。在本示例中,`price`可以是随机变量或 “序列变量(Sequence variable)”。还有`find_min`命令。
```r
optimal_price = find_max(profit, price)
```
- 要确定多个变量(例如 x 和 y)中每对值的最小值(最大值),使用函数`pmin`和`pmax`。在下面的示例中,当 x 大于 y 时,z 取值为 x;否则,z 取值为 y。
```r
z = pmax(x, y)
```
示例见下表:
| x |
y |
pmax(x,y) |
| 1 |
0 |
1 |
| 2 |
3 |
3 |
| 3 |
8 |
8 |
| 4 |
2 |
4 |
| 5 |
10 |
10 |
- 与`pmin`和`pmax`类似,有一些函数可用于计算多个变量的汇总统计量。例如,`psum`计算不同向量元素的总和。更多信息见https://radiant-rstats.github.io/radiant.data/reference/pfun.html。
```r
z = psum(x, y)
```
示例见下表:
| x |
y |
psum(x,y) |
| 1 |
0 |
1 |
| 2 |
3 |
5 |
| 3 |
8 |
11 |
| 4 |
2 |
6 |
| 5 |
10 |
15 |
其他常用函数包括`ln`(自然对数,例如`ln(x)`)、`sqrt`(x 的平方根,例如`sqrt(x)`)和`square`(计算变量的平方,例如`square(x)`)。
要从计算中返回单个值,使用`min`、`max`、`mean`、`sd`等函数。
- 投资组合优化中一个有用的特殊函数是`sdw`。它接受权重和变量作为输入,返回变量加权和的标准差。例如,要计算三只股票(如波音、通用汽车和埃克森美孚)投资组合的标准差,可在 “模拟公式(Simulation formulas)” 输入框中使用以下方程。`f`和`g`可以是值(例如 0.2 和 0.8),或通过 “网格搜索(Grid search)” 输入框指定的不同权重向量(见上文)。`Boeing`、`GM`和`Exxon`是使用 “数据(Data)” 输入框(见上文)包含在模拟中的数据集中的变量名称。
```r
Pstdev = sdw(f, g, 1-f-g, Boeing, GM, Exxon)
```
关于如何使用模拟工具进行投资组合优化的示例,见可下载的状态文件此处。
### 函数(Functions)
可能 R 中可用的标准函数不足以灵活地进行你想要的模拟。如果是这种情况,点击屏幕左下角的 “添加函数(Add functions)” 复选框,在主面板的 “模拟函数(Simulation functions)” 输入框中创建自定义函数。要学习编写 R 函数,https://www.statmethods.net/management/userfunctions.html是一个很好的起点。
关于如何在赌博模拟中使用自定义 R 函数的示例,见可下载的状态文件此处。通过 “报告> Rmd” 生成的报告提供了关于模拟设置和函数使用的更多信息。
### 运行模拟
“模拟次数(# sims)” 输入框中显示的值决定模拟**抽取**的次数。要使用相同的随机生成值重新进行模拟,在 “设置随机种子(Set random seed)” 输入框中指定一个数字(例如 1234)。
要保存模拟数据供进一步分析,在 “模拟数据(Simulated data)” 输入框中指定名称。然后,可在任何 “数据” 标签页(例如 “数据 > 查看”、“数据 > 可视化” 或 “数据 > 探索”)的 “数据集(Datasets)” 下拉菜单中选择指定名称的数据集,以研究模拟数据。
指定所有必要输入后,点击 “模拟(Simulate)” 按钮运行模拟。
在下方截图中,`var_cost`和`fixed_cost`被指定为常数。`E`服从均值为 0、标准差为 100 的正态分布。`price`是离散随机变量,取值为 6 美元(概率 30%)或 8 美元(概率 70%)。“模拟公式(Simulation formulas)” 文本输入框中有三个公式。第一个公式确定 “需求(demand)” 对模拟变量 “价格(price)” 的依赖关系;第二个公式指定利润函数;最后一个公式用于确定利润低于 100 的案例数量(和比例),结果赋值给新变量`profit_small`。

在 “模拟摘要(Simulation summary)” 的输出中,首先看到模拟规格的详细信息(例如模拟次数)。“常数(Constants)” 部分列出各模拟中不变的变量值。“随机变量(Random variables)” 和 “逻辑变量(Logicals)” 部分列出模拟结果。我们看到模拟中的平均 “需求(demand)” 为 627.94,标准差为 109.32。还提供了模拟数据的其他特征(例如最大利润为 1758.77)。最后,我们看到利润低于 100 的概率为 0.32(即 1000 次模拟中,有 315 次利润低于 100 美元)。
要查看随机变量以及使用 “模拟公式(Simulation formulas)” 创建的变量的直方图,请确保勾选 “显示图表(Show plots)”。

由于我们在 “模拟数据(Simulated data)” 框中指定了名称,数据在 Radiant 中以`simdat`为名可用(见下方截图)。要在 Excel 中使用该数据,点击 “数据> 查看” 标签页右上角的下载图标,或前往 “数据 > 管理” 标签页将数据保存为 csv 文件(或使用剪贴板功能)。更多信息见 “数据 > 管理” 标签页的帮助文件。

## 重复模拟
假设上述模拟用于更好地理解每日利润。要深入了解年度利润,我们可以重新运行模拟 365 次。但通过 “重复(Repeat)” 标签页的功能可以更方便地实现。首先,在 “要重新模拟的变量(Variables to re-simulate)” 中选择变量,此处为`E`和`price`。然后在 “输出变量(Output variables)” 框中选择关注的变量(例如`profit`)。将 “重复次数(# reps)” 设置为 365。
接下来,需要确定如何汇总数据。如果在 “分组依据(Group by)” 中选择 “模拟(Simulation)”,数据将按每次模拟抽取**在**365 次重复模拟中汇总,得到 1000 个值。如果选择 “重复(Repeat)”,数据将按每次重复**在**1000 次模拟中汇总,得到 365 个值。如果将完整的重复模拟数据集想象为 1000 行 365 列的表格,按 “模拟(Simulation)” 分组将为每行创建汇总统计量,按 “重复(Repeat)” 分组将为每列创建汇总统计量。在本示例中,要确定 365 次重复模拟的每日利润总和,在 “分组依据(Group by)” 框中选择 “模拟(Simulation)”,在 “应用函数(Apply function)” 框中选择 “sum”。
要确定年度利润低于 36,500 美元的概率,在 “重复模拟公式(Repeated simulation formula)” 文本输入框中输入以下公式:
```r
profit_365 = profit_sum < 36500
```
注意,`profit_sum`是 “模拟(Simulation)” 标签页中定义的`profit`变量的重复模拟总和。输入所有值后,点击 “重复(Repeat)” 按钮。由于我们为 “重复数据(Repeat data)” 指定了名称,将创建新数据集。`repdat`将包含按模拟分组的汇总数据(即 1000 行)。要存储所有 365×1000 次模拟 / 重复结果,从 “应用函数(Apply function)” 下拉菜单中选择 “none”。
重复模拟的描述性统计量显示在主面板的 “重复模拟摘要(Repeated simulation summary)” 下。我们看到公司的年度预期利润(即`profit_sum`的均值)为 172,311.84 美元,标准差为 10,772.29 美元。尽管上文发现每日利润可能低于 100 美元,但全年利润低于 365×100 美元的可能性几乎为零(即年度利润低于 36,500 美元的重复模拟比例为 0)。

如果勾选 “显示图表(Show plots)”,“重复模拟图表(Repeated simulation plots)” 下将显示年度利润(`profit_sum`)的直方图。`profit_365`没有图表,因为它只有一个值(即 FALSE)。

下方截图中示例的状态文件可从此处下载。
关于如何使用模拟工具找到最大化利润的价格的简单示例,见可下载的状态文件此处。
### 在重复标签页中使用网格搜索
注意,“重复(Repeat)” 标签页也可以使用 “网格搜索(Grid search)” 输入,通过迭代方式替换 “模拟(Simulation)” 标签页中指定的一个或多个 “常数(Constants)” 来重复模拟。仅当 “分组依据(Group by)” 设置为 “重复(Repeat)” 时,才显示此输入选项。在 “网格搜索(Grid search)” 输入框中提供最小值、最大值和步长。例如,输入名称(`price`)、最小值(Min)(4)、最大值(Max)(10)和步长(Step)(0.01)。如果在 “网格搜索(Grid search)” 中指定多个变量,模拟会生成并评估所有可能的取值组合。注意,如果选择了 “网格搜索(Grid search)”,生成的值数量将覆盖 “重复次数(# reps)” 中指定的数量。然后点击图标。或者,直接在文本区域输入(或删除)内容(例如`price 4 10 0.01`)。
### 报告 > Rmd
通过点击屏幕左下角的图标或按键盘上的`ALT-enter`,向*报告 > Rmd*添加代码以(重新)创建分析。
如果已创建图表,可使用`ggplot2`命令或`patchwork`进行自定义。详见下方示例和*数据 > 可视化*。
```r
plot(result, custom = TRUE) %>%
wrap_plots(plot_list, ncol = 2) + plot_annotation(title = "Simulation plots")
```
### R 函数
有关 Radiant 中用于构建和评估(重复)模拟模型的相关 R 函数概述,请参见*模型 > 模拟*。
`simulater`工具中使用的来自`stats`包的核心函数包括`rbinom`、`rlnorm`、`rnorm`、`rpois`和`runif`。
### 视频教程
将以下完整命令复制粘贴到 RStudio 控制台(即左下角窗口),按回车即可获取 Radiant 教程系列中模拟模块使用的所有材料:
usethis::use_course("https://www.dropbox.com/sh/72kpk88ty4p1uh5/AABWcfhrycLzCuCvI6FRu0zia?dl=1")
在 Radiant 中设置模拟(一)
- 本视频演示如何使用 Radiant 设置模拟
- 主题列表:
- 泊松分布简介
- 指定模拟
- 模拟摘要解读
在 Radiant 中设置重复模拟(二)
- 本视频展示如何使用 Radiant 设置重复模拟
- 主题列表:
- 指定重复模拟
- 重复模拟摘要解读
使用模拟解决概率问题(三)
- 本视频演示如何使用 Radiant 中的模拟解决概率问题
- 主题列表:
- 回顾设置(重复)模拟
- 模拟摘要解读
- 重复模拟工作原理的直观理解
模拟公式技巧(四)
- 本视频讨论模拟公式中常用的一些实用函数
- 主题列表:
- 使用`ifelse`指定模拟公式
- 使用`pmax`指定模拟公式
在模拟中使用网格搜索(五)
- 本视频演示如何在模拟中使用网格搜索
- 主题列表:
- 通过排序模拟数据或创建图表找到最优值
- 使用`find_max`函数找到最优值