
将 Pandas、NumPy 和 scikit-learn 集成到机器学习工作流中
图片作者 | ChatGPT
引言
机器学习工作流需要几个不同的步骤——从加载和准备数据到创建和评估模型。Python 提供了在每个步骤中表现出色的专用库:Pandas 处理数据操作,NumPy 提供数学运算,scikit-learn 提供机器学习算法。虽然它们各自都有价值,但当它们协同工作时,其真正的优势才会显现。
在本教程中,您将学习如何在一个统一的工作流中集成这三个库来构建有效的机器学习解决方案。您将使用一个具体的混凝土抗压强度数据集,根据各种成分预测强度——这是一个展示机器学习实际应用工程问题。
到本教程结束时,您将理解
- 这三个库在数据科学工作流中如何互补
- 每个库在分析的不同阶段所扮演的具体角色
- 如何在保留重要信息的同时在库之间顺畅地移动数据
- 从原始数据到预测创建集成流程的技术
先决条件
在深入学习本教程之前,您应该
- 在您的系统上安装了 Python 3.6 或更高版本
- 对 Python 语法和编程概念有基本了解
- 已安装以下库
- Pandas (1.0.0 或更高版本)
- NumPy (1.18.0 或更高版本)
- scikit-learn (0.22.0 或更高版本)
- Matplotlib (3.1.0 或更高版本),用于可视化
如果您需要安装这些包,可以使用 pip
1 |
pip install pandas numpy scikit-learn matplotlib |
本教程假定您对机器学习概念(如回归、训练/测试分割和模型评估)有一些基本的了解。但是,我们将在进行过程中解释关键概念,因此即使您是机器学习方面的新手,也应该能够跟上。
对于那些想在结合使用这些库之前先复习一下各个库的人,以下资源可能会有帮助
数据科学流程
在数据科学项目中,我们通常遵循一个顺序工作流,数据流经不同的处理阶段。我们的三个库都在此流程中发挥特定作用
- Pandas 作为我们的初始数据处理器,擅长
- 从各种来源读取数据(CSV、Excel、SQL)
- 探索和汇总数据集特征
- 清理混乱的数据和处理缺失值
- 转换和重塑数据结构
- NumPy 作为我们的数值计算引擎
- 提供高效的数组操作
- 实现矢量化数学运算
- 支持科学计算功能
- 提供线性代数运算
- scikit-learn 作为我们的建模工具包
- 使用一致的 API 预处理数据
- 构建机器学习模型
- 评估模型性能
- 创建预测流程
这三个库的优雅之处在于它们的兼容性。Pandas DataFrame 可以轻松转换为 NumPy 数组,这是 scikit-learn 模型的标准输入格式。这种无缝的数据流使我们能够毫不费力地在描述性分析、数值计算和预测建模之间进行转换。
使用 Pandas 加载和探索数据
让我们开始使用 Pandas 加载我们的混凝土抗压强度数据集。该数据集包含有关混凝土混合料及其产生的强度测量值的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split 来自 sklearn.linear_model 导入 LinearRegression from sklearn.metrics import mean_squared_error, r2_score # 加载数据集 url = "https://archive.ics.uci.edu/ml/machine-learning-databases/concrete/compressive/Concrete_Data.xls" concrete_data = pd.read_excel(url) # 显示前几行并检查缺失值 print(concrete_data.head()) print(f"数据集形状:{concrete_data.shape}") print(f"缺失值:{concrete_data.isnull().sum().sum()}") |
运行此代码时,您将看到数据集的前五行,其中列代表不同的混凝土成分和产生的抗压强度
1 2 |
数据集 形状: (1030, 9) 缺失 值: 0 |
该数据集包含 1030 个样本,其中 8 个特征会影响混凝土强度。目标变量是以兆帕 (MPa) 为单位测量的混凝土抗压强度。
让我们可视化水泥(一种主要成分)与抗压强度之间的关系
1 2 3 4 5 6 7 |
plt.figure(figsize=(10, 6)) plt.scatter(concrete_data.iloc[:, 0], concrete_data.iloc[:, -1]) plt.xlabel("水泥 (kg/m³)") plt.ylabel("抗压强度 (MPa)") plt.title("水泥与抗压强度对比") plt.grid(True) plt.show() |
这个散点图显示了水泥含量和抗压强度之间存在正相关关系,这与工程知识一致。
我们还可以使用 Pandas 创建相关矩阵来识别变量之间的关系
1 2 3 4 5 6 |
# 计算相关矩阵 correlation_matrix = concrete_data.corr() # 显示与抗压强度的相关性 print("与抗压强度的相关性:") print(correlation_matrix.iloc[-1, :-1].sort_values(ascending=False)) |
该分析揭示了哪些成分与混凝土强度关系最强。了解这些关系将有助于我们稍后解释机器学习模型。Pandas 使这些初始数据探索步骤变得简单,使我们能够在进行更高级的分析之前快速获得见解。
数据准备和转换
在探索了我们的数据集之后,让我们通过将 Pandas DataFrame 转换为适合 scikit-learn 模型的 NumPy 数组来准备它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 将数据分割为特征 (X) 和目标变量 (y) X = concrete_data.iloc[:, :-1] # 特征:除最后一列外的所有列 y = concrete_data.iloc[:, -1] # 目标:仅最后一列 # 在这里,我们通过将 DataFrame 转换为数组来从 Pandas 转移到 NumPy # 这是两个库之间一个关键的集成点 X_array = X.values # Pandas DataFrame → NumPy 数组 y_array = y.values # Pandas Series → NumPy 数组 print(f"转换前类型:{type(X)}") print(f"转换后类型:{type(X_array)}") # 将数据拆分为训练集和测试集 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X_array, y_array, test_size=0.2, random_state=42) print(f"训练集形状:{X_train.shape}") |
输出将是
1 2 3 |
转换前 类型: <class 'pandas.core.frame.DataFrame'> 转换后 类型: <class 'numpy.ndarray'> 训练集 形状: (824, 8) |
本节强调了我们工作流中的第一个关键集成点:如何使用 .values
属性将 Pandas DataFrame 转换为 NumPy 数组。虽然 scikit-learn 实际上可以直接处理 Pandas DataFrame(它会在内部进行转换),但理解这一过渡有助于说明这些库是如何设计为协同工作的。NumPy 数组格式是实现高效数值计算并允许与 scikit-learn 算法无缝集成的“通用语言”。
使用 scikit-learn 构建机器学习模型
现在让我们使用我们处理过的数据来构建和评估机器学习模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
来自 sklearn.linear_model 导入 LinearRegression from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score # 训练一个线性回归模型 lr_model = LinearRegression() lr_model.fit(X_train, y_train) # 训练一个随机森林模型 rf_model = RandomForestRegressor(n_estimators=100, random_state=42) rf_model.fit(X_train, y_train) # 进行预测 lr_predictions = lr_model.predict(X_test) rf_predictions = rf_model.predict(X_test) # 评估模型 models = ["线性回归", "随机森林"] predictions = [lr_predictions, rf_predictions] for model_name, pred in zip(models, predictions): mse = mean_squared_error(y_test, pred) r2 = r2_score(y_test, pred) print(f"{model_name}:") print(f" 均方误差:{mse:.2f}") print(f" R² 分数:{r2:.2f}") |
上面的代码块应该会输出
1 2 3 4 5 6 |
线性 回归: 均方 误差: 95.98 R² 分数: 0.63 随机 森林: 均方 误差: 30.36 R² 分数: 0.88 |
本节强调了第二个关键的集成点:将 NumPy 数组直接馈入 scikit-learn 模型。请注意,scikit-learn 的一致 API 如何无缝接受我们的 NumPy 数组,而无需任何进一步的转换。这种集成使我们能够在不更改预处理数据的情况下,切换不同的机器学习算法(如线性回归和随机森林)。
结果显示两种模型在性能上存在显著差异。随机森林模型的 R² 分数达到了 0.88,远高于线性回归模型的 0.63,并将均方误差降低了三分之二以上(从 95.98 降至 30.36)。这种显著的改进表明混凝土成分与强度之间的关系是非线性的,随机森林能够捕捉到这一点,而线性回归则不能。
能够快速比较不同算法的能力是 scikit-learn 统一接口的一个主要优势——我们只需几行代码就可以更改模型,同时保持其余工作流程不变。这种灵活性得益于 NumPy 数组和 scikit-learn 算法之间的无缝集成。
案例研究:加入领域知识
最后,让我们通过结合混凝土领域的知识来改进我们的模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 使用 NumPy 高效的算术运算来创建领域特定的特征 cement_water_ratio = X_train[:, 0] / X_train[:, 3] # 水泥/水比 cement_water_ratio_test = X_test[:, 0] / X_test[:, 3] # 使用 NumPy 的数组操作将此新特征添加到我们的特征矩阵中 X_train_enhanced = np.column_stack((X_train, cement_water_ratio)) X_test_enhanced = np.column_stack((X_test, cement_water_ratio_test)) # 使用增强的特征训练模型 from sklearn.ensemble import GradientBoostingRegressor model = GradientBoostingRegressor(n_estimators=100, random_state=42) model.fit(X_train_enhanced, y_train) predictions = model.predict(X_test_enhanced) print(f"加入领域知识的模型:") print(f" R² 分数:{r2_score(y_test, predictions):.2f}") # 可视化结果 plt.figure(figsize=(8, 6)) plt.scatter(y_test, predictions, alpha=0.5) plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], 'r--') plt.xlabel('实际强度 (MPa)') plt.ylabel('预测强度 (MPa)') plt.title('预测与实际混凝土强度对比') plt.grid(True) plt.show() |
这个最后的例子展示了集成所有三个库的全部威力。我们从使用 Pandas 准备的数据开始,然后利用 NumPy 的矢量化运算高效地创建一个领域特定的特征(水泥与水之比),工程师们认为这对混凝土强度很重要。NumPy 的数组操作函数(如 column_stack
)使我们能够将原始特征与这个新工程特征无缝地组合起来。
1 2 |
加入领域知识的 模型: R² 分数: 0.89 |
结果令人印象深刻,我们的增强模型达到了 0.89 的 R² 分数,甚至优于随机森林模型的 0.88。可视化显示了预测和实际强度值在整个范围内的强相关性,点紧密地聚集在参考对角线周围。
这个完整的流程——从 Pandas 到 NumPy 再到 scikit-learn——展示了为什么这些库会成为许多数据科学项目的基石。每个库都在特定任务上表现出色:Pandas 用于数据处理,NumPy 用于数值运算,scikit-learn 用于机器学习。结合使用时,它们构成了一个强大的工具集,使数据科学家能够快速地从原始数据迭代到准确的预测。
通过了解这些库如何协同工作以及它们在哪里集成,您可以构建更高效、更有效的机器学习解决方案。通过特征工程添加领域知识进一步表明,人类专业知识与这些工具的结合可以带来卓越的结果。
扩展和总结
在本教程中,我们探讨了如何组合 Pandas、NumPy 和 scikit-learn 来创建一个有效的机器学习工作流
- 我们使用 Pandas 加载、探索和清理我们的混凝土数据集
- 我们利用 NumPy 进行高效的数值运算和特征转换
- 我们使用 scikit-learn 的一致 API 构建了预测模型
这种集成使我们能够发挥每个库的优势:Pandas 用于数据操作,NumPy 用于数值计算,scikit-learn 用于机器学习算法。
要进一步扩展此工作流,请考虑探索
- scikit-learn 的 Pipeline API 以实现简化的工作流
- 特征选择技术以识别最重要的混凝土成分
- 集成技术,例如我们演示过的随机森林
- 交叉验证方法以确保模型鲁棒性
通过学习这些库如何协同工作,您将能够高效地解决各种数据科学和机器学习问题。
非常棒的信息
感谢您的反馈,Francis!
我还没读完,但已经觉得这篇文章很有价值了。非常感谢。
感谢 Zakhele 的反馈和支持!期待您的进展!
我真的很喜欢您对这些库在构建 ML 模型中的关系的分解。解释非常适合初学者。我是这个领域的新手,读了这篇文章,它确实帮助我理解了一些我一直难以理解的东西。我非常感激。非常感谢。
感谢 Brian 的反馈!期待您的进展!
解释得非常清楚
感谢 Rajeev 的反馈!
探索知识是神圣的。