首页 > 解决方案 > 如何找到包含一组给定点的函数?

问题描述

如果我有一组点,我怎样才能找到适合它的函数?我看了看这里,它工作得很好,直到我尝试了一个更复杂的功能。当给出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))。提前致谢!

标签: pythonfunctionmathregressionsympy

解决方案


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

是的,您可以像这样使用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)

输出:

在此处输入图像描述


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

由于sigmoid 函数有多种类型,我将选择逻辑函数,因为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, -1, 1, .5, -.5]
ys = [.5, .269, .731, .622, .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()

输出:

在此处输入图像描述

这篇文章中的所有代码也可以在这个 repo中找到。


那么有什么方法可以找到具有最少术语的函数吗?

这是开放的解释和模棱两可。多种类型的sigmoid 函数的特征不仅仅在于许多术语。可能可以写下这些函数的目录,提出自己的指标来区分哪个更简单,然后对它们中的每一个进行拟合,最后决定哪一个更合适。


推荐阅读