【问题标题】:Plotting horizontal hyperbola/circle using fsolve, numpy, and matplotlib使用 fsolve、numpy 和 matplotlib 绘制水平双曲线/圆
【发布时间】:2018-02-01 05:44:16
【问题描述】:

我最近试图绘制一个非线性决策边界,该函数最终成为一个部分水平的双曲线,其中给定 x 有多个 y 值。虽然我让它工作了,但我知道必须有一种更 Pythonic 或 numpythonic 的方式来绘制这条线。

背景:问题在于感知器分类器对一组不可线性分离的输入进行分类。为了找到这一点,输入被映射到一个通用的双曲线函数以将维数增加到 5,并通过超平面将它们分开。将绘制的决策边界方程为 d(x) = w0 + w1xx + w2yy + w3xy + wx + w5y 通过感知器的梯度下降过程,找到了 w0-w5 的值,边界是 d(x)=0 时的 x,y 值。

当前的实现:我得到了它的工作,但我认为它是 hacky。我首先必须创建一个给定大小的数组,以便可以附加这些值,并且我必须在第一次附加找到的值时删除初始化值。然后我扫过我图表上的空间并找到一个 y 值,首先通过猜测高,然后通过猜测低,以便找到两个可能的 y 值。我将这些找到的值放在 D 的前面和后面,以便使用 matplotlib 绘制它。

D = np.array([[0], [0]])
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
a_iter, b_iter = 0, 0   # used as initial guess for numeric solver
for xx in range(x_min, x_max):
    # used to print top and bottom sides of hyperbola
    yya = fsolve(lambda yy: W[:,0] + W[:,1]*xx**2 + W[:,2]*yy**2 + W[:,3]*xx*yy + W[:,4]*xx + W[:,5]*yy, max(a_iter, 7))
    yyb = fsolve(lambda yy: W[:,0] + W[:,1]*xx**2 + W[:,2]*yy**2 + W[:,3]*xx*yy + W[:,4]*xx + W[:,5]*yy, b_iter)
    a_iter = yya
    b_iter = yyb
    # add these points to a single matrix for printing
    dda = np.array([[xx],[yya]])
    ddb = np.array([[xx],[yyb]])
    D = np.concatenate((dda, D), axis=1)
    if xx == x_min: # delete initial [0; 0]
        D = dda
    D = np.concatenate((D, ddb), axis=1)

我知道必须有更好的方法来做到这一点。任何见解都值得赞赏。

编辑:抱歉,我意识到如果没有图片,这真的很难理解。查找多个根和填充 numpy 数组的主要问题有点通用。我没有足够的代表来发布图片,但链接在下面 nonlinear classifier

【问题讨论】:

  • 我知道您对这个主题非常深入,但其他大多数人都不是。所以请把自己放在最后几天没有花在分类问题上的人的位置上——他们会理解你的问题吗?我猜不是。因此,审查它并清楚地说明实际问题是有意义的。还要使问题可重现,使用minimal reproducible example 并显示代码的输出。可能使用数据图来解释问题。
  • 如果你有分析解决方案,究竟是什么让你绊倒了?

标签: python numpy matplotlib plot


【解决方案1】:

如果你想绘制一个隐式方程曲线,你可以使用pyplot.contour(),这里是一个例子:

np.random.seed(1)
w = np.random.randn(6)

def f(x, y, w):
    return w[0] + w[1]*x**2 + w[2]*y**2 + w[3]*x*y + w[4]*x + w[5]*y

X, Y = np.mgrid[-2:2:100j, -2:2:100j]

pl.contour(X, Y, f(X, Y, w), levels=[0])

【讨论】:

  • 我的 "python 绘图分支双曲线" 搜索顶部:blog.mmast.net/conics-matplotlib 滚动到底部
  • 我错过了该查询的“分支”部分。我的 google-fu 让我失望了。 pyplot.countour 似乎比我做这一切的方式更好
【解决方案2】:

也有参数化选项 - 一个三角,以 0 为中心的分支,pi

t = np.linspace(-np.pi/3, np.pi/3, 200)  # 0 centered branch

y = 1/np.cos(t) 
x = 1*np.tan(t)
plt.plot(x, y)  # (default blue)
Out[94]: [<matplotlib.lines.Line2D at 0xe26e6a0>]

t = np.linspace(np.pi-np.pi/3, np.pi+np.pi/3, 200)  # pi centered branch

y = 1/np.cos(t) 
x = 1*np.tan(t)
plt.plot(x, y)  # (default orange)
Out[96]: [<matplotlib.lines.Line2D at 0xf68e780>]   

sympy 应该能够从二元多项式ws 中找到完整的非归一化、旋转、偏移参数化双曲线系数 (或继续进行黑客攻击)

【讨论】: