第十三天学习进度--曲线函数拟合(可以做数据预测的函数)

因为之前学习的神经网络的算法大多都是拟合非线性函数的,所以在某些具有连续性的预测方面,神经网络算法的函数拟合并没有简单函数好用。

今天学习一下关于曲线函数的拟合方式。

首先给定一组数据来对数据进行拟合,例如随便想一个函数 y=2x^3+x^2+1

接下来分别取x=[1,2,3,4,5]

对应的y就为y=[4,21,64,145,276]

上面的数据x和y就为基础的数据,然后我们需要通过x,y这些训练数据,得到一个f(x)来得到具体的函数转换器y=2x^3+x^2+1

所以现在我们吧x,y作为训练数据代入 则有以下的过程

 (对于上下波动的函数拟合暂时不太理想)

 

import numpy as np
import scipy.stats as stats

#自动型最大幂次,减小计算量
maxn=20

#自动多项式函数拟合(计算量相对较大)
def auto_ax_bfit(x,y):
    x=np.array(x)
    y=np.array(y)
    n=maxn if len(x)-1>maxn else len(x)-1
    alist=[]
    g_start=True
    suit=1
    minsuit=0
    import warnings
    warnings.filterwarnings("ignore")
    pi=np.where(x==max(x))[0][0]
    new_x = np.delete(x,pi)
    new_y = np.delete(y,pi)
    for i in range(1, n, 1):
        fit_coef, blist = ax_bfit(new_x, new_y, i)
        temp_minus = abs(func_general(fit_coef, [x[pi]])[0] - y[pi])
        if (g_start or temp_minus < minsuit):
            minsuit = temp_minus
            suit = i
            if (g_start):
                g_start = False
    warnings.filterwarnings("default")
    fit_coef, blist = ax_bfit(x, y, suit)
    print("自适应最高幂次:",suit)
    minnum=1e-12
    for one in fit_coef:
        if(not g_start):
            if(abs(one)>minnum):
                g_start=True
                alist.append(one)
        else:
            alist.append(one)
    alist=[round(one,9) for one in list(alist)]
    return fit_coef,alist

#靠猜最高幂次多项式拟合,n是最高幂次,这个需要靠猜n的大小,n越大计算量也就越大,同时也越准确(泰勒展开公式,最高幂次越大越逼近准确函数),同时n需要小于len(x),当太大时直接取正整数型,想方便时也直接用自动型就好了
#但如果一个函数中包含幂函数,则需要将最高幂次调整至对应的范围使其符合幂函数的增长趋势才能让拟合函数在一定区间内符合函数增长,这点自动型做不到
def ax_bfit(x,y,n):
    x=np.array(x)
    y=np.array(y)
    fit_coef=np.polyfit(x,y,n)
    alist=[round(one,9) for one in list(np.polyfit(x,y,n))]
    return fit_coef,alist

#函数构建器
def func_general(fit_coef,predict_xlist):
    calculate_y = [round(one, 9) for one in list(np.polyval(fit_coef, predict_xlist))]
    return calculate_y

 

代入对应数据,并预测当x=[1,3,6]时,f(x)对应的值是多少(根据事先所想的函数,正确的值应该是[4,64,469]),下面我们代入数据看看结果

#数据列表
x=[1,2,3,4,5]
y=[4,21,64,145,276]

#需要预测的x值
calculate_x=[1,3,6]
#期待值[4,64,469]

# #拟合函数最高次幂(这部分可以靠猜,当为3时是准确值,计算量相对较小型)
# n=3
# fit_coef,alist=ax_bfit(x,y,n)

#自动型,计算量相对较大
fit_coef,alist=auto_ax_bfit(x,y)

print("系数列表:",alist)
print("calculate_x列表对应的预测值:",func_general(fit_coef,calculate_x))

最终结果如下:

 

可以看到预测出来的函数为: 与2x^3+x^2+1一致

预测值和期待值[4,64,469]一致

 

有人说,预测这么简单的函数太简单了,给我时间我也能计算预测出来结果。

所以我们来根据函数值,预测自然数的y=e^x的通项公式

根据训练值

x=[2,2.11,3.24,3,4,5,2.1,4.2,3.2,1.3,1.36,1.6,2.7,5.7,3.6]

y=[np.exp(one) for one in x]

我们知道e是一个无理数,平常来说,我们基本上很难通过上述给定的数值来确定其通项公式

这个时候我们看看曲线拟合之后的结果(泰勒展开公式,预测结果的准确率将根据最高幂次和给定的训练值的量的而变化,最高幂越高和值越多结果将越准确)

我们知道 e≈2.7182818284590452353602874713526624977572

我们看看预测出来的e的大小是多少,上述给定的训练值中并没有x=1的情况

当x=1时

#数据列表
x=[2,2.11,3.24,3,4,5,2.1,4.2,3.2,1.3,1.36,1.6,2.7,5.7,3.6]
y=[np.exp(one) for one in x]

#需要预测的x值
calculate_x=[1]
#期待值[2.7182818284590452353602874713526624977572]
# #拟合函数最高次幂(这部分可以靠猜,当为3时是准确值,计算量相对较小型)
# n=3
# fit_coef,alist=ax_bfit(x,y,n)

#自动型,计算量相对较大
fit_coef,alist=auto_ax_bfit(x,y)

print("系数列表:",alist)
print("calculate_x列表对应的预测值:",func_general(fit_coef,calculate_x))

结果对比

 

 虽然提醒我们给定的训练值太少了,但是我们可以看到预测结果接近2.7182818284590452353602874713526624977572了

 

posted on 2020-07-22 22:33  Halone  阅读(1730)  评论(0编辑  收藏  举报