首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python中的最小二乘法?

python中的最小二乘法?
EN

Stack Overflow用户
提问于 2017-04-26 01:09:37
回答 2查看 32.4K关注 0票数 5

我有这些值:

代码语言:javascript
复制
T_values = (222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259) (x values)
代码语言:javascript
复制
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)

我知道他们遵循这样的模式:

代码语言:javascript
复制
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中的最小二乘法来解决这个问题,但是我真的不太明白它是如何工作的。有谁可以帮我?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-26 09:38:08

此答案提供了使用Python为一般指数模式确定拟合参数的演练。另请参阅linearization techniques和使用lmfit库的相关文章。

数据清理

首先,让我们以numpy数组的形式输入和组织采样数据,这将有助于稍后的计算和清晰度。

代码语言:javascript
复制
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    

在scipy和curve fitting中有许多numpy函数,每个函数的用法都不同,例如scipy.optimize.leastsqscipy.optimize.least_squares。为简单起见,我们将使用scipy.optimize.curve_fit,但如果没有选择合理的起始参数,则很难找到优化的回归曲线。稍后将演示一种选择启动参数的简单技术。

回顾

首先,尽管OP提供了预期的拟合方程,但我们将通过查看指数函数的一般方程来解决使用Python进行曲线拟合的问题:

现在我们构建这个通用函数,它将被使用几次:

代码语言:javascript
复制
# GENERAL EQUATION ------------------------------------------------------------
def func(x, A, c, d):
    return A*np.exp(c*x) + d

趋势

负振幅:一个小的膝部给一个小的amplitude

  • shape:一个小的膝部通过展平curve

  • position:的“A”来控制形状d设置一个负值A将曲线反转到水平轴上;负值c将曲线反转到垂直轴上

后一种趋势如下所示,与具有不同参数的线(红线)相比,突出显示了控件(黑线):

选择初始参数

使用后一种趋势,让我们接下来查看数据,并尝试通过调整这些参数来模拟曲线。为了演示,我们根据我们的数据绘制了几个试验方程:

代码语言:javascript
复制
# 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()

通过简单的试错,我们可以更好地近似曲线的形状、振幅、位置和方向。例如,我们知道前两个参数(Ac)必须为负。我们对c的数量级也有一个合理的猜测。

计算估计参数

现在,我们将使用最佳试验的参数进行初始猜测:

代码语言:javascript
复制
# 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的最后一个练习)。

票数 16
EN

Stack Overflow用户

发布于 2017-04-26 01:15:28

您想要使用scipy

代码语言:javascript
复制
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])      
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43616993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档