Python神经网络回归实战:从数据可视化到模型调优全流程解析

📅 2026/8/21 3:22:45
Python神经网络回归实战:从数据可视化到模型调优全流程解析
1. 从零开始为什么用Python做神经网络回归如果你正在处理一堆数据想预测一个连续的值——比如根据历史天气数据预测明天的温度或者根据房屋面积、地段预测房价——那你大概率会遇到“回归”问题。传统的线性回归可能力不从心这时候神经网络就该登场了。它就像一个超级能干的学徒能从复杂的数据模式里学到我们人类一眼看不出的规律。用Python来实现这件事现在几乎是行业标配。不是因为Python语法有多优美而是因为它背后有像NumPy、Pandas、Matplotlib以及深度学习框架TensorFlow和PyTorch这样的“神级队友”。这些库把复杂的矩阵运算、自动求导、模型训练都封装成了简单的几行代码让我们能把精力集中在数据和问题本身而不是底层数学上。但很多人学神经网络容易陷入两个极端要么被各种数学公式吓退要么就只会调用model.fit()然后对着最终那个冷冰冰的损失值发呆。这就像你费尽心思做了一桌子菜却不让客人看见、闻到、尝到一样。结果可视化就是让这桌菜色香味俱全的关键一步。它不仅仅是最后画个预测曲线那么简单更是我们理解模型行为、诊断问题、向别人解释成果的必备工具。一个没有可视化的神经网络项目是不完整的。所以这篇内容我们就来扎扎实实地走一遍如何用Python从准备数据开始搭建一个用于回归任务的神经网络训练它并最终通过一系列可视化手段把整个过程和结果“摊开来”看明白。我会分享一些我实际项目中总结出来的、文档里不太会写的细节和技巧。2. 环境搭建与核心工具链选择工欲善其事必先利其器。在开始写代码之前我们需要一个稳定、高效的工作环境。对于深度学习来说环境管理是避免日后“依赖地狱”的第一步。2.1 Python与包管理Anaconda的明智之选我强烈建议新手和有经验的开发者都从Anaconda开始。它是一个集成了Python、包管理工具conda和大量科学计算库的发行版。对于神经网络项目它的核心优势在于能轻松创建独立的虚拟环境。为什么需要虚拟环境想象一下你手头有两个项目一个需要用TensorFlow 2.10另一个老项目必须跑在TensorFlow 1.15上。如果没有虚拟环境这两个版本的库会互相冲突让你焦头烂额。用conda一行命令就能解决问题# 创建一个名为nn_regression的虚拟环境并指定Python版本 conda create -n nn_regression python3.9 # 激活这个环境 conda activate nn_regression激活后你在这个环境下安装的所有包都只属于这个环境与其他项目完全隔离。这是保持项目纯净和可复现性的基石。2.2 核心库详解每个工具扮演什么角色环境准备好后我们来安装核心的“四大金刚”。你可以通过pip在激活的虚拟环境中逐一安装NumPy (必选)这是整个Python科学计算生态的基石。神经网络底层本质是大量的矩阵和向量运算。NumPy提供了高效的多维数组对象和运算函数。即使TensorFlow和PyTorch有自己的张量对象但它们与NumPy数组的转换也极其方便很多数据预处理也依赖NumPy。Pandas (强烈推荐)处理结构化数据的利器。我们的数据通常来自CSV、Excel或数据库Pandas的DataFrame结构让数据加载、清洗、探索和预处理变得异常直观。比如处理缺失值、进行特征缩放、划分数据集用Pandas都能优雅地完成。Matplotlib Seaborn (必选)可视化双雄。Matplotlib是底层绘图库功能强大且灵活可以绘制任何你想要的图表。Seaborn是基于Matplotlib的高级接口它简化了许多常见统计图表的创建过程并且默认的样式更加美观。在神经网络回归中我们会用它来画数据分布、学习曲线、预测对比图等。深度学习框架TensorFlow/Keras vs. PyTorch这是最重要的选择。目前主流是两大阵营TensorFlow/Keras尤其是TensorFlow 2.x之后其高级APIKeras被深度集成变得非常易用。它的设计哲学是“用户友好、模块化、可扩展”。对于快速原型开发、标准网络构建Keras的Sequential或Functional API能让你用极少的代码搭建出模型。它的文档和社区资源也极其丰富。对于回归任务入门和大多数生产部署我通常首选Keras因为它简单直接不容易出错。PyTorch以动态计算图和更“Pythonic”的编程风格著称在研究领域和需要高度定制化的模型中非常受欢迎。它的设计让调试变得更直观因为你可以像调试普通Python代码一样调试网络。我的选择建议如果你是初学者或者你的目标是快速、稳定地解决一个回归预测问题那么从TensorFlow/Keras开始。它的学习曲线更平缓能让你的注意力集中在理解机器学习流程上而不是框架的复杂性上。本篇后续的代码示例也将基于TensorFlow/Keras。安装命令很简单pip install tensorflow。这会安装包含Keras的完整TensorFlow包。同时也建议安装scikit-learn它提供了优秀的数据集、数据划分和评估工具pip install scikit-learn。3. 回归问题实战波士顿房价数据集全流程理论说再多不如动手做一遍。我们选用一个经典的数据集波士顿房价数据集虽然由于其伦理问题已从sklearn最新版中移除但作为教学示例其结构依然典型。我们的目标是根据房屋的多个特征如犯罪率、房间数、到市中心的距离等预测房屋的中位数价格。3.1 数据加载与第一眼观察首先我们导入所有必要的库并加载数据。import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import fetch_california_housing # 使用加州房价数据集作为替代 from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers # 设置随机种子保证结果可复现 np.random.seed(42) tf.random.set_seed(42) # 加载加州房价数据集特征更多更接近现实 housing fetch_california_housing() # 将数据转换为Pandas DataFrame便于观察 df pd.DataFrame(housing.data, columnshousing.feature_names) df[MedHouseVal] housing.target # 目标值房屋中位数价格单位十万美元 print(数据集形状:, df.shape) print(\n前5行数据:) print(df.head()) print(\n数据基本信息:) print(df.info()) print(\n描述性统计:) print(df.describe())运行这段代码你会立刻对数据有个整体认识有多少样本、多少个特征、是否有缺失值、各个特征的大致范围。这是任何数据分析的第一步绝不能跳过。3.2 数据可视化探索看见才能理解在把数据扔给模型之前我们必须先“看”懂它。这里有几个关键的可视化1. 目标值分布plt.figure(figsize(10, 5)) plt.subplot(1, 2, 1) sns.histplot(df[MedHouseVal], bins50, kdeTrue) plt.title(目标值(房价)分布) plt.xlabel(Median House Value (单位: $100,000)) plt.subplot(1, 2, 2) sns.boxplot(ydf[MedHouseVal]) plt.title(目标值箱线图) plt.tight_layout() plt.show()直方图可以看分布是否正态这对某些模型有影响箱线图能快速发现异常值。如果分布严重偏斜我们可能需要对目标值进行对数变换。2. 特征与目标的关系# 选取几个关键特征绘制其与房价的散点图 fig, axes plt.subplots(2, 3, figsize(15, 10)) features_to_plot [MedInc, HouseAge, AveRooms, AveBedrms, Population, AveOccup] for idx, feature in enumerate(features_to_plot): row, col idx // 3, idx % 3 axes[row, col].scatter(df[feature], df[MedHouseVal], alpha0.3, s10) axes[row, col].set_xlabel(feature) axes[row, col].set_ylabel(MedHouseVal) # 尝试添加一条趋势线多项式拟合 try: z np.polyfit(df[feature], df[MedHouseVal], 1) p np.poly1d(z) axes[row, col].plot(df[feature], p(df[feature]), r--, linewidth2) except: pass plt.suptitle(关键特征与房价的关系散点图, fontsize16) plt.tight_layout() plt.show()散点图能直观展示特征与目标之间是线性关系、非线性关系还是基本没关系。图中红色的虚线是简单线性拟合的趋势线可以帮助我们判断。例如MedInc收入中位数与房价呈现明显的正相关而Population人口的关系则显得杂乱。3. 特征间相关性热图plt.figure(figsize(12, 8)) # 计算相关系数矩阵 correlation_matrix df.corr() # 绘制热图 sns.heatmap(correlation_matrix, annotTrue, fmt.2f, cmapcoolwarm, center0, squareTrue, linewidths.5, cbar_kws{shrink: .8}) plt.title(特征间相关性热图, fontsize16) plt.tight_layout() plt.show()热图是发现多重共线性的利器。如果两个特征之间高度相关接近1或-1那么它们提供的信息可能是冗余的我们可以考虑移除其中一个以简化模型、提高稳定性。从热图中我们可能会发现AveRooms和AveBedrms有较高的相关性这符合常识。3.3 数据预处理模型性能的基石原始数据很少能直接用于神经网络。预处理是关键一步做不好模型再复杂也白搭。1. 处理缺失值与异常值我们这个数据集是清洗过的没有缺失值。但在真实项目中你必须检查并用适当的方法处理缺失值如删除、均值/中位数填充等。对于异常值可以基于箱线图或标准差原则如3σ原则进行识别和处理。对于回归问题异常值对模型的影响可能很大。2. 特征缩放标准化/归一化这是神经网络训练的标配。因为网络中的优化算法如梯度下降对特征的尺度非常敏感。如果特征A的范围是0-1特征B的范围是0-10000那么梯度更新会在B的方向上剧烈震荡导致收敛缓慢甚至失败。# 分离特征和目标 X df.drop(MedHouseVal, axis1).values y df[MedHouseVal].values # 划分训练集和测试集通常8:2或7:3 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 特征标准化减去均值除以标准差。注意用训练集的参数来转换测试集 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) # fit计算训练集的均值和标准差 X_test_scaled scaler.transform(X_test) # transform使用训练集的参数进行转换 print(f训练集形状: {X_train_scaled.shape}, 测试集形状: {X_test_scaled.shape})重要提示fit_transform只在训练集上做测试集必须使用从训练集学到的同一个scaler进行transform。这是为了避免数据泄露——即测试集的信息以任何形式“污染”了训练过程。这是一个非常容易踩的坑。3. 目标值是否需要缩放对于回归问题如果目标值范围很大也可以考虑对其进行缩放比如StandardScaler或MinMaxScaler。但请注意在模型预测后你需要将预测值反向缩放回原始尺度才能进行有意义的评估和可视化。在本例中房价范围在0-5左右可以暂时不做缩放。4. 构建与训练你的第一个回归神经网络数据准备好了现在我们来搭建模型。我们将使用Keras的SequentialAPI它就像搭积木一样简单。4.1 模型架构设计层、神经元与激活函数def build_model(input_shape): model keras.Sequential([ # 输入层需要指定输入数据的形状 layers.Input(shape(input_shape,)), # 第一个隐藏层64个神经元使用ReLU激活函数 layers.Dense(64, activationrelu), # Dropout层随机丢弃20%的神经元防止过拟合 layers.Dropout(0.2), # 第二个隐藏层32个神经元 layers.Dense(32, activationrelu), # 输出层1个神经元回归任务预测一个连续值不使用激活函数或使用线性激活 layers.Dense(1) ]) return model # 获取输入特征的维度 input_dim X_train_scaled.shape[1] model build_model(input_dim) # 打印模型结构摘要 model.summary()运行model.summary()你会看到每一层的输出形状和参数数量。理解这个很重要Dense层全连接层每个神经元都与上一层的所有神经元相连。参数数量 (输入维度 1) * 输出维度。那个“1”是偏置项。激活函数ReLUf(x) max(0, x)。它解决了线性模型表达能力不足的问题引入了非线性使得网络可以拟合复杂的曲线。同时它的计算简单能缓解梯度消失问题是目前最常用的激活函数。Dropout层在训练时随机将一部分神经元的输出置零。这是一种正则化技术强迫网络不依赖于任何单个神经元从而学习到更鲁棒的特征有效减轻过拟合。注意Dropout只在训练时启用在预测时是不起作用的。输出层回归任务通常使用线性激活即无激活函数因为我们希望输出可以是任意实数。如果对目标值做了归一化到[0,1]也可以使用sigmoid激活。4.2 编译模型定义损失与优化器模型结构是骨架编译是给它注入灵魂——告诉它如何学习和衡量好坏。model.compile( optimizeradam, # 优化器自适应学习率的梯度下降算法非常流行且效果好 lossmse, # 损失函数均方误差回归问题的标准损失函数 metrics[mae] # 评估指标平均绝对误差比MSE更直观单位与目标值相同 )优化器 (Optimizer)负责根据损失函数的梯度来更新网络的权重。Adam优化器结合了动量Momentum和自适应学习率RMSProp的优点在大多数情况下都能快速稳定地收敛是默认的推荐选择。损失函数 (Loss)模型要最小化的目标。MSE均方误差会放大较大误差的影响对异常值敏感。如果你的数据中有很多异常值可以考虑MAE平均绝对误差或Huber Loss结合了MSE和MAE的优点。评估指标 (Metrics)用于在训练和评估过程中监控模型性能。MAE告诉我们平均预测误差有多大单位是十万美元非常直观。4.3 训练模型并可视化学习过程现在让我们开始训练并实时可视化训练过程这是理解模型行为的关键。# 训练模型并保留历史记录用于绘图 history model.fit( X_train_scaled, y_train, validation_split0.2, # 从训练集中再分出20%作为验证集用于在训练中监控泛化能力 epochs150, # 整个数据集遍历150次 batch_size32, # 每次梯度更新使用的样本数 verbose1, # 显示进度条 callbacks[keras.callbacks.EarlyStopping(patience10, restore_best_weightsTrue)] ) # 可视化训练历史 def plot_training_history(history): fig, axes plt.subplots(1, 2, figsize(14, 5)) # 绘制损失曲线 axes[0].plot(history.history[loss], labelTraining Loss) axes[0].plot(history.history[val_loss], labelValidation Loss) axes[0].set_xlabel(Epoch) axes[0].set_ylabel(Loss (MSE)) axes[0].set_title(Training and Validation Loss) axes[0].legend() axes[0].grid(True, linestyle--, alpha0.7) # 绘制评估指标曲线 axes[1].plot(history.history[mae], labelTraining MAE) axes[1].plot(history.history[val_mae], labelValidation MAE) axes[1].set_xlabel(Epoch) axes[1].set_ylabel(MAE) axes[1].set_title(Training and Validation MAE) axes[1].legend() axes[1].grid(True, linestyle--, alpha0.7) plt.tight_layout() plt.show() plot_training_history(history)这里有几个非常重要的点验证集 (Validation Set)我们用validation_split从训练集中分出一部分作为验证集。验证集不参与梯度更新它只用来在每一轮训练后评估模型在未见过的数据上的表现。这是检测过拟合的“照妖镜”。早停法 (EarlyStopping)这是一个极其实用的回调函数。它监控验证集损失如果连续patience个轮次这里设10损失没有下降就停止训练并可以自动恢复到验证损失最低的那个轮次的模型权重。这能有效防止过拟合并节省不必要的训练时间。学习曲线解读理想情况训练损失和验证损失都稳步下降并最终趋于平稳且两者数值接近。过拟合训练损失持续下降但验证损失在某个点后开始上升。这意味着模型把训练数据的噪声也学进去了泛化能力变差。解决方案包括增加Dropout比率、增加更多数据、简化模型结构、使用更强的正则化。欠拟合训练损失和验证损失都很高且下降缓慢或很早就停滞了。这意味着模型太简单无法捕捉数据中的模式。解决方案包括增加网络层数或神经元数量、训练更多轮次、检查特征工程是否到位。5. 模型评估与结果深度可视化模型训练好了损失曲线也看了但这还不够。我们需要在真正的测试集模型从未见过的数据上评估它并用更丰富的可视化来“感受”模型的预测能力。5.1 定量评估在测试集上计算指标# 在测试集上进行最终评估 test_loss, test_mae model.evaluate(X_test_scaled, y_test, verbose0) print(f\n测试集评估结果:) print(f均方误差 (MSE): {test_loss:.4f}) print(f平均绝对误差 (MAE): {test_mae:.4f}) # 进行预测 y_pred model.predict(X_test_scaled).flatten() # flatten将二维数组展平为一维 # 计算R-squared (决定系数)衡量模型对目标变量方差的解释程度 from sklearn.metrics import r2_score r2 r2_score(y_test, y_pred) print(f决定系数 (R²): {r2:.4f})MSE/MAE给出了误差的绝对大小。例如MAE0.5意味着平均预测误差是0.5即5万美元。R²这个指标非常有用。它的取值范围大致在0到1之间也可能为负。R²越接近1说明模型对数据的拟合越好为0意味着模型不比直接用均值预测好为负则意味着模型拟合得非常差。一个大于0.8的R²通常被认为是不错的。5.2 核心可视化预测值 vs. 真实值这是最直观的评估图。plt.figure(figsize(10, 8)) # 绘制散点图 plt.scatter(y_test, y_pred, alpha0.5, s20, labelPredictions) # 绘制理想情况下的对角线yx max_val max(y_test.max(), y_pred.max()) min_val min(y_test.min(), y_pred.min()) plt.plot([min_val, max_val], [min_val, max_val], r--, linewidth2, labelPerfect Prediction (yx)) plt.xlabel(True Values (MedHouseVal)) plt.ylabel(Predictions (MedHouseVal)) plt.title(True Values vs. Predictions on Test Set) plt.legend() plt.grid(True, linestyle--, alpha0.7) # 添加R²和MAE文本 plt.text(0.05, 0.95, fR² {r2:.3f}\nMAE {test_mae:.3f}, transformplt.gca().transAxes, fontsize12, verticalalignmenttop, bboxdict(boxstyleround, facecolorwheat, alpha0.8)) plt.tight_layout() plt.show()如何解读这张图所有的点越靠近红色虚线yx说明预测越准确。如果点呈现明显的非线性分布如曲线说明模型可能没有捕捉到足够的非线性关系。如果点云分散得很开说明模型预测不稳定误差大。如果点云整体偏离对角线比如整体在上方或下方说明模型存在系统性偏差。5.3 误差分布可视化模型在哪里犯错只看总体误差不够我们需要看误差的分布情况。# 计算残差误差 residuals y_test - y_pred fig, axes plt.subplots(1, 2, figsize(14, 5)) # 1. 残差分布直方图 axes[0].hist(residuals, bins50, edgecolorblack, alpha0.7) axes[0].axvline(x0, colorr, linestyle--, linewidth2) axes[0].set_xlabel(Residuals (True - Predicted)) axes[0].set_ylabel(Frequency) axes[0].set_title(Distribution of Residuals) axes[0].grid(True, linestyle--, alpha0.5) # 2. 残差 vs. 预测值散点图 axes[1].scatter(y_pred, residuals, alpha0.5, s20) axes[1].axhline(y0, colorr, linestyle--, linewidth2) axes[1].set_xlabel(Predicted Values) axes[1].set_ylabel(Residuals) axes[1].set_title(Residuals vs. Predicted Values) axes[1].grid(True, linestyle--, alpha0.5) plt.tight_layout() plt.show()如何解读残差分布图理想情况下残差应该服从均值为0的正态分布钟形曲线。如果分布明显偏斜或有多个峰说明模型在某些特定情况下系统性地预测不准。残差 vs. 预测值图理想情况下点应该随机、均匀地分布在y0这条红线上下并且不随预测值的大小而改变其离散程度。如果出现“漏斗形”即预测值越大/越小残差的波动越大说明误差的方差不是恒定的异方差性这可能意味着模型在某些值域表现不稳定或者需要对目标值进行变换如取对数。5.4 特征重要性分析简易版对于神经网络这样的“黑盒”模型理解哪个特征更重要是个挑战。一个简单的方法是使用“排列特征重要性”。from sklearn.inspection import permutation_importance # 计算排列特征重要性这需要一些时间 perm_importance permutation_importance(model, X_test_scaled, y_test, n_repeats10, random_state42) # 获取重要性分数和特征名 sorted_idx perm_importance.importances_mean.argsort()[::-1] # 从高到低排序 feature_names housing.feature_names plt.figure(figsize(10, 6)) plt.barh(range(len(sorted_idx)), perm_importance.importances_mean[sorted_idx]) plt.yticks(range(len(sorted_idx)), [feature_names[i] for i in sorted_idx]) plt.xlabel(Permutation Importance (Decrease in Model Score)) plt.title(Feature Importance (via Permutation on Test Set)) plt.grid(True, axisx, linestyle--, alpha0.7) plt.tight_layout() plt.show()这个方法的原理是随机打乱某个特征在测试集中的值然后看模型性能如R²下降了多少。下降得越多说明这个特征越重要。这能帮助我们理解模型决策的依据并可能进行特征筛选。6. 模型优化与调参实战经验第一次训练的模型往往不是最好的。我们可以从以下几个方面进行优化6.1 网络结构调优深度与宽度加深网络尝试增加隐藏层的数量。对于更复杂的关系深层网络可能更有优势。例如可以尝试[128, 64, 32]这样的结构。加宽网络增加每层的神经元数量。但要注意参数数量会平方级增长容易导致过拟合。经验之谈我通常从一个适中的结构开始比如我们例子中的[64, 32]如果欠拟合就增加层数或神经元如果过拟合就减少神经元或增加Dropout。“残差连接”Residual Connection是训练深层网络的有效技巧但在简单的全连接回归网络中不常用。6.2 正则化技术对抗过拟合除了Dropout还有L1/L2 权重正则化在Dense层中添加kernel_regularizer参数惩罚大的权重值迫使模型学习更简单、更泛化的模式。layers.Dense(64, activationrelu, kernel_regularizerkeras.regularizers.l2(0.001))Batch Normalization (批归一化)在激活函数前或后加入BatchNormalization层。它能够稳定并加速训练过程有时还能起到轻微的正则化效果。model keras.Sequential([ layers.Input(shape(input_dim,)), layers.Dense(64), layers.BatchNormalization(), layers.Activation(relu), layers.Dropout(0.3), # ... 后续层 ])6.3 学习率调度更精细的控制固定的学习率可能不是最优的。我们可以使用学习率调度器在训练过程中动态调整学习率。# 定义学习率调度器 lr_scheduler keras.callbacks.ReduceLROnPlateau( monitorval_loss, # 监控验证损失 factor0.5, # 当条件触发时新学习率 旧学习率 * factor patience5, # 容忍轮次 min_lr1e-6 # 学习率下限 ) # 在model.fit的callbacks中加入这个调度器 history model.fit(..., callbacks[keras.callbacks.EarlyStopping(patience10), lr_scheduler])当验证损失在patience个轮次内没有改善时学习率会自动减半。这有助于模型在训练后期更精细地收敛到最优点。6.4 超参数系统化搜索KerasTuner手动调参效率低。可以使用KerasTuner库进行自动化超参数搜索。# 这是一个高级话题简要示例 import keras_tuner as kt def build_model_hp(hp): model keras.Sequential() model.add(layers.Input(shape(input_dim,))) # 可变的层数和神经元数 for i in range(hp.Int(num_layers, 1, 3)): model.add(layers.Dense(unitshp.Int(funits_{i}, min_value32, max_value256, step32), activationrelu)) model.add(layers.Dropout(ratehp.Float(fdropout_{i}, 0.1, 0.5, step0.1))) model.add(layers.Dense(1)) model.compile(optimizerkeras.optimizers.Adam(hp.Float(learning_rate, 1e-4, 1e-2, samplinglog)), lossmse, metrics[mae]) return model tuner kt.RandomSearch(build_model_hp, objectiveval_mae, max_trials10, executions_per_trial2, directorymy_tuning_dir, project_namehousing_regression) tuner.search(X_train_scaled, y_train, epochs50, validation_split0.2, verbose0) best_model tuner.get_best_models(num_models1)[0]这会让程序自动尝试不同的层数、神经元数、Dropout率、学习率并找出在验证集上表现最好的组合。7. 将模型投入实际使用保存、加载与预测模型训练和调优满意后我们需要保存它以便将来在新的数据上直接进行预测而无需重新训练。7.1 保存与加载模型Keras提供了非常简单的模型保存方式。# 保存整个模型包括架构、权重和优化器状态 model.save(my_housing_regression_model.keras) # 推荐使用.keras后缀 # 在另一个脚本或环境中加载模型 loaded_model keras.models.load_model(my_housing_regression_model.keras) # 验证加载的模型 loss, mae loaded_model.evaluate(X_test_scaled, y_test, verbose0) print(f加载模型的测试MAE: {mae:.4f})注意保存的模型不包含数据预处理步骤如StandardScaler你必须将scaler对象也保存下来例如使用pickle或joblib并在预测新数据时使用相同的scaler进行变换。7.2 对新数据进行预测假设我们有一条新的房屋数据特征值需要进行预测。import joblib # 1. 加载之前保存的scaler scaler joblib.load(my_scaler.pkl) # 假设你之前用 joblib.dump(scaler, my_scaler.pkl) 保存了 # 2. 准备新数据这里是一个样本 new_house_data np.array([[8.3252, 41.0, 6.984127, 1.023810, 322.0, 2.555556, 37.88, -122.23]]) # 注意是二维数组 # 3. 使用相同的scaler进行特征缩放 new_house_data_scaled scaler.transform(new_house_data) # 4. 使用加载的模型进行预测 predicted_price loaded_model.predict(new_house_data_scaled) print(f预测的房屋中位数价格: ${predicted_price[0][0]*100000:.2f})记住这个流程加载模型 - 加载预处理器 - 预处理新数据 - 预测。这是将机器学习模型部署到生产环境或提供API服务的基础。走完这一整套流程你不仅得到了一个可用的房价预测模型更重要的是你通过可视化工具从数据理解、模型训练到结果评估完整地洞察了模型的“内心世界”。这种深入的理解远比单纯调出一个高分数更重要。下次当你面对一个新的回归问题时这套从探索、构建、训练、评估到可视化的方法论就是你最可靠的工具箱。