因為一直想寫一種可以只輸入一堆數,然后就能找出數列之間的通項公式,但是之前百度了很久都沒有找到類似的算法。就拿現在大部分的情況來說,預測的算法像網上的大部分地方都選擇了像神經網絡這一類的算法,而我認為神經網絡算法的模擬性比預測性強,神經網絡在一些歸類的問題上的解決要比預測性強得多,這是平時在實驗上的感覺。
為了找到一種通用類型的算法,前幾天特意在學習了曲線函數擬合的算法運用,通過一個簡單的修改,來實現輸入一堆數列然后得出數列對應的函數的功能,之后就能通過這個曲線函數做對應的預測了。
今天在之前的基礎上,添加對應的函數來實現只輸入一個數列,就能得到數列對應的規律的方法。(當前方法具有局限性,因為多項式不可能有無限項,無法做泰勒展開以接近任意可導函數)
我們知道了,數列的規律一般都是由公式來組成的,而一般來說,數和數之間的規律都是比較簡單的,為了找到一個通項公式,需要對其中所有的函數做一個還原,而前幾天學習到的函數擬合算法就派上了用場:曲線函數擬合
不過既然是擬合的話,如果預測數列中包含冪函數的規律的話,將會隨着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,雖然有一定誤差,但是預測出來的結果,可以說很接近了