减少校准中的测量次数
Posted
技术标签:
【中文标题】减少校准中的测量次数【英文标题】:Reduce Number of Measurements in Calibration 【发布时间】:2020-01-11 23:51:55 【问题描述】:出于校准目的,我对水流进行了 N 次测量,每次测量都非常耗时。我想减少测量次数。听起来这是功能选择的一部分,因为我正在减少我拥有的列数。但是 - 我需要预测我将要放弃的测量值。
以下是数据示例:
SerialNumber val speed
0 193604048 1.350254 105.0
1 193604048 1.507517 3125.0
2 193604048 1.455142 525.0
6 193604048 1.211184 12.8
7 193604048 1.238835 20.0
对于每个序列号,我都有一套完整的速度验证测量值。理想情况下,我想要一个模型,其输出是所有 N val 测量的向量,但似乎选项都是神经网络,我现在试图避免。还有其他选择吗?
如果我将此数据输入回归模型,如何区分每个序列号数据集?
为了确保我的目标很明确 - 我想了解我拥有的 N 个测量值的历史测量值,并找到我可以降低哪个速度值以仍然准确地预测所有 N 个输出值。
谢谢!
【问题讨论】:
【参考方案1】:我试图找到最适合您发布的示例数据的最简单方程,并从我的方程中搜索哈里斯产量密度方程,“y = 1.0 / (a + b * pow(x, c) )”,是一个很好的候选。这是使用该方程和您的数据的图形 Python 拟合器,非线性拟合器的初始参数估计值直接从数据最大值和最小值计算。请注意,序列号本身与数据无关,不会用于回归。
我希望你会发现这个方程在你的工作中通常很有用,并且在对几个不同的数据集执行类似的回归之后,参数 a、b 和 c 在所有情况下都非常相似——也就是说最好的结果。如果您的测量精度很高,我个人希望通过这个三参数方程,每次校准至少可以使用四个数据点,其中最大值、最小值和其他两个沿预期校准曲线间隔良好的点。
注意这里拟合的参数 a = -1.91719091e-03。 b = 1.11357103e+00,c = -1.51294798e+01 得出 RMSE = 3.191,R 平方 = 0.9999
import numpy, scipy, matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
xData = numpy.array([1.350254, 1.507517, 1.455142, 1.211184, 1.238835])
yData = numpy.array([105.0, 3125.0, 525.0, 12.8, 20.0])
def func(x, a, b, c): # Harris yield density equation
return 1.0 / (a + b*numpy.power(x, c))
initialParameters = numpy.array([0.0, min(xData), -10.0 * max(xData)])
# curve fit the test data
fittedParameters, pcov = curve_fit(func, xData, yData, initialParameters)
modelPredictions = func(xData, *fittedParameters)
absError = modelPredictions - yData
SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(yData))
print('Parameters:', fittedParameters)
print('RMSE:', RMSE)
print('R-squared:', Rsquared)
print()
##########################################################
# graphics output section
def ModelAndScatterPlot(graphWidth, graphHeight):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
axes = f.add_subplot(111)
# first the raw data as a scatter plot
axes.plot(xData, yData, 'D')
# create data for the fitted equation plot
xModel = numpy.linspace(min(xData), max(xData))
yModel = func(xModel, *fittedParameters)
# now the model as a line plot
axes.plot(xModel, yModel)
axes.set_title('Harris Yield Density Equation') # title
axes.set_xlabel('Val') # X axis data label
axes.set_ylabel('Speed') # Y axis data label
plt.show()
plt.close('all') # clean up after using pyplot
graphWidth = 800
graphHeight = 600
ModelAndScatterPlot(graphWidth, graphHeight)
使用反转的 X 和 Y 更新
根据 cmets,这是一个三参数方程 Mixed Power and Eponential "a * pow(x, b) * exp(c * x)" 图形拟合器,其中 X 和 Y 与之前的代码相反。这里拟合参数 a = 1.05910664e+00、b = 5.26304345e-02 和 -2.25604946e-05 得到 RMSE = 0.0003602 和 R-squared= 0.9999
import numpy, scipy, matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
xData = numpy.array([105.0, 3125.0, 525.0, 12.8, 20.0])
yData = numpy.array([1.350254, 1.507517, 1.455142, 1.211184, 1.238835])
def func(x, a, b, c): # mixed power and exponential equation
return a * numpy.power(x, b) * numpy.exp(c * x)
initialParameters = [1.0, 0.01, -0.01]
# curve fit the test data
fittedParameters, pcov = curve_fit(func, xData, yData, initialParameters)
modelPredictions = func(xData, *fittedParameters)
absError = modelPredictions - yData
SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(yData))
print('Parameters:', fittedParameters)
print('RMSE:', RMSE)
print('R-squared:', Rsquared)
print()
##########################################################
# graphics output section
def ModelAndScatterPlot(graphWidth, graphHeight):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
axes = f.add_subplot(111)
# first the raw data as a scatter plot
axes.plot(xData, yData, 'D')
# create data for the fitted equation plot
xModel = numpy.linspace(min(xData), max(xData))
yModel = func(xModel, *fittedParameters)
# now the model as a line plot
axes.plot(xModel, yModel)
axes.set_title('Mixed Power and Exponential Equation') # title
axes.set_xlabel('Speed') # X axis data label
axes.set_ylabel('Val') # Y axis data label
plt.show()
plt.close('all') # clean up after using pyplot
graphWidth = 800
graphHeight = 600
ModelAndScatterPlot(graphWidth, graphHeight)
【讨论】:
非常感谢您的详细解答!我试过这个并得到一个错误:RuntimeError: Optimal parameters not found: Number of call to function has达到maxfev = 800。另外,我可能不清楚——你的xData真的是yData,y是x。这导致更多的对数函数,而不是幂函数。 Re serialNumber - 我知道它只是一个标识符,但我确实希望能够将它们区分开来。最佳情况下,我将有一个基于 4-5 点的函数/模型,正如您所建议的,使用拟合/模型我可以准确预测其他 9-10 点 请参阅答案的更新部分,了解反向 X 和 Y 钳工。 对迟到的回复表示歉意。非常感谢!!以上是关于减少校准中的测量次数的主要内容,如果未能解决你的问题,请参考以下文章