python 中的最小二乘法?
Least square method in python?
我有这些价值观:
T_values = (222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259) (x values)
C/(3Nk)_values = (0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316) (y values)
我知道他们遵循以下模型:
C/(3Nk)=(h*w/(k*T))**2*(exp(h*w/(k*T)))/(exp(h*w/(k*T)-1))**2
我也知道k=1.38*10**(-23)
和h=6.626*10**(-34)
。
我必须找到最能描述测量数据的 w。我想使用 python 中的最小二乘法来解决这个问题,但我不太明白这是如何工作的。谁能帮帮我?
您想使用 scipy
:
import scipy.optimize.curve_fit
def my_model(T,w):
return (hw/(kT))**2*(exp(hw/(kT)))/(exp(hw/(kT)-1))**2
w= 0 #initial guess
popt, pcov = curve_fit(my_model, T_values, C_values,p0=[w])
此答案提供了使用 Python 确定一般指数模式的拟合参数的演练。另请参阅 linearization techniques and using the lmfit
库中的相关帖子。
数据清理
首先,让我们将采样数据输入并组织为 numpy 数组,这将有助于稍后的计算和清晰度。
import matplotlib.pyplot as plt
import scipy.optimize as opt
import numpy as np
#% matplotlib inline
# DATA ------------------------------------------------------------------------
T_values = np.array([222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259])
C_values = np.array([0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316])
x_samp = T_values
y_samp = C_values
有很多curve fitting functions in scipy and numpy and each is used differently, e.g. scipy.optimize.leastsq
and scipy.optimize.least_squares
. For simplicity, we will use scipy.optimize.curve_fit
,但如果不选择合理的起始参数,很难找到优化的回归曲线。稍后将在选择起始参数时演示一种简单的技术。
评论
首先,虽然 OP 提供了预期的拟合方程,但我们将通过回顾指数函数的一般方程来解决使用 Python 进行曲线拟合的问题:
现在我们构建这个通用函数,会用到几次:
# GENERAL EQUATION ------------------------------------------------------------
def func(x, A, c, d):
return A*np.exp(c*x) + d
趋势
- 振幅:小
A
给出小振幅
- shape: 一个小的
c
通过压平曲线的“拐点”来控制形状
- 位置:
d
设置 y 截距
- 方向:负数
A
使曲线沿水平轴翻转;负值 c
翻转垂直轴上的曲线
后面的趋势如下图所示,突出显示了对照(黑线)与具有不同参数的线(红线)的比较:
选择初始参数
使用后面的趋势,让我们接下来查看数据并尝试通过调整这些参数来模拟曲线。为了演示,我们根据数据绘制了几个试验方程:
# SURVEY ----------------------------------------------------------------------
# Plotting Sampling Data
plt.plot(x_samp, y_samp, "ko", label="Data")
x_lin = np.linspace(0, x_samp.max(), 50) # a number line, 50 evenly spaced digits between 0 and max
# Trials
A, c, d = -1, -1e-2, 1
y_trial1 = func(x_lin, A, c, d)
y_trial2 = func(x_lin, -1, -1e-3, 1)
y_trial3 = func(x_lin, -1, -3e-3, 1)
plt.plot(x_lin, y_trial1, "--", label="Trial 1")
plt.plot(x_lin, y_trial2, "--", label="Trial 2")
plt.plot(x_lin, y_trial3, "--", label="Trial 3")
plt.legend()
通过简单的试错,我们可以更好地近似曲线的形状、幅度、位置和方向。例如,我们知道前两个参数(A
和 c
)必须为负数。我们对 c
.
的数量级也有一个合理的猜测
计算估计参数
我们现在将使用最佳试验的参数进行初始猜测:
# REGRESSION ------------------------------------------------------------------
p0 = [-1, -3e-3, 1] # guessed params
w, _ = opt.curve_fit(func, x_samp, y_samp, p0=p0)
print("Estimated Parameters", w)
# Model
y_model = func(x_lin, *w)
# PLOT ------------------------------------------------------------------------
# Visualize data and fitted curves
plt.plot(x_samp, y_samp, "ko", label="Data")
plt.plot(x_lin, y_model, "k--", label="Fit")
plt.title("Least squares regression")
plt.legend(loc="upper left")
# Estimated Parameters [-1.66301087 -0.0026884 1.00995394]
这是如何工作的?
curve_fit
是 scipy 提供的众多 optimization functions 之一。给定一个初始值,得到的估计参数被迭代地细化,使得得到的曲线最小化残差,或者拟合线和采样数据之间的差异。更好的猜测减少了迭代次数并加快了结果的速度。有了这些拟合曲线的估计参数,现在可以计算特定方程的特定系数(留给 OP 的最后练习)。
我有这些价值观:
T_values = (222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259) (x values)
C/(3Nk)_values = (0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316) (y values)
我知道他们遵循以下模型:
C/(3Nk)=(h*w/(k*T))**2*(exp(h*w/(k*T)))/(exp(h*w/(k*T)-1))**2
我也知道k=1.38*10**(-23)
和h=6.626*10**(-34)
。
我必须找到最能描述测量数据的 w。我想使用 python 中的最小二乘法来解决这个问题,但我不太明白这是如何工作的。谁能帮帮我?
您想使用 scipy
:
import scipy.optimize.curve_fit
def my_model(T,w):
return (hw/(kT))**2*(exp(hw/(kT)))/(exp(hw/(kT)-1))**2
w= 0 #initial guess
popt, pcov = curve_fit(my_model, T_values, C_values,p0=[w])
此答案提供了使用 Python 确定一般指数模式的拟合参数的演练。另请参阅 linearization techniques and using the lmfit
库中的相关帖子。
数据清理
首先,让我们将采样数据输入并组织为 numpy 数组,这将有助于稍后的计算和清晰度。
import matplotlib.pyplot as plt
import scipy.optimize as opt
import numpy as np
#% matplotlib inline
# DATA ------------------------------------------------------------------------
T_values = np.array([222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259])
C_values = np.array([0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316])
x_samp = T_values
y_samp = C_values
有很多curve fitting functions in scipy and numpy and each is used differently, e.g. scipy.optimize.leastsq
and scipy.optimize.least_squares
. For simplicity, we will use scipy.optimize.curve_fit
,但如果不选择合理的起始参数,很难找到优化的回归曲线。稍后将在选择起始参数时演示一种简单的技术。
评论
首先,虽然 OP 提供了预期的拟合方程,但我们将通过回顾指数函数的一般方程来解决使用 Python 进行曲线拟合的问题:
现在我们构建这个通用函数,会用到几次:
# GENERAL EQUATION ------------------------------------------------------------
def func(x, A, c, d):
return A*np.exp(c*x) + d
趋势
- 振幅:小
A
给出小振幅 - shape: 一个小的
c
通过压平曲线的“拐点”来控制形状 - 位置:
d
设置 y 截距 - 方向:负数
A
使曲线沿水平轴翻转;负值c
翻转垂直轴上的曲线
后面的趋势如下图所示,突出显示了对照(黑线)与具有不同参数的线(红线)的比较:
选择初始参数
使用后面的趋势,让我们接下来查看数据并尝试通过调整这些参数来模拟曲线。为了演示,我们根据数据绘制了几个试验方程:
# SURVEY ----------------------------------------------------------------------
# Plotting Sampling Data
plt.plot(x_samp, y_samp, "ko", label="Data")
x_lin = np.linspace(0, x_samp.max(), 50) # a number line, 50 evenly spaced digits between 0 and max
# Trials
A, c, d = -1, -1e-2, 1
y_trial1 = func(x_lin, A, c, d)
y_trial2 = func(x_lin, -1, -1e-3, 1)
y_trial3 = func(x_lin, -1, -3e-3, 1)
plt.plot(x_lin, y_trial1, "--", label="Trial 1")
plt.plot(x_lin, y_trial2, "--", label="Trial 2")
plt.plot(x_lin, y_trial3, "--", label="Trial 3")
plt.legend()
通过简单的试错,我们可以更好地近似曲线的形状、幅度、位置和方向。例如,我们知道前两个参数(A
和 c
)必须为负数。我们对 c
.
计算估计参数
我们现在将使用最佳试验的参数进行初始猜测:
# REGRESSION ------------------------------------------------------------------
p0 = [-1, -3e-3, 1] # guessed params
w, _ = opt.curve_fit(func, x_samp, y_samp, p0=p0)
print("Estimated Parameters", w)
# Model
y_model = func(x_lin, *w)
# PLOT ------------------------------------------------------------------------
# Visualize data and fitted curves
plt.plot(x_samp, y_samp, "ko", label="Data")
plt.plot(x_lin, y_model, "k--", label="Fit")
plt.title("Least squares regression")
plt.legend(loc="upper left")
# Estimated Parameters [-1.66301087 -0.0026884 1.00995394]
这是如何工作的?
curve_fit
是 scipy 提供的众多 optimization functions 之一。给定一个初始值,得到的估计参数被迭代地细化,使得得到的曲线最小化残差,或者拟合线和采样数据之间的差异。更好的猜测减少了迭代次数并加快了结果的速度。有了这些拟合曲线的估计参数,现在可以计算特定方程的特定系数(留给 OP 的最后练习)。