第十五天学习进度--数列找规律算法(预测算法)(1)
因为一直想写一种可以只输入一堆数,然后就能找出数列之间的通项公式,但是之前百度了很久都没有找到类似的算法。就拿现在大部分的情况来说,预测的算法像网上的大部分地方都选择了像神经网络这一类的算法,而我认为神经网络算法的模拟性比预测性强,神经网络在一些归类的问题上的解决要比预测性强得多,这是平时在实验上的感觉。
为了找到一种通用类型的算法,前几天特意在学习了曲线函数拟合的算法运用,通过一个简单的修改,来实现输入一堆数列然后得出数列对应的函数的功能,之后就能通过这个曲线函数做对应的预测了。
今天在之前的基础上,添加对应的函数来实现只输入一个数列,就能得到数列对应的规律的方法。(当前方法具有局限性,因为多项式不可能有无限项,无法做泰勒展开以接近任意可导函数)
我们知道了,数列的规律一般都是由公式来组成的,而一般来说,数和数之间的规律都是比较简单的,为了找到一个通项公式,需要对其中所有的函数做一个还原,而前几天学习到的函数拟合算法就派上了用场:曲线函数拟合
不过既然是拟合的话,如果预测数列中包含幂函数的规律的话,将会随着x的增大,误差越来越大,不过总体上只要控制好最高幂次,使其在最后的某个区域内符合幂函数的增长趋势,就能保证在一定范围内的准确性
例如预测斐波那契数列
[1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
的下一项
在之前的曲线函数拟合的那篇文章基础上,添加上以下的内容
#数列规律寻找(数列中包含的None表示该位置没有数值标志,数列规律受数列顺序影响) def auto_find_logical(y): x=[] x_None=[] y_temp=[] for i,info in enumerate(y): if(info!=None): x.append(i+1) y_temp.append(info) else: x_None.append(i) suit=1 minsuit=0 g_start=True import warnings warnings.filterwarnings("ignore") for i in range(1,maxn,1): fit_coef, alist =ax_bfit(x[:-1], y_temp[:-1], i) temp_minus=abs(func_general(fit_coef, [x[-1]])[0]-y_temp[-1]) if(g_start or temp_minus<minsuit): minsuit=temp_minus suit=i if(g_start): g_start=False else: break warnings.filterwarnings("default") fit_coef, alist = ax_bfit(x, y_temp, suit) print("自适应最高幂次:",suit) for one in x_None: x.insert(one,None) return fit_coef,alist,x #靠猜最高幂次型数列规律寻找(数列中包含的None表示该位置没有数值标志,数列规律受数列顺序影响) def find_logical(y,n): x=[] x_None=[] y_temp=[] for i,info in enumerate(y): if(info!=None): x.append(i+1) y_temp.append(info) else: x_None.append(i) fit_coef,alist=ax_bfit(x,y_temp,n) for one in x_None: x.insert(one,None) return fit_coef,alist,x
由于斐波那契数列的增长是幂次增长的,需要控制最高幂次(平常数列的预测直接用自动型就好了,要是知道增长是幂函数类型的就得靠测试了),所以将最高幂次控制在11(可以测试得出,最高幂次波动将会影响对应预测值的范围,但整体预测都是相对接近的),这里使用的是自动型(计算量会比较大,但是能自动设置为11,受maxn影响最大只会自动到20),使其符合斐波那契数列在我们给定的这些数列中的最后那一部分的增长
输入训练数据
fit_coef,alist,x=auto_find_logical([1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]) print(func_general(fit_coef,[x[-1]+1,x[-1]+2]))
然后我们看看预测的下两项是什么,通过计算可以发现,斐波那契数列的下两项真实值是10946和17711
我们看看实验结果是什么:
我们发现预测出来的最终结果是10946和17710,虽然有一定误差,但是预测出来的结果,可以说很接近了