什么是曲线拟合
所谓的曲线拟合,就是使用某一个模型(或者称为方程式),将一系列的数据拟成平滑的曲线,以便观察两组数据之间的内在联系,了解数据之间的变化趋势。
曲线拟合的作用
在数据分析时,我们有时需要通过已有数据来预测未来数据。在一些复杂的数据模型中,数据维度很多,数据之间的关系很复杂,我们可能会用到深度学习的算法。但是在一些简单的数据模型中,数据之间有很明显的相关性,那我们就可以使用简单的曲线拟合来预测未来的数据。
曲线拟合的方法
Excel曲线工具
假设我们有一组用户生命周期价值(LTV)和天数的对应数据
Day | LTV |
---|---|
1 | $0.20 |
2 | $0.35 |
3 | $0.45 |
4 | $0.52 |
5 | $0.57 |
6 | $0.60 |
7 | $0.62 |
8 | $0.63 |
将数据放进Excel中,插入折线图
右击蓝色曲线,选择“添加趋势线”,并选择趋势线为“对数”,并勾选“显示公式”
可以看到,曲线图中出现了一条虚线的曲线,并显示了对应的公式为
Excel的趋势线工具提供了几个常用的函数,包括指数函数、对数函数等,可以满足一般需求。但是如果数据曲线相对复杂的话,就需要用到下面的工具了。
Excel Solver
要使用Solver,首先需要进入Excel的选项,启用“规划求解”工具
启用之后,在工具栏“数据”标签页下,会多出一个“规划求解”的工具
我们先看一下这个工具的界面,就可以大概了解它的功能。简单来说,Solver可以通过改变一些单元格的值,来使一个目标单元格的值最接近理想值。
我们还是用之前的表格来举例如何使用Solver。现在已经知道了LTV对于Day来说是一条类似对数函数的曲线,可以使用对数函数来模拟。我们假设这个函数是
其中a和b为参数,是可变的。我们调整一下表格,添加一列Estimate LTV,为根据a、b和Day列计算出来的值。再增加一列Diff,为Estimate LTV和Real LTV的差值的平方(平方是为了防止不同行的正负差值会互相抵消),最后加总这些差值。
我们希望通过改变a、b的值,使通过公式得出的LTV与真实LTV的偏差最小,即Total Diff(F18)的值最小。打开规划求解工具,设置如下
点击求解,片刻后即可计算出最接近目标的a、b值
可以看到,a、b的值和使用趋势线得到的值是一样的。
在线工具
介绍一个非常好用的在线曲线拟合工具:
http://www.qinms.com/webapp/curvefit/cf.aspx
Python matplotlib库
Python的matplotlib库有一个自定义公式来拟合曲线的功能。下面代码演示了通过它来拟合上述例子的过程
1 | # -*- coding: UTF-8 -*- |
输出结果为:
1 | [0.21482987 0.20772681] |
曲线拟合公式
在前面的例子中,我们使用了对数函数来进行拟合。在上文提到的在线曲线拟合工具网站中,也列出了一些常见的拟合方程,包括直线、多项式、对数、指数等。其中有一个方程对于拟合自然曲线非常好用,就是四参数方程。
四参数方程的格式为:
我们还是用最开始的Day/LTV数据来举例,比较一下它和对数函数拟合的结果。
四参数方程 - Solver比较
修改一下之前的Excel表,将Estimate LTV列使用的公式修改成四参数方程
在规划求解设置中,依然是期望Total Diff达到最小值,可变单元格增加了c、d两个参数
点击求解,获得a、b、c、d四个参数的最优解。我们可以看到,Total Diff比使用对数函数时减少了将近一半
四参数方程 - matplotlib比较
同样,我们修改一下python脚本,改为使用四参数方程。请注意,我们这次添加了一个param_bounds值,将C这个参数限定在了0.001到正无穷。这是因为C在公式中充当了分母,不能等于0,而我还没找到一个有效的限制C不为0的方法。
1 | # -*- coding: UTF-8 -*- |
输出结果为
1 | [0.0923509 1.73652154 2.41689489 0.70144044] |
可以看到,相对于Excel Solver来说,matplotlib库获得的结果更精准,预测值和真实值几乎没有偏差。