各位小伙伴大家好,线性回归是一种统计方法,用于描述两个或多个变量之间的线性关系。其主要目标是建立一个数学模型,通过自变量(输入变量或解释变量)来预测因变量(输出变量或响应变量)的值。线性回归广泛应用于数据分析、经济学、金融、工程、社会科学等领域。这周我们将在上一课的基础上,先学习使用 pandas 库导入本课的数据。然后,我们将使用 SciPy 库执行线性回归。
由于有些小伙伴是新加入我们的,大家可以通过网盘获取课程材料:
链接: https://pan.baidu.com/s/1eJKPQ64SDoMdywZNEdgr7Q?pwd=hiya 提取码: hiya
下载好之后需要各位小伙伴解压,然后一定要记住解压的地址哦,因为我们的代码需要指定文件的路径。
在之前的课程中,我们使用过 os、numpy 和 pandas。在本课中,我们将添加 SciPy 库,它是用于解决数学、科学、技术和工程问题的数值工具的集合。SciPy 的特定子集可用于线性代数 (scipy.linalg)、优化和拟合 (scipy.optimize)、统计和随机数 (scipy.stats) 以及数值积分 (scipy.integrate)。
我们将使用之前介绍的点符号来访问这些库中的函数。大家可以看到下图中列出的缩写(Abbreviation)只是最常见的缩写。实际上,我们也可以定义任何您喜欢的缩写,但最好使用常规缩写。这将有助于未来的程序员(包括六个月后的您自己)理解和使用代码。

那么今天我们需要做四件事情:
1.导入正确的库
2.使用 pandas 导入数据
3.运行简单线性回归并且打印出所需的统计数据
4.使用线性回归结果计算蛋白质样品浓度。
首先第一步:导入正确的库
我们使用代码:
import osimport numpy as npimport pandas as pdfrom scipy import stats
以下是每行代码的意思:
import os这行代码导入了 Python 的 os 模块,它提供了一些函数用于与操作系统进行交互,如文件和目录操作。这些函数可以用于获取文件路径、创建目录、删除文件等。
import numpy as np这行代码导入了 NumPy 库,并将其简写为 np。NumPy 是一个用于科学计算的库,提供了支持多维数组和矩阵操作的大量数学函数。np 是一个常用的简写,使得代码更简洁。
import pandas as pd这行代码导入了 Pandas 库,并将其简写为 pd。Pandas 是一个用于数据分析和数据操作的库,提供了数据结构和工具,用于高效地操作大型数据集。pd 也是一个常见的简写,方便引用 Pandas 提供的功能。
from scipy import stats这行代码从 SciPy 库中导入了 stats 模块。SciPy 是一个用于科学和技术计算的库,提供了许多函数和工具。stats 模块提供了丰富的统计函数和方法,如概率分布、统计测试等。
接下来是第二步:使用 pandas 导入数据
在这一步,我们将继续使用 os 和 pandas 来导入数据。使用 pandas 时,有经验的程序员经常将 _df 附加到变量名称的末尾,以提醒这是一个DataFrame (一个二维数据结构),因此包含我们结果的DataFrame可以表示为 results_df。
.webp)
这段代码涉及到文件路径的构建和 CSV 文件的读取,并将数据存储在 Pandas DataFrame 中。
protein_file = os.path.join('data', 'protein_assay.csv')这行代码使用 os.path.join 函数构建了一个文件路径。os.path.join 函数会根据操作系统的路径分隔符,智能地拼接路径字符串。在这个例子中,它将 'data' 目录和 'protein_assay.csv' 文件名连接起来,形成文件的完整路径,并将其存储在变量 protein_file 中。这个路径可能是相对路径(相对于当前脚本的工作目录),也可能是绝对路径。
results_df = pd.read_csv(protein_file)这行代码使用 Pandas 的 read_csv 函数读取 CSV 文件中的数据。protein_file 是文件路径,pd.read_csv 函数会从该路径加载数据,并将其转换为一个 Pandas DataFrame 对象。DataFrame 是一种数据结构,类似于电子表格,它能够方便地进行数据操作和分析。读取的数据被存储在变量 results_df 中。
results_df这一行只是表示输出 results_df,即显示 results_df 中的内容。Jupyter Notebook 等环境中,当最后一行代码是一个对象时,它会自动显示该对象的内容。因此,这行代码的目的是展示读取的 DataFrame 的数据。
在DataFrame中,您可以仅通过列标题引用列中的数据。这些是字符串,因此在使用它们时需要用单引号或双引号引起来。在 pandas 中,术语系列通常用于指代DataFrame中单个列中的数据。因此,我们将使用两个列标题来定义线性回归的数据。
大家可以输入:
xdata = results_df['Protein Concentration (mg/mL)']ydata = results_df['A595']print("Protein Concentration (mg/mL):")print(xdata)print("\nA595 Absorbance:")print(ydata)
来看看结果:
.webp)
xdata = results_df['Protein Concentration (mg/mL)'这行代码从 results_df DataFrame 中提取名为 'Protein Concentration (mg/mL)' 的列。results_df 是一个包含多个列的数据表格,results_df['Protein Concentration (mg/mL)'] 提取的是该表格中名为 'Protein Concentration (mg/mL)' 的一列数据,并将其存储在变量 xdata 中。xdata 现在是一个 Pandas Series 对象,包含了所有的蛋白质浓度数据。
ydata = results_df['A595']这行代码类似于前一行,从 results_df DataFrame 中提取名为 'A595' 的列,并将其存储在变量 ydata 中。ydata 是一个 Pandas Series 对象,包含了所有的 A595 吸光度数据。
现在数据已就位,我们只需从 SciPy 导入 stats 模块就可以实现我们的今天学习的第三步。
第三步:运行简单线性回归
scipy.stats 中的 linregress 函数其实很有意思,当我们给它输入两组数据(也就是我们刚才分出来的 xdata 和 ydata 的时候,它实际上生成了五个值:斜率(slope)、截距(intercept)、r 值(r_value)、p 值(p_value)和标准误差(std_err)。我们可以试一下,输入我们的数据,然后打印出这些值。
slope, intercept, r_value, p_value, std_err = stats.linregress(xdata, ydata)print("Slope = ", slope)print("Intercept = ", intercept)print("R-squared = ", r_value**2)print("P value = ", p_value)print("Standard error = ", std_err)
.webp)
是不是很方便?那我们直接运用这个方法来完成今天的最后一步。
最后一步:计算蛋白质样品浓度
我们将确定蛋白质浓度(以 mg/mL 为单位)。六个蛋白质样品的数据可以在 data/ Protein_samples.csv 中找到,各位小伙伴可以自己尝试用代码打开它。
我们从标准曲线的方程开始

我们可以将其重新排列以求解蛋白质浓度。

我们的最终方程将会求解出以 mg/mL 为单位的浓度,基于斜率的单位(/mg/mL)和无单位的截距。
protein_conc = ((results_df['A-595'] - intercept) / slope)print(protein_conc)
这时我们就得到了蛋白质浓度的数据,当然我们可以将这个结果直接添加进 DataFrame 中。我们只需使用数据框的名称,后跟方括号内单引号中的新列的名称。在这种情况下,我们将创建新列并将计算出的浓度值分配给该列。
results_df['ProtConc'] = protein_concresults_df

我们看这个表中,有两个未知样品的吸光度值超出了标准吸光度值。因此,这些浓度在实验上无效,应报告为“超出范围”。所以我们需要消除校准曲线之外的值。
今天的所有代码如下:
import osimport numpy as npimport pandas as pdfrom scipy import statsprotein_file = os.path.join('data', 'protein_samples.csv')results_df = pd.read_csv(protein_file)protein_conc = ((results_df['A-595'] - intercept) / slope)results_df['ProtConc'] = protein_concresults_df.loc[results_df['A-595'] < 0.285, 'ProtConc'] = np.nanresults_df.loc[results_df['A-595'] > 1.118, 'ProtConc'] = np.nanresults_df
我们在代码中通过使用 loc 查看 DataFrame 中的行来进行数据的更改。同时使用 np.nan 来将结果是 NaN(非数字)值作为输出。我们来最终总结一下每一行代码的意义:
import os这行代码导入了 os 模块。os 模块提供了与操作系统交互的功能,如文件和目录操作。在这个代码中,它用于构建文件路径。
import numpy as np这行代码导入了 NumPy 库,并将其简写为 np。NumPy 是一个用于科学计算的库,提供了多维数组对象和大量的数学函数。在这个代码中,NumPy 可能用于数据处理和计算。
import pandas as pd这行代码导入了 Pandas 库,并将其简写为 pd。Pandas 是一个强大的数据分析库,提供了数据结构和工具,用于高效地处理和分析数据。在这个代码中,它用于读取 CSV 文件并进行数据操作。
from scipy import stats这行代码从 SciPy 库中导入了 stats 模块。SciPy 是一个用于科学计算的库,stats 模块包含了许多统计函数和方法。虽然在这个代码片段中没有直接使用 stats 模块,但它可能在其他部分用于统计分析。
protein_file = os.path.join('data', 'protein_samples.csv')这行代码使用 os.path.join 函数将 'data' 目录和 'protein_samples.csv' 文件名连接起来,构建了 CSV 文件的路径,并将其存储在变量 protein_file 中。这个路径可能是相对路径,也可能是绝对路径。
results_df = pd.read_csv(protein_file)这行代码使用 Pandas 的 read_csv 函数读取 protein_file 路径下的 CSV 文件,并将其数据加载到一个 DataFrame 中,存储在变量 results_df 中。results_df 是一个 Pandas DataFrame 对象,包含了读取的数据。
protein_conc = ((results_df['A-595'] - intercept) / slope)这行代码计算蛋白质浓度。它使用公式 (A_{595} - intercept) / slope 计算 results_df 中每一行数据的蛋白质浓度,其中 intercept 和 slope 是之前定义的截距和斜率。结果存储在变量 protein_conc 中。
results_df['ProtConc'] = protein_conc这行代码将计算得到的 protein_conc 列添加到 results_df DataFrame 中,列名为 'ProtConc'。这相当于为每个样本添加了计算得到的蛋白质浓度。
results_df.loc[results_df['A-595'] < 0.285, 'ProtConc'] = np.nan这行代码使用 loc 方法查找 results_df 中 A-595 值小于 0.285 的所有行,并将这些行的 'ProtConc' 列设置为 NaN。这是为了处理不在有效测量范围内的值。
results_df.loc[results_df['A-595'] > 1.118, 'ProtConc'] = np.nan这行代码类似于上一行,它将 A-595 值大于 1.118 的所有行的 'ProtConc' 列设置为 NaN。这同样是为了处理不在有效测量范围内的值。
results_df这行代码用于输出 results_df 的内容。在交互式环境(如 Jupyter Notebook)中,这行代码会显示 results_df DataFrame 的当前内容。

Tip:loc 的使用方法很多,我们再举几个例子(假如我们已经读取了一个表格读取在 results_df中):
将特定条件下的数据标记为缺失值(NaN),比如我们将 'Age' 列中年龄小于 18 岁的人的 'Status' 列设为 NaN。
results_df.loc[results_df['Age'] < 18, 'Status'] = np.nan修改特定条件下的列值,比如,将 'Score' 列中成绩大于 90 的行的 'Grade' 列设为 ‘A’。
results_df.loc[results_df['Score'] > 90, 'Grade'] = ‘A'用特定值替换特定条件下的列值,将 'Salary' 列中薪资大于 100000 的行的 'Tax' 列设为 0.3。
results_df.loc[results_df['Salary'] > 100000, 'Tax'] = 0.3添加新列并根据条件进行赋值,例如添加新列 'HighIncome',并将收入大于 50000 的行设为 True,其他设为 False。
results_df['HighIncome'] = Falseresults_df.loc[results_df['Income'] > 50000, 'HighIncome'] = True
基于多个条件更新列值,例如将 'Discount' 列设为 0.1,如果 'Category' 为 'Electronics' 且 'Price' 大于 500。
results_df.loc[(results_df['Category'] == 'Electronics') & (results_df['Price'] > 500), 'Discount'] = 0.1
这些示例展示了如何使用 loc 方法结合条件进行数据筛选和操作。这种方法非常灵活,可以用于更新、替换或标记特定数据。



沪公网安备 31011002003500