通过上周的学习,我们在文件夹中生成并储存了一个名称为 MM_data 的 csv文件。在之前线性回归的课程中,我们使用 scipy.stats 库中的 linregress 函数来执行线性回归。这个方法足以对数据进行最小二乘线性的拟合。今天小亚老师将带大家一方面进行一下回顾,通过使用 Python 的数据处理的库,进行数据拟合,并可视化拟合结果,同时将创建一个基于 Michaelis-Menten 方程的函数,学习如何使用 scipy.optimize 中的 curve_fit 将数据拟合到函数,来分析数据是否符合假设模型
首先我们了解一下米氏方程(Michaelis-Menten equation),米氏方程描述了酶催化反应的动力学。我们将使用基于单个底物的初始反应速度的最简单版本的方程。
在我们的方程中,有两个参数,一个是最大速度(Vmax)和米氏常数(Km),自变量 [S] 是底物浓度,因变量 Vi 是初速度。
为了方便起见,我们可以先导入所有要用到的库:
import osimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom scipy.optimize import curve_fit

现在我们输入代码来导入数据:
datafile = os.path.join('data', 'MM_data.csv')rates_df = pd.read_csv(datafile)rates_df
.webp)
我们首先从 DataFrame 中分别提取 initial velocities 和 pNPP (mM) 列,作为自变量和因变量。然后使用 matplotlib 来绘制散点图,展示数据的分布情况。代码如下:
ydata = rates_df['initial velocities']xdata = rates_df['pNPP (mM)']plt.plot(xdata, ydata, 'o', label=‘data')
.webp)
以上步骤各位小伙伴应该是比较熟悉了,如果还不太熟悉,需要及时复习哦。当我们看到数据情况之后,接下来就是要看这些数据是不是与我们的公式拟合。这里需要用到 python 中函数的定义。
Tip:
这里给大家介绍一下函数的概念:函数是使用 def 关键字定义的,后跟函数的名称。该函数可以具有传递给它的自变量和参数;它们位于函数名称后面的括号中。然后在括号后添加冒号。这会导致函数主体代码在 Jupyter 笔记本编码单元中缩进。在某些情况下,函数也可能没有参数。大多数函数返回某种类型的信息。这里需要注意的是,定义函数并不代表它会被立刻执行。
比如接下需要定义 Michaelis-Menten 函数这里我们用缩写MM,我们使用 Python 的 def 关键字来定义这个函数,并使用底物浓度 (SubConc)、最大速度 (Vmax)、米氏常数 (Km) 作为参数。
def MM(SubConc, Vmax, Km):Vi = Vmax * SubConc/(Km + SubConc)return Vi
现在,我们可以使用 rates_df 数据中的底物浓度列,以及假设的 Vmax 和 Km 值来测试这个函数,看看它是否产生预期的输出。
result = MM(rates_df['pNPP (mM)'], 100, 1)result
.webp)
result 变量中将包含基于 pNPP (mM) 列中的底物浓度、假设的 Vmax = 100 和 Km = 1 计算出的初速度。如果一切正常,我们将看到一个与 pNPP (mM) 列具有相同大小的序列,其值对应于使用 Michaelis-Menten 方程计算得出的初速度。
很好,相信大家已经定义好了 Michaelis-Menten 函数。接下来就是需要使用 curve_fit 进行数据拟合。curve_fit 的基本语法如下:
popt, pcov = curve_fit(model_function, xdata, ydata, p0=initial_guesses)1 参数说明:
model_function:你要拟合的数据的函数模型。在这里我们使用刚才定义的 MM 函数。
xdata:自变量数据(例如底物浓度)。
ydata:因变量数据(例如初速度)。
p0(可选):参数的初始猜测值的数组。如果未提供,函数默认使用 1.0 作为所有参数的起始值。
2 获得的返回值:
Popt:最佳拟合参数的数组,这些参数使函数最适合数据。在这里返回的是最佳拟合参数包含Vmax和Km。
pcov:是popt 的协方差估计。对角线提供参数估计的方差,这些值的平方根给出了参数估计的不确定性(标准差)。
在前面的代码中,我们定义了一个用于 Michaelis-Menten 方程的函数 MM,现在我们来使用 scipy.optimize.curve_fit() 来拟合实验数据。
大家可以看到,我们需要将三个数据传递给 MM 函数,分别是:SubConc, Vmax, Km,然后 MM 函数会反馈给我们一个酶催化反应的初始速度(Vi)。然后 curve_fit 将使用实验数据来拟合后 Vmax 和 Km 的最佳估计值,使得 MM 函数的输出(计算出来的初速度)最接近实验数据(ydata)。
popt, pcov = curve_fit(MM, xdata, ydata)print (popt)print (pcov)
.webp)
我们可以将popt中的两个数值提取出来,并且为每个参数提取一个标准差。
Vmax = popt[0]Km = popt[1]stdev = np.sqrt(np.diag(pcov))print('Vmax for this reaction:', Vmax, '+/-', stdev[0])print('Km for this reaction:', Km, '+/-', stdev[1])
.webp)
stdev = np.sqrt(np.diag(pcov)) 这一句代码用来计算参数估计值的标准误差(standard deviation),具体来说,是拟合参数(如 Vmax 和 Km)的标准误差。
让我们一步步解释这句话的含义:
在前面的代码中,我们使用了 curve_fit 函数来拟合数据:popt 是最佳拟合参数的数组(即 Vmax 和 Km)。pcov 是这些参数的协方差矩阵(covariance matrix)。协方差矩阵是统计学中用于描述多个变量之间关系的一个重要工具。在曲线拟合中,它被用来量化参数估计值的不确定性以及参数之间的相关性。这里不再对定义细节深究,感兴趣的小伙伴可以自己进行学习。简单来讲,矩阵的对角线元素表示各参数估计值的方差,非对角线元素表示参数之间的协方差。np.diag(pcov) 是 numpy 的一个函数,用于提取矩阵的对角线元素。在这里,它提取了 pcov 矩阵中的对角线元素,这些元素分别对应 Vmax 和 Km 的方差。np.sqrt 是 numpy 的平方根函数,所以np.sqrt(np.diag(pcov)) 计算了每个参数方差的平方根,得到每个参数的标准误差(standard deviation)。
我们可以让数据显示的更加直观一些
fit_y = MM(xdata, Vmax, Km)plt.plot(xdata, ydata, 'o', label='data')plt.plot(xdata, fit_y, '-', label='fit')
.webp)
每一行的详细解释:
fit_y = MM(xdata, Vmax, Km)这一行代码使用先前定义的米氏方程(Michaelis-Menten equation)MM来计算拟合曲线上的点。xdata 是底物浓度的数组。Vmax 和 Km 是通过曲线拟合得到的参数。fit_y 是一个数组,包含了根据拟合参数计算得到的反应速率值(即 Vi = Vmax * SubConc / (Km + SubConc))。这些值是根据输入的 xdata 和拟合出的 Vmax、Km 计算得出的,代表拟合曲线上的点。
plt.plot(xdata, ydata, 'o', label='data')这一行代码用于绘制实验数据。
plt.plot() 是 matplotlib 中用于绘制图形的函数。xdata 是底物浓度的数据,ydata 是对应的初始反应速率。'o' 指定使用圆点来表示数据点。这些圆点会出现在图上,用于标记实验数据。label='data' 为这一系列数据点添加了图例标签,图例在图形中可以帮助我们区分数据点和拟合曲线。
plt.plot(xdata, fit_y, '-', label='fit')这一行代码用于绘制拟合曲线。
xdata 是底物浓度的数据,fit_y 是根据拟合参数计算得到的反应速率(在第一行代码中计算)。'-' 指定使用实线来表示拟合曲线。label='fit' 为拟合曲线添加了图例标签,图例在图形中可以帮助我们区分拟合曲线和实验数据点。
我们也可以生成更平滑的拟合曲线
smooth_x = np.linspace(np.min(xdata), np.max(xdata), 1000)smooth_y = MM(smooth_x, Vmax, Km)plt.plot(xdata, ydata, 'bo', label='data')plt.plot(smooth_x, smooth_y, 'r', label = 'fit')plt.legend()
.webp)
每一行的详细解释:
smooth_x = np.linspace(np.min(xdata), np.max(xdata), 1000)np.linspace(np.min(xdata), np.max(xdata), 1000) 生成了一个包含 1000 个点的数组 smooth_x,这些点均匀分布在 xdata 的最小值和最大值之间。这使得我们在拟合曲线绘制时有了更多的点,从而得到一条更平滑、更连续的曲线。
smooth_y = MM(smooth_x, Vmax, Km)使用先前定义的米氏方程 MM 计算 smooth_x 对应的 y 值,即反应速率 smooth_y。
由于 smooth_x 包含了更多点,smooth_y 也会有更多的对应值,这为绘制平滑的拟合曲线做好了准备。
plt.plot(xdata, ydata, 'bo', label='data')使用蓝色圆点('bo')来绘制原始数据点,其中:'b' 表示蓝色(blue)。'o' 表示圆点。这些数据点代表实验中获得的初始反应速率。
plt.plot(smooth_x, smooth_y, 'r', label = 'fit')使用红色实线('r')绘制平滑的拟合曲线,其中:'r' 表示红色(red)。由于 smooth_x 包含更多点,曲线会显得更加平滑和连续,而不是像上一段代码那样仅仅通过有限的 xdata 绘制曲线。
plt.legend()添加图例,帮助区分图中的不同元素(如实验数据和拟合曲线)。



沪公网安备 31011002003500