跳到主要内容

方法论 之 问题的解,科学方法,以及 然后呢?

继续上节说方法论。

问题的解/解决方案/解空间

假设我们已经搞清楚了问题是什么,并且有了一些思考和线索,但下一步呢?立即动手吗?It depends(看情况). 如果动手这个动作只需要两分钟(确指两分钟,而非虚指),那么就马上去做,然后看看能不能解决问题,(事实上,两分钟原则是《尽管去做 Getting Things Done / GTD》里面提到的原则之一)。 但是在数据分析的绝大部分问题中,立即动手并不是最好的选择,即使是一些初步试探性的方案,需要的时间也会在几天,几周到几月不等,甚至一个团队的人花了几个月的时间却走到一个死胡同都是非常有可能的。

寻找树根中的宝藏

寻找树根中的宝藏

想象一下,我们站在树根位置(问题的起点)往下挖,期待能够挖到我们的宝藏(问题的解)。一个明显的方案是顺着树根开始的位置挖,随着挖掘的深入,会逐渐遇到各种分叉,我们需要根据蛛丝马迹判断形势,做出要往什么地方继续挖的决定。有一些看上去很粗的根(一些看上去很明显的方案)不一定能够更快地找到我们想要的宝藏,而一些看上去是在走回头路的根茎也许能够达到目标。

那么究竟要怎么做,才会解决问题呢?我们所需要的是“科学方法”。

科学方法

获得解释宇宙某个方面理论的过程被称为科学方法。

使用科学方法在解决数据分析问题时大致包括以下几个步骤:

  1. 观察问题。
  2. 构造出一个假设来解释问题,使它与观察到的事实保持一致。
  3. 根据假设进行预测
  4. 通过试验或进一步的观察来验证那些预测
    • 如果试验结果符合预测,那么就改进这个假设
    • 如果试验结果不符合预测,那么就构造一个新的假设来替代它
  5. 重复第3步和第4步,一直到假设不需要再改进了。

也许会有人觉得,这就是正常解决问题的方法啊,只不过换成了更晦涩的语言来表述而已。就像前面说过的,这的确是常识,但仍然有一些细微且非常重要的不同。我试着举例解释一下。

一个做投资的老哥给我讲过这样一件事。一个创业者给老哥讲了一下他的商业计划书,观察到现在市面上的智能家居都缺少某某功能,而且通过广泛调研确定这个需求是真实存在的,甚至思考了怎么具体做推广,怎么尽量让这个产品快速占领用户的客厅。 老哥只问了一个问题:"假设你的技术问题都一个个被完全解决,而且也通过各种渠道占领了一部分市场,用户也都把你这套设备放在了客厅中,然后呢?然后怎么挣钱?靠硬件挣钱吗?成本能足够低吗?靠广告挣钱?嗯, 行. 能挣多少?需要多少个客户以及客户每天使用的频率是多少才能挣到钱?" 创业者呆住了。

这个例子里的创业者 观察到了问题(包括实际需求问题以及创业问题),确定了实际需求问题的确是实际需求;构造出了一个能够解决问题,并将产品推广的假设,然后希望在这个假设前提之下通过创业(试验)解决问题。

用上面使用科学方法的步骤可以知道,其实他只对需求问题的假设进行了预测,而缺少对创业问题假设预测,这也正是老哥问问题的内容。

当然,科学方法并不是解决整个问题唯一的方法,也许有人能够一拍脑袋就给出一个正确的解决方案,但按照解决问题的平均时间来看,科学方法毫无疑问会是最快的方法。

然后呢?

我们已经稍微理解了一点如何使用科学方法去解决问题. 其中个人觉得最容易疏漏的就是其中的第 3 步(根据假设进行预测)。也许是因为人类天生的惰性,想到假设就已经很辛苦了,很难再去进一步想 -- 如果真的是这个假设,能预测到什么结果(观察到什么现象)。所以这里特别提出来一节,举一个个人经历过的实际例子,并把第 3 步中的细节抽象出来。为了方便记忆理解,简称为,"然后呢?"

我曾做过一些 Linux 中非常底层的开发 -- 无线路由的驱动开发。非常底层的另外一个意思是,我们能拥有的工具相对较少。高级语言开发过程中,如果程序出错了,我们可以看程序的堆栈,看程序的log,或者加断点等等,调试手段非常丰富。如果我们是做驱动开发的,普通错误还比较简单,无论如何可以增加一些打印信息来看一下出错前的地方在哪,然后再推断错误;而复杂错误,比如kernel panic(系统崩溃)这种级别的错误,就比较难以调试了,打印信息大部分情况是根本不可能存在的。不熟悉 Linux 的同学可以类比 Windows 蓝屏 -- 如果我们使用一个程序,平时使用还正常,但不知怎么回事,有时就会出现蓝屏,我们只能重启机器,这种错误我们应该怎么追溯?

堪比 kernel panic 的 windows 蓝屏

堪比 kernel panic 的 windows 蓝屏

有一次,组长 Peter 给了我台设备,并且告诉我,在这台设备上会有系统崩溃的现象出现,让我去查查什么问题。于是:

  1. 观察问题。拿到设备之后,我写了一套自动化的方法,随机输入一些命令,不停地使用它,两个小时之后,系统崩溃了。 两个小时才会出现一次的错误,而且没有什么日志,这种错误怎么查?先重现错误让观察问题方便点吧。 仔细回顾了之前随机输入的命令,改进了一下,筛选出了一些感觉有用的操作,成功的让这个错误几分钟就出现一次。
  2. 假设是我们的软件(无线驱动)内部的缺陷导致的问题,而非板级BSP,或操作系统的问题(我们会裁剪操作系统,所以操作系统也可能出问题)。
  3. 如果是我们的软件问题,那么预测在某些非常特定的条件下这个问题会被触发,某些条件下不会触发。
  4. 试验。我找了几台设备,模拟了各种不同的环境,结果发现只有我使用的这台设备会系统崩溃。 试验结果不满足3中的预测"某些条件下"会被触发,而只是"某个设备"会触发。 那么说明,2中的假设是错误的。我需要重新构造一个新的假设
  5. (2)这台设备的硬件是有问题的。这是一个假设,并不是一个结果,需要验证这个假设。
  6. (3)如果这台设备硬件是有问题的,那么预测这台设备的硬件状态和其他设备的硬件状态应该是有差别的。看了下硬件版本号,都是同一个批次的。
  7. (4)试验。因为环境所限,并没有工业X光机这样的设备,直接对设备进行对比,只能另辟蹊径。我先让不同的设备跑相同的程序一个小时,之后,找了一台红外线体温计测量了设备中各个芯片的温度,这台出问题设备射频芯片温度比其他设备的相关芯片温度明显高了很多。
  8. (5)结论。射频芯片周边电路配置或射频芯片焊接有问题(接触不良导致电阻增加,而电阻增加会导致发热量增加)。

这个有趣而且神奇的经历,也是我目前经历过的,唯一一次用体温计进行 Debug(排错)的经历。

多问问自己,"然后呢?"。有一个假设之后,*然后呢?*如果假设成立,然后呢?如果假设不成立,然后呢?然后的然后呢?

思维并不总是有乐趣的,尤其是有时看不到结束的一个个"然后呢?"。但是想到如果能够减少自己最宝贵的时间损耗,"然后呢?"还是一个很好的问题。