如何找到包含一组给定点的函数?

问题描述

如果我有一组点,我如何找到适合它的函数?我查看了 here,在我尝试更复杂的函数之前,它运行良好。当从 python 中的函数给出一个点列表时,我试图找到 sigmoid 函数。我知道任何多项式都可以工作,但我想找到适合这些点的最简单的函数。简单来说,我的意思是最少的术语。这是我的代码

import numpy as np
from sympy import Symbol,Function

x = Symbol("x")
xs = np.array([0,-1,1,.5,-.5])
ys = np.array([.5,.269,.731,.622,.378])

fx = ys[0]

for i in range(len(xs)-1):
    #g(x) function
    gx = x-xs[0]
    for j in range(1,i+1):
        gx *= (x-xs[j])

    #lambda function. Make sure to watch out for the first loop when fx is not a symbol
    if type(fx) == np.float64:
        lmx = (ys[i+1]-fx)/(gx.subs(x,xs[i+1]))
    else:
        lmx = (ys[i+1]-fx.subs(x,xs[i+1]))/(gx.subs(x,xs[i+1]))

    #redefine f(x)
    fx = fx +(lmx)*(gx)
fx = fx.simplify()
print(fx)

这个输出-1.48029736616688e-16*x**4 - 0.0173333333333334*x**3 + 1.48029736616688e-16*x**2 + 0.248333333333333*x + 0.5 但我期待 1/(1+e^(-x))。 提前致谢!

解决方法

我知道任何多项式都可以工作

是的,您可以像这样在数据点上使用 interpolateinterpolating_poly

from sympy import *
from sympy.polys.specialpolys import interpolating_poly
from sympy.polys.polyfuncs import interpolate

x = Symbol("x")
xs = [0,-1,1,.5,-.5]
ys = [.5,.269,.731,.622,.378]

xs = [QQ.convert(i) for i in xs]
ys = [QQ.convert(i) for i in ys]

p1 = expand(interpolating_poly(len(xs),x,X=xs,Y=ys)).as_poly()
display(p1)

p2 = interpolate( [(xs[i],ys[i]) for i in range(len(xs))],x).as_poly()
display(p2)

输出:

enter image description here


当给定来自 python 函数的点列表时,我试图找到 sigmoid 函数

由于 sigmoid functions 有多种类型,我会选择 logistic function,因为 heinwol 在评论中也提到了它。可以在SymPy中定义函数的一般形式,使用Scipy进行曲线拟合,然后替换函数中找到的系数,然后绘制它看是否与输入数据点匹配。

import numpy as np
from sympy import *
from scipy.optimize import curve_fit
from sympy.utilities.lambdify import lambdify
import matplotlib.pyplot as plt

x = Symbol("x")
xs = [0,.378]

L,k,x0,x = symbols('L k x_0 x')
f = L/(1+(exp(-k*(x-x0))))
display(f)

syms = list(f.free_symbols)
syms.remove(x)
syms.insert(0,x)
py_f = lambdify(syms,f)

popt,pcov = curve_fit(py_f,xs,ys,maxfev = 4 * (10**5))

syms.pop(0)
subs_arg = dict(list(zip(syms,popt)))

f1 = f.subs(subs_arg)
display(f1)

f2 = lambdify([x],f1)

# plot input data points
plt.scatter(np.array(xs),np.array(ys),color="red")

# plot fitted function
xp = np.arange(min(xs),max(xs)+1,0.05)
yp = f2(xp)
plt.plot(xp,yp,color="blue")
plt.show()

输出:

enter image description here

这篇文章中的所有代码也都可用 in this repo


那么有没有什么办法可以找到词项最少的函数?

这是可以解释和模棱两可的。多种类型的 sigmoid functions 不仅仅具有多个术语的特征。或许可以写下此类函数的目录,提出您自己的度量标准来区分哪个更简单,然后对每个函数进行拟合,最后决定哪个更合适。