在实际的生产当中会积累很多的业务数据,很多时候数据的质量变得很重要,现在已经有很多数据质控的算法陆续应用了起来,但是大都是基于业务知识与数据分析技术来实现的,难以独立应用,今天想从单一数学的角度来尝试一下数据拟合相关的东西,在数据质控领域内,连续时刻的数据会形成一条曲线,做质控往往和数据曲线拟合密不可分,我们已经尝试过多种的数据曲线拟合方法,可以基于机器学习的回归模型来基于历史数据集构建回归模型进而挖掘曲线的规律,也可以基于深度学习来做同样的事情,今天的主要学习内容是基于多项式模型PCF来实现数据曲线拟合。
多项式拟合模型中的一个核心优化策略就是最小二乘法,不了解这个方法的可以先去简单百度一下,整体的路线是这样的:
python中scipy模块已经实现了多项式拟合模型,我们不需要自己再去实现只需要一句话导入进来需要的方法就行了,具体命令如下:
from scipy.optimize import curve_fit
实验中用到数据如下:
D0=[40, 33, 32, 32, 30, 29, 28, 29, 27, 25, 22, 21, 20, 19, 17, 17, 18, 20, 20, 21, 21, 23, 21, 22, 24, 24, 24, 26, 25, 23, 23, 20, 23, 25, 22, 21, 18, 18, 19, 19, 19, 18, 18, 18, 18, 18, 18, 17, 19, 20, 20, 19, 20, 20, 20, 20, 19, 18, 18, 21, 24, 20, 25, 25, 24, 21, 21, 21, 21, 25, 29, 32, 30, 29, 29, 32, 32, 33, 36, 36, 35, 34, 36, 39, 43, 47, 48, 46, 47, 50, 50, 54, 55, 58, 55, 52, 49, 52, 49, 46, 46, 43, 39, 38, 39, 39, 39, 38, 36, 36, 35, 33, 33, 35, 36, 33, 32, 32, 26, 26, 28, 26, 28, 30, 30, 27, 26, 27, 26, 27, 22, 22, 25, 28, 29, 27, 28, 31, 35, 50, 60, 65, 66, 67, 64, 61, 69, 74, 77, 75, 77, 72, 64, 73, 80, 77, 74, 77, 83, 84, 87, 88, 85, 79, 77, 68, 68, 69, 65, 64, 64, 60, 64, 63, 65, 67, 68, 68, 62, 54, 52, 52, 47, 48, 47, 0, 45, 46, 48, 46, 45, 45, 45, 43, 42, 42, 40, 39, 38, 39, 38, 36, 38, 39, 38, 38, 35, 35, 29, 32, 42, 52, 55, 58, 57, 55, 55, 56, 55, 53, 52, 54, 58, 59, 62, 59, 54, 53, 52, 52, 55, 57, 55, 54, 55, 62, 72, 53, 74, 70, 72, 68, 67, 60, 58, 56, 54, 53, 52, 52, 51, 48, 45, 42, 40, 42, 45, 53, 57, 55, 53, 53, 55, 56, 57, 58, 57, 56, 56, 55, 55, 55, 54, 53, 52, 54, 57, 63, 67, 70, 70, 66, 64, 62, 60, 60, 63, 66, 61, 62, 66, 69, 72, 74, 75, 72, 69, 65, 62, 63, 62, 58, 52, 48, 46, 43, 38, 35, 32, 31, 31, 32, 29, 27, 29, 28, 29, 28, 26, 26, 29, 30, 28, 23, 23, 22, 20, 20, 19, 0, 33, 42, 42, 42, 44, 48, 52, 53, 52, 50, 46, 43, 41, 38, 38, 39, 38, 34, 30, 28, 30, 33, 33, 37, 40, 46, 49, 51, 52, 52, 52, 51, 49, 48, 48, 47, 46, 48, 49, 47, 44, 42, 40, 36, 36, 40, 40, 42, 43, 43, 45, 48, 53, 54, 53, 51, 46, 42, 43, 48, 52, 53, 52, 50, 52, 52, 53, 54, 62, 65, 67, 68, 68, 69]
数据量不是很大,差不多是几百个数据吧,感兴趣的话可以直接复制过去跑一跑的。
拿到这一批数据后我们首先先对数据做一个整体的查看,可视化命令如下:
plt.plot(D0)
plt.plot(D00)
plt.show()
上图中,蓝色曲线是原始的数据曲线,黄色线条是经过滑动平均的数据填充算法处理后的数据曲线。
接下来我们要对比一下经过数据预处理与未经过数据预处理两种形式得到的数据拟合的效果有没有差别,具体实现如下:
def twoCompare(y1,y2,n,flag=True,pic_path='compare.png'):
'''
对比数据预处理与未预处理的效果
'''
#未预处理
x=range(len(y1))
f1=np.polyfit(x,y1,n)
p1=np.poly1d(f1)
yvals=p1(x)
mse,info1=calPerformance(y1,yvals.tolist())
plt.clf()
plt.figure(figsize=(8,6))
#预处理
f2=np.polyfit(x,y2,n)
p1=np.poly1d(f2)
yvals2=p1(x)
mse,info2=calPerformance(y2,yvals2.tolist())
plt.plot(x,y1,'b',label='original values')
plt.plot(x,yvals,'g',label='polyfit values(NO)')
plt.plot(x,yvals2,'r',label='polyfit values(YES)')
plt.xlabel('X',english)
plt.ylabel('Y',english)
#设置图例信息
plt.legend(loc=4,ncol=1) #指定legend的位置右下角
title_info=str(n)+u"阶多项式拟合结果对比曲线(未预处理) \n"+info1+\
'\n'+str(n)+u"阶多项式拟合结果对比曲线(预处理) \n"+info2
plt.title(title_info,chinese)
plt.savefig(pic_path)
return yvals,yvals2
结果如下:
我们以回归模型常用的四个指标来衡量PCF对数据曲线的拟合好坏,可以发现经过数据预处理后再同等阶数的多项式模型中拟合的效果要优于未经过数据预处理的情况,此外,我们同样证实了,在自动调参实验中,未经过数据预处理时在较低的阶数就停止了继续优化,且最终的拟合效果不如经过数据预处理的情况。
在完成上述工作后,我突然想到,是否可以将原始的数据曲线人为进行划分呢,划分成多个区段,然后分阶段拟合呢,效果是不是会更好一点呢?想到这里不如实现一下吧:
def jieDuanFitting(data,num=24,n=5,save_path='save_path.png'):
'''
分阶段拟合数据
'''
data_list=cutList(data,c=num)
res_list=[]
for i in range(len(data_list)):
one=data_list[i]
one_res=polyDemo(range(len(one)),one,n=n)
res_list+=one_res
plt.clf()
x_list=range(len(data))
plt.plot(x_list,data,'b',label='original values')
plt.plot(x_list,res_list,'r',label='polyfit values')
plt.xlabel('X',english)
plt.ylabel('Y',english)
mse,info=calPerformance(data,res_list)
plt.legend(loc=4,ncol=1) #指定legend的位置右下角
title_info=str(n)+u"阶多项式拟合结果对比曲线\n"+info
plt.title(title_info,chinese)
plt.savefig(save_path)
return res_list
结果如下:
从上图结果中看到,5阶的时候就已经达到了0.981的拟合度,果然是非常不错的。
写到这里忍不住要对比一下上面三种方法:
D1、D2和D3分别表示未经过数据预处理、经过数据预处理和分阶段拟合三种方式得到的拟合曲线,还是很有收获的,之后有时间接着再做,记录一下。