【问题标题】:Conditional curve fit with scipy?条件曲线与scipy拟合?
【发布时间】:2018-06-02 05:09:28
【问题描述】:

假设我想用一条直线拟合我在熄灯时记录的数据。现在我不小心把灯开着了,我的数据与数据点 101 及以后有一个恒定的偏移量。

我怎样才能适应这个?我试图为 x 合并一个条件,但我得到了错误

ValueError:具有多个元素的数组的真值是 模糊的。使用 a.any() 或 a.all()

记得取消注释其余代码(遇到错误)。

import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt

d1 = np.random.normal(0,0.1, 100)
d2 = np.random.normal(3,0.1, 100)

x = np.arange(0,200)
y = np.concatenate((d1,d2))

plt.plot(x, y)

# def line(x, a, b, offset):
#     if x < 101:
#         y = a * x + b
#     else:
#         y = (a * x + b) + offset
#     return y
# 
# popt, pcov = optimize.curve_fit(line, xdata = x, ydata = y)
# 
# plt.plot(x, line(x, *popt), color = "firebrick")
plt.show()

预期输出:

【问题讨论】:

  • 虽然 Pavel 的把戏可能在这里奏效。小心更复杂的优化模型。该技巧使那些求解器的(恕我直言)假设无效。另一种方法是使用手动曲线拟合的外部 minimize_scalar 循环(手动,因为使用curve_fit的API修复参数不是很好)内部计算,其中偏移量得到固定。
  • 除此之外,我还尝试将两个完全不同的函数合二为一,并带有 x 的条件,例如return f(x) * (x =&gt; z) + g(x) * (x &lt; z),所有参数的错误结果都是 +/- 无穷大。所以你是完全正确的! :)

标签: python scipy curve-fitting


【解决方案1】:

我认为标准技巧是将布尔条件转换为整数因子:

def line(x, a, b, offset):
    return (a * x + b) + offset * (x>100)

【讨论】:

  • 非常有用的技巧!如果添加为具有自己的布尔值的新术语,它可以轻松地同时处理多个偏移常数,用于不同的范围。
【解决方案2】:

您收到该错误的原因是 optimize 正在调用您的 line 函数,方法是向其传递 array 的值,而不仅仅是单个值。要解决此问题,您的 line 函数必须能够处理一组值。幸运的是,numpy 有一个功能可以帮助您。

def line(x, a, b, offset):
    return np.piecewise(x, 
                        [x < 101, x >= 101],
                        [lambda x: a * x + b, lambda x: a * x + b + offset])

我应该注意到它仍然没有收敛,但这是一个不同的问题。

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 2014-12-02
    • 2018-11-20
    • 1970-01-01
    • 2020-05-05
    • 2013-10-10
    • 1970-01-01
    • 2021-11-01
    • 2016-11-29
    相关资源
    最近更新 更多