scipy Python -在csv数据中查找最小化误差的系数

qc6wkl3g  于 2022-11-10  发布在  Python
关注(0)|答案(2)|浏览(145)

我最近遇到了一个问题。我的数据如下所示:
| 数值1|数值2|目标值|
| - -|- -|- -|
| 小行星1345|小行星4590|二点四五|
| 小行星1278|小行星3567|二点四八分|
| 小行星1378|小行星4890|二点四六分|
| 小行星1589|小行星4987|二点五十|
| 一个人。|一个人。|一个人。|
数据持续了几千行。
我需要找到两个值(A和B),当数据输入时,这两个值可以使误差最小化,如下所示:
Value 1 * A + Value 2 * B = Target
我已经研究过scipy. optimiz.curve_fit,但是我似乎不明白它是如何工作的,因为函数在数据的每次迭代中都会改变(因为Value 1和Value 2在每行中并不相同)。
任何帮助都是非常感谢的,提前感谢!

8ehkhllq

8ehkhllq1#

函数curve_fit有3个参数:

  • 一个函数f,它接受一个 input 参数,我们将其命名为X,参数为params(数量不限)
  • 数据集中的 inputX_data
  • 数据集中的 * 输出 * Y_data

这个函数的重点是给予你最好的params输入到f(X_data, params)得到Y_data
直观上,函数f的形式X是一个简单的一维数组,但实际上它可以有你想要的形式。这里你输入的是一个由两个一维数组组成的元组(或者一个二维数组,如果你想这样实现它的话)。
下面是一个代码示例:

import numpy as np 
from scipy.optimize import curve_fit

X_data = (np.array([1345,1278,1378,1589]),
          np.array([4590,3567,4890,4987]))
Y_data = np.array([2.45,2.48,2.46,2.50])

def my_func(X, A, B):
    x1, x2 = X
    return A*x1 + B*x2

(A, B), _ = curve_fit(my_func, X_data, Y_data)

interpolated_results = my_func(X_data, A, B)
relative_error_in_percent = abs((Y_data - interpolated_results)/Y_data)*100
print(relative_error_in_percent)
7kjnsjlb

7kjnsjlb2#

不幸的是,您没有提供任何测试数据,因此我提出了自己的测试数据:

import pandas as pd
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt

def f(V1,V2,A,B): #Target function
    return V1*A+V2*B

# Generate Test-Data

def generateData(A,B): 
    np.random.seed(0)
    V1=np.random.uniform(low=1000, high=1500, size=(100,))
    V2=np.random.uniform(low=3500, high=5000, size=(100,))
    Target=f(V1,V2,A,B) +np.random.normal(0,1,100)
    return V1,V2,Target
data=generateData(2,3) #Important: 
data={"Value 1":data[0], "Value 2":data[1], "Target":data[2]}
df=pd.DataFrame(data) #Similar structure as given in Table

df.head()看起来像这样:

Value 1 Value 2 Target
0   1292.0525763109854  3662.162080896163   13570.276523473405
1   1155.0421489258965  4907.133274663096   17033.392287295104
2   1430.7172112685223  4844.422515098364   17395.412651006143
3   1396.0480757043242  4076.5845114488666  15022.720636830541
4   1346.2120476329646  3570.9567326419674  13406.565815022896

您的问题的答案如下:


## Plot Data to check whether linear function is useful

df.head()
fig=plt.figure()
ax1=fig.add_subplot(211)
ax2=fig.add_subplot(212)
ax1.scatter(df["Value 1"], df["Target"])
ax2.scatter(df["Value 2"], df["Target"])

def fmin(x, df): #Returns Error at given parameters
    def RMSE(y,y_target): #Definition for error term 
        return np.sqrt(np.mean((y-y_target)**2))
    A,B=x
    V1,V2,y_target=df["Value 1"], df["Value 2"], df["Target"]
    y=f(V1,V2,A,B) #Calculate target value with given parameter set
    return RMSE(y,y_target)

res=minimize(fmin,x0=[1,1],args=df, options={"disp":True})
print(res.x)

我更喜欢scipy.optimize.minimize()而不是curve_fit,因为你可以自己定义错误函数。文档可以在here中找到。你需要:

  • 函数fun,返回给定参数集x的误差(此处为fmin和RMSE)
  • 初始猜测x0(这里是[1,1]),如果你的猜测完全错误,你可能找不到解决方案,或者(对于更复杂的问题)只是局部的一个
  • 提供给fun的附加自变量args这里的数据df对固定参数也有帮助
  • options={"disp":True}用于打印附加信息
  • 除了返回的变量res中的详细信息外,还可以找到参数

对于这种情况,结果为:

[1.9987209 3.0004212]

类似于生成数据时给定的参数。

相关问题