概述
预测,在商业中,是一个永恒的话题。PowerBI对预测的支持首先要承认是很有限的。对于非常多的企业,从计划管理的角度,会有这样的情况:
- 依赖人的经验辅助计算得到某些指标的预测。(如:销售额,员工数,项目完成度等)
- 每年做全年预测。
- 预测是如何进行的,可以由业务执行者完成。
- 常常依赖于经验,也就是拍脑袋或梳头发。
- 允许预测是带有偏差的。
- 企业高层决策深知这是常态。
- 甚至偏差是可以被当做目标的。
- 因此预测往往会是保守的,使得实际总是会更加理想。
- 允许预测可以每个月进行调整。
- 随着时间的推移,每月的调整预测将更加准确。
- 直至整年结束。
上述流程几乎是非常成熟的,从设计来看,这是一种非常好的模式,因为预测与实际的呈现与预测的过程是独立的,也就是说,预测与实际的对比根本不Care预测的过程是瞎猜的,AI的,计算的还是如何得到的。
例如:
如上所示,含义如下:
- 2019年1月 分别预测了个月的业务指标,并以红色显示。
- 2019年2月 已知了1月的实际,填入并以绿色显示;重新调整对随后月份的预测,并以红色显示。
- 依次类推。
在现实中,可能需要的内容要比这样的显示更加复杂,但很多复杂可以由巧妙的设计来扩展。我们一起来研究这里的设计应该具有的特点。
建模中的核心思想
上述展示了模型的核心部分。所有现实的各种复杂性都将基于这个不变的结构进行扩展。
值得强调的是:
- 不变的部分:每个月知道小于本月的实际,且不再改变;预测大于等于本月的部分。
- 扩展的部分:具体的指标是可以扩展的。
因此,实际的情况可能是:
当用户选择不同指标以及预测的子项时,该矩阵会自动显示出相应的结果。这体现了BI的切片效应。
数据准备
值得强调的是,该模型的实际数据与预测数据来自外部,实际数据可以直接导出,而预测数据是怎么得到的,这里并不关心,这点非常重要。
在某些企业,预测是可以交给经验丰富的专业人员进行的;在某些企业,预测又是可以交给某精确复杂的计算流程实现的(如:通过R的某些特别适合的算法等)。
在这里我们只关心结果,并在结果的基础上供决策人员进一步分析。
准备的数据至少由两部分构成:
- 实际数据
- 预测数据
而它们都必须符合一个特点:每月更新版本。
这里模拟了它们可能的存放结构:
其中,实际数据:
类似的,预测数据:
以201904版本为例,对于实际数据,其结构为:
其特点是:对于某月版本,只能知道小于该月版本的实际数据。
以201904版本为例,类似的,对于预测数据,其机结构为:
其特点是:对于某月版本,只能填写大于等于该月版本的预测数据。
因此,在数据处理中,需要:
- 分离出不同的指标。
- 合并整个实际数据。
- 合并整个预测数据。
这部分在传统上,可能需要IT来完成,而在自助商业智能分析的体系下,可以借助PowerBI的查询编辑(又叫:PowerQuery)由业务分析人员自行完成,如下:
这里给出了一个标准的参考。
大家可以自己模拟数据并根据学到的PowerQuery知识来尝试,关于这部分系统的能力教学已经收录在我们的《PowerBI自助商业智能分析系列视频教程》中,此处不再赘述。
对于处理好的数据,如下所示:
命名,体现了极高的专业性,例如:YMDate表明这是一个日期类型,目的是为了与日期表进行关联,如果需要发生日期维度的计算,可以直接利用日期(时间)智能函数的便捷性。而YM二字体现该列的实际粒度在月的级别,使用日期级别是错误的。 合理的命名,可以给后期的使用带来重大的便利。 通过查看一个人的命名,便知道他对PowerBI或DAX理解的级别。
数据模型
这是一个典型的多事实(明细)表案例,如下:
在这个模型中,由三大非常重要的维度:
- 日期
- 版本
- 属性
这决定了用户可以在某版本来观察某些属性在某些日期的实际与预测综合表现。
度量值
以 销售额 和 利润 为例,来看度量值的写法:
代码语言:javascript复制KPI.Actual.Base =
VAR vKPIName = SELECTEDVALUE( KPIName[KPIName] , "Sales" )
RETURN CALCULATE( SUM( DataActual[Value] ) , DataActual[KPIName] = vKPIName )
KPI.Forecast.Base =
VAR vKPIName = SELECTEDVALUE( KPIName[KPIName] , "Sales" )
RETURN CALCULATE( SUM( DataForecast[Value] ) , DataForecast[KPIName] = vKPIName )
以及:
KPI.Base = [KPI.Actual.Base] [KPI.Forecast.Base]
以及:
KPI = IF( ISFILTERED( 'Version'[Version] ) , [KPI.Base] )
由于前面的设计,让这里的度量值编写非常具有技巧性:
可以看出,这里构建了具有层次性的度量值体系,它们的特点在于:
- KPI,处理版本化后的KPI.Base;
- KPI.Base,计算实际与预测结合的综合效果;
- KPI.ActualBase,计算实际;
- KPI.ForecastBase,计算预测。
Base一词,语义为基础,它预示着这是一个不该直接使用的度量值,而是为另外的度量值提供了基础。
这里体现了一个重要的设计思想:用层次结构解除内部依赖结构。
当用户的需求开始发生变化时,您会发现这样的结构可以让我们灵活地工作在不同的位置,可以应对业务的变化。
值得强调的是:
代码语言:javascript复制KPI.Base = [KPI.Actual.Base] [KPI.Forecast.Base]
在这里有一个非常惊艳的计算,KPI居然直接可以由实际与预测相加。这基于下面的优化(这是为了让您遇到问题时,回来第N次查看时可以得到的感悟):
- 在数据准备中,实际数据我们需要用户填写积累更新的每月数据,而不是仅仅填写当月数据。这样,我们取不同版本计算时,都可以确保该版本下,需要有实际数据的月份都可以有实际数据,而不用去考虑低版本中的实际数据。
- 在数据准备中,我们明确发现有实际则预测无效;有预测则实际无效;因此,综合表现恰好为实际与预测的和。这种直接加和的巧合,不但简化的计算,还可以免去IF逻辑,大幅优化了性能。
度量值的染色
我们知道PowerBI给出了设置颜色的功能,但在很多高级的专业设计中,我们需要的是DAX驱动的可视化。这里直接使用度量值来制备染色方法。
代码语言:javascript复制-- 当用户选择版本和日期时,我们判断该版本下在该日期段是否已经有了实际数据
Version.IsUpdate =
VAR vYMNumber = SELECTEDVALUE( 'Calendar'[Year] ) * 100 SELECTEDVALUE( 'Calendar'[Month] )
VAR vVersion = SELECTEDVALUE( 'Version'[Version] )
RETURN vYMNumber < vVersion
-- 对实际与预测进行染色
KPI.Color =
IF( [Version.IsUpdate] , "#348640" , "#B10113" )
总结
这是一个非常通用的业务模型,它为企业在月粒度管理企业计划与实际的所有需求提供了核心模型;这里作为该模型的第一课,希望大家可以自行实践。
在很多大型传统企业,尤其是外企,这是一种几乎通用的方法,在PowerBI中的实现可以让人眼前一亮,为您在外企的晋升提供专业助力。
在企业的实际运用中,可能会基于此提出更多需求,例如:
- 在一个月同时显示不同指标;
- 计算前后版本的估算差异;
- 计算季度粒度以及年度粒度的完成性;
- 动态筛选某些维度来观察。
这些可能性我们将在后续文章进一步展开,欢迎您需要关注。
案例模型及模拟数据已经共享至订阅会员区,请大家自行获取学习。
欢迎交流