我希望最小化一组方程,其中变量是已知的,具有不确定性。本质上,我想测试一个假设,即给定的测量变量符合方程给出的公式约束。这似乎是我应该能够用scipy-optimize做的事情。例如,我有三个方程式:
8 = 0.5 * x1 + 1.0 * x2 + 1.5 * x3 + 2.0 * x4
4 = 0.0 * x1 + 0.0 * x2 + 1.0 * x3 + 1.0 * x4
1 = 1.0 * x1 + 1.0 * x2 + 0.0 * x3 + 0.0 * x4
四个测量未知数的1-sigma不确定性:
x1 = 0.246 ± 0.007
x2 = 0.749 ± 0.010
x3 = 1.738 ± 0.009
x4 = 2.248 ± 0.007
寻找正确方向的任何指针。
答案 0 :(得分:4)
这是我的方法。假设x1-x4
近似正态分布在每个均值周围(1-sigma不确定性),问题变成了最小化误差平方和的问题,具有3个线性约束函数。因此,我们可以使用scipy.optimize.fmin_slsqp()
In [19]:
def eq_f1(x):
return (x*np.array([0.5, 1.0, 1.5, 2.0])).sum()-8
def eq_f2(x):
return (x*np.array([0.0, 0.0, 1.0, 1.0])).sum()-4
def eq_f3(x):
return (x*np.array([1.0, 1.0, 0.0, 0.0])).sum()-1
def error_f(x):
error=(x-np.array([0.246, 0.749, 1.738, 2.248]))/np.array([0.007, 0.010, 0.009, 0.007])
return (error*error).sum()
In [20]:
so.fmin_slsqp(error_f, np.array([0.246, 0.749, 1.738, 2.248]), eqcons=[eq_f1, eq_f2, eq_f3])
Optimization terminated successfully. (Exit mode 0)
Current function value: 2.17576389592
Iterations: 4
Function evaluations: 32
Gradient evaluations: 4
Out[20]:
array([ 0.25056582, 0.74943418, 1.74943418, 2.25056582])
答案 1 :(得分:0)
我觉得我有一个非常相似的问题。我对py比较陌生,主要用于对大熊猫进行排序和减少数据。
我有一组线性方程,我想在其中找到最合适的参数。但是,该数据集具有已知的不确定性,需要考虑在括号中给出)。
x1*99(1)+x2*45(1)=52(0.2)
x1*1(0.5)+x2*16(1)=15(0.1)
此外,还有一些约束条件:
x1>=0
x2>=0
x1+x2=1
我的方法是将等式视为约束,并求解残差之和,如上例所示。
毫无疑问地解决这个问题不是问题。我希望在寻找最佳拟合参数时获得有关如何解决不确定性的提示。
答案 2 :(得分:0)
正如所给的,问题没有解决的办法。这是因为如果输入x1,x2,x3和x4是高斯,则输出:
y1 = 0.5 * x1 + 1.0 * x2 + 1.5 * x3 + 2.0 * x4 - 8.0
y2 = 0.0 * x1 + 0.0 * x2 + 1.0 * x3 + 1.0 * x4 - 4.0
y3 = 1.0 * x1 + 1.0 * x2 + 0.0 * x3 + 0.0 * x4 - 1.0
也是高斯的。 假设x1,x2,x3和x4是独立的随机变量,使用OpenTURNS可以很容易地看出这一点:
import openturns as ot
x1 = ot.Normal(0.246, 0.007)
x2 = ot.Normal(0.749, 0.010)
x3 = ot.Normal(1.738, 0.009)
x4 = ot.Normal(2.248, 0.007)
y1 = 0.5 * x1 + 1.0 * x2 + 1.5 * x3 + 2.0 * x4 - 8.0
y2 = 0.0 * x1 + 0.0 * x2 + 1.0 * x3 + 1.0 * x4 - 4.0
y3 = 1.0 * x1 + 1.0 * x2 + 0.0 * x3 + 0.0 * x4 - 1.0
以下脚本生成图形:
graph1 = y1.drawPDF()
graph1.setLegends(["y1"])
graph2 = y2.drawPDF()
graph2.setLegends(["y2"])
graph3 = y3.drawPDF()
graph3.setLegends(["y3"])
graph1.add(graph2)
graph1.add(graph3)
graph1.setColors(["dodgerblue3",
"darkorange1",
"forestgreen"])
graph1.setXTitle("Y")
上一个脚本产生以下输出。
鉴于此分布中0.0的位置,我想说在数学上不可能求解方程,但在物理上与数据一致。
实际上,我想您为x1,...,x4给出的高斯分布是根据数据估算的。所以我宁愿将问题改写如下:
给出一个观测值x1,x2,x3,x4的样本,那么e1,e2,e3的值是多少?
y1 = 0.5 * x1 + 1.0 * x2 + 1.5 * x3 + 2.0 * x4 - 8 + e1 = 0
y2 = 0.0 * x1 + 0.0 * x2 + 1.0 * x3 + 1.0 * x4 - 4 + e2 = 0
y3 = 1.0 * x1 + 1.0 * x2 + 0.0 * x3 + 0.0 * x4 - 1 + e3 = 0
这将问题变成反问题,可以通过校准e1,e2,e3来解决。此外,给定x1,...,x4的有限样本大小,我们可能要生成e1,e2,e3的分布。这可以通过引导输入/输出对(x,y)来完成:e1,e2,e3的分布然后反映了这些参数随手头样品的可变性。
首先,我们必须从分发中生成一个样本(我想您已经有这个样本,但是到目前为止尚未发布):
distribution = ot.ComposedDistribution([x1, x2, x3, x4])
sampleSize = 10
xobs = distribution.getSample(sampleSize)
然后我们定义模型:
formulas = [
"y1 := 0.5 * x1 + 1.0 * x2 + 1.5 * x3 + 2.0 * x4 + e1 - 8.0",
"y2 := 0.0 * x1 + 0.0 * x2 + 1.0 * x3 + 1.0 * x4 + e2 - 4.0",
"y3 := 1.0 * x1 + 1.0 * x2 + 0.0 * x3 + 0.0 * x4 + e3 - 1.0"
]
program = ";".join(formulas)
g = ot.SymbolicFunction(["x1", "x2", "x3", "x4", "e1", "e2", "e3"],
["y1", "y2", "y3"],
program)
并设置观察到的输出,它是零的样本:
yobs = ot.Sample(sampleSize, 3)
我们从等于零的初始值开始,然后定义要校准的函数:
e1Initial = 0.0
e2Initial = 0.0
e3Initial = 0.0
thetaPrior = ot.Point([e1Initial,e2Initial,e3Initial])
calibratedIndices = [4, 5, 6]
mycf = ot.ParametricFunction(g, calibratedIndices, thetaPrior)
然后我们可以校准模型:
algo = ot.NonLinearLeastSquaresCalibration(mycf, xobs, yobs, thetaPrior)
algo.run()
calibrationResult = algo.getResult()
print(calibrationResult.getParameterMAP())
此打印:
[0.0265988,0.0153057,0.00495758]
这意味着错误e1,e2,e3很小。 我们可以计算出置信区间:
thetaPosterior = calibrationResult.getParameterPosterior()
print(thetaPosterior.computeBilateralConfidenceIntervalWithMarginalProbability(0.95)[0])
此打印:
[0.0110046, 0.0404756]
[0.00921992, 0.0210059]
[-0.00601084, 0.0156665]
第三个参数e3可能为零,但e1和e2都不为零。 最后,我们可以获得错误的分布:
thetaPosterior = calibrationResult.getParameterPosterior()
并绘制:
graph1 = thetaPosterior.getMarginal(0).drawPDF()
graph2 = thetaPosterior.getMarginal(1).drawPDF()
graph3 = thetaPosterior.getMarginal(2).drawPDF()
graph1.add(graph2)
graph1.add(graph3)
graph1.setColors(["dodgerblue3",
"darkorange1",
"forestgreen"])
graph1
这将产生:
这表明给定观测输入x1,...,x4的可变性,e3可能为零。但是e1和e2不能为零。该样本的结论是,第三个方程近似地由观测值x1,...,x4求解,但不是两个第一个方程。