归一化 超全总结!!
哈喽大家好~我是我不是小upper~
周末逛社区的时候,发现大家对归一化的讨论热度很高。今天咱们就来盘一盘这个机器学习里的关键预处理步骤,看看它到底为啥这么重要。
首先来说,归一化到底在做什么?
简单来说,归一化是把不同尺度、不同范围的数据(拉到同一个起跑线)上。
比如,一个特征取值范围是 0-1,另一个是 100-1000,直接丢进算法里就像让小学生和大学生一起考试,结果肯定跑偏。归一化会通过数学变换(如缩放到 0-1 区间或标准正态分布),让所有特征处于相同的度量空间。
其次,为什么说它是(算法的起跑线)?
1. 让算法跑得更快更稳
想象一下:你在凹凸不平的路上跑步(特征尺度不一),肯定比在平坦路面慢很多。
- 梯度下降类算法(如神经网络训练):尺度差异大的特征会让损失函数「形状」变得狭长,梯度更新像走迷宫,归一化后损失函数更「圆」,收敛速度可能提升数十倍。
- 实例:K-means 聚类中,若一个特征是 “年龄(0-100)”,另一个是 “收入(1000-100000)”,未归一化时算法会过度关注 “收入”,导致聚类结果失真。
2. 防止特征「贫富差距」影响结果
- 距离类算法的公平性:在 K 近邻(KNN)中,数值范围大的特征会主导距离计算。比如 “像素值(0-255)” 和 “亮度(0-1)” 未归一化时,亮度的差异可能被忽略。
- 模型权重的可信度:归一化后,特征的权重大小直接反映其重要性。例如,线性回归中,归一化后的特征权重可直接对比,未归一化的权重可能因尺度差异产生误导。
3. 数值计算的「安全网」
- 深度学习的稳定性:深层神经网络中,未归一化的数据可能导致激活函数输出值进入饱和区(如 sigmoid 的平坦区),引发梯度消失问题。
- 避免计算溢出:极端数值(如 1e10 或 1e-10)可能导致浮点运算不稳定,归一化可将数据限制在安全区间。
归一化的核心应用场景
场景 | 典型算法 | 归一化作用 |
---|---|---|
特征尺度差异大 | 线性回归、逻辑回归 | 确保特征权重合理,避免模型偏向大尺度特征 |
基于距离的计算 | KNN、K-means、SVM | 公平计算样本间距离 |
梯度优化类算法 | 神经网络(CNN/RNN) | 加速收敛,防止梯度爆炸 / 消失 |
特征重要性分析 | 树模型(需先归一化) | 权重可直接反映特征贡献度 |
四、常见误区提醒
-
归一化≠标准化:
- 归一化(Min-Max 缩放):缩放到固定区间(如 0-1),公式:
(x - min)/(max - min)
。 - 标准化(Z-score):转化为均值 0、标准差 1 的分布,公式:
(x - μ)/σ
。 - 选哪个?:数据分布无特殊要求时用归一化;存在异常值或需要概率解释时用标准化。
- 归一化(Min-Max 缩放):缩放到固定区间(如 0-1),公式:
-
不是所有算法都需要归一化:
- 不需要的场景:树模型(决策树、随机森林)、朴素贝叶斯(基于概率而非距离)。
- 必须的场景:神经网络、SVM、KNN、线性模型。
下面咱们从代码层面,说说几种不同的归一化方法,以及归一化带来的效果。
-
最小-最大归一化
-
标准化
-
小数定标归一化
-
均值归一化
-
单位长度归一化
咱们一起来看看~
1. 最小 - 最大归一化(Min-Max Normalization)。
这是一种在机器学习和数据预处理中非常实用的技术,核心是将不同尺度的数据「压缩」到统一的区间(通常是 0 到 1),让算法能公平地对待每一个特征。
1.1 最小 - 最大归一化的本质:线性缩放的魔法
最小 - 最大归一化是一种线性变换,它就像给数据量体裁衣,将原始数据的最小值映射为 0,最大值映射为 1,中间的数值按比例缩放。这个过程不会改变数据的分布形状,只会调整数据的「位置」和「跨度」。比如一组数据的原始范围是 [5, 25],经过归一化后,5 变成 0,25 变成 1,中间值 15 会变成 0.5。
1.2 公式拆解
假设原始数据集为 D,其中任意一个数据点为 x,归一化后的结果为 ,则公式为:
- 分子
:计算数据点与最小值的偏移量,相当于把数据「整体平移」,使最小值对齐到 0 点。
- 分母
:数据的总跨度(范围),用于将偏移量「压缩」到 0-1 区间。
1.3 从理论到实践:三步完成归一化
- 确定数据边界:先找出数据集的最小值
和最大值
。比如数据集是 [10, 30, 50, 70],则 min=10,max=70。
- 逐点计算缩放值:对每个数据点 x,用公式计算其归一化后的值。以数据点 30 为例:
3. 验证结果范围:确保所有归一化后的数据都落在 0-1 之间,原始最小值对应 0,最大值对应 1。
1.4 案例代码:用 Python 直观展示归一化效果
下面通过代码生成两组差异极大的数据,直观呈现归一化的缩放Power。
import numpy as np
import matplotlib.pyplot as plt# 生成两组不同尺度的数据
data_small_scale = np.random.randint(0, 100, 100) # 生成100个0到100之间的随机整数
data_large_scale = np.random.randint(1000, 10000, 100) # 生成100个1000到10000之间的随机整数# 定义最小-最大归一化函数
def min_max_normalize(data):return (data - np.min(data)) / (np.max(data) - np.min(data)) # 套用公式,自动处理数组中的每个元素# 对两组数据分别归一化
normalized_small_scale = min_max_normalize(data_small_scale)
normalized_large_scale = min_max_normalize(data_large_scale)# 可视化对比原始数据与归一化后的数据
plt.figure(figsize=(12, 6)) # 创建一个宽12英寸、高6英寸的画布# 绘制原始小尺度数据的直方图(左上图)
plt.subplot(2, 2, 1) # 将画布分为2行2列,当前绘制第1个子图
plt.hist(data_small_scale, bins=15, color='blue', alpha=0.7) # 绘制直方图,15个 bins,蓝色半透明
plt.title('Small-scale data distribution (0-100)')
plt.xlabel('Original Value')
plt.ylabel('Frequency')# 绘制原始大尺度数据的直方图(右上图)
plt.subplot(2, 2, 2)
plt.hist(data_large_scale, bins=15, color='red', alpha=0.7)
plt.title('Large-scale data distribution (1000-10000)')
plt.xlabel('Original Value')
plt.ylabel('Frequency')# 绘制归一化后小尺度数据的直方图(左下图)
plt.subplot(2, 2, 3)
plt.hist(normalized_small_scale, bins=15, color='green', alpha=0.7)
plt.title('Normalized small-scale data (0-1)')
plt.xlabel('Normalized Value')
plt.ylabel('Frequency')# 绘制归一化后大尺度数据的直方图(右下图)
plt.subplot(2, 2, 4)
plt.hist(normalized_large_scale, bins=15, color='orange', alpha=0.7)
plt.title('Normalized large-scale data (0-1)')
plt.xlabel('Normalized Value')
plt.ylabel('Frequency')plt.tight_layout() # 自动调整子图间距,避免重叠
plt.show() # 显示所有图形
1.5 归一化前后对比:尺度消失,分布留存
从可视化结果可以清晰看到:
- 原始数据的差异:
- 左上图(小尺度数据)的横轴范围是 0-100,右上图(大尺度数据)的横轴范围是 1000-10000,两者跨度相差近 100 倍,直接影响算法对特征重要性的判断。
- 归一化后的统一:
- 左下图和右下图的横轴范围都变成 0-1,无论原始数据是「小数据」还是「大数据」,归一化后都被「拉平」到相同尺度,但每个数据点的相对位置和分布形状(如峰值、离散程度)完全保留。
- 核心价值:在 K 近邻、神经网络等算法中,这种尺度统一能避免大数值特征「霸凌」小数值特征,让算法更公平地学习数据内在规律。
1.6 、延伸思考:归一化的适用场景
- 适合场景:需要保留数据原始分布、对极值不敏感的场景(如图像像素值缩放)。
- 注意事项:若数据中存在异常值(如极大值或极小值),可能导致归一化后的数据过于集中(因为
或 \(\min\) 被异常值拉高 / 拉低),此时可改用标准化(Z-Score)或稳健归一化(如分位数缩放)。
通过最小 - 最大归一化,我们为不同「语言」的特征搭建了统一的沟通桥梁,这是数据预处理中看似简单却至关重要的一步。下面几种归一化方法,咱们结合具体的算法模型来说说~
2. 标准化(Standardization)
接下来我们深入聊聊标准化(Standardization)。标准化是一种数据预处理手段,具体来说,它致力于将数据调整为均值为 0、标准差为 1 的分布形态。这一处理过程对于众多机器学习算法至关重要,原因在于这些算法往往假设所有特征都是以相同规模(例如高斯分布)进行测量的。
从公式推导来看,对于数据集里的每个特征 x,标准化可通过以下公式实现: 其中,
代表特征的平均值,
为标准差。这一转换过程确保了特征
的均值为 0,标准差为 1,让不同尺度的特征能够在同一度量空间下进行比较。
标准化的计算步骤可概括为:首先,针对数据集中的每个特征,遍历计算其均值和标准差;接着,运用上述公式对每个特征值进行转换,使其成为标准化值。
下面通过一段案例代码来直观展示标准化对模型性能的影响,我们以支持向量机(SVM)为例,借助 Python 的 scikit - learn 库实现,并使用 make_classification 生成虚拟分类数据集。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score# 生成虚拟数据集:创建一个包含1000个样本、2个特征的二维分类数据集,n_redundant=0表示无冗余特征,n_clusters_per_class=1指定每个类别一个簇,random_state=42确保结果可复现
X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_clusters_per_class=1, random_state=42)# 划分数据集:将数据集按8:2比例划分为训练集和测试集,test_size=0.2,random_state=42保证划分一致性
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 未标准化的SVM模型:直接使用原始数据训练SVM,由于SVM对特征尺度敏感,未标准化可能导致模型性能受限
model = SVC(kernel='linear')
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy_non_standardized = accuracy_score(y_test, y_pred)# 应用标准化:使用StandardScaler对数据进行标准化处理,fit_transform在训练集上拟合均值和标准差并转换数据,transform用训练集的参数转换测试集,避免数据泄露
scaler = StandardScaler()
X_train_standardized = scaler.fit_transform(X_train)
X_test_standardized = scaler.transform(X_test)# 标准化的SVM模型:用标准化后的数据训练SVM,此时特征处于同一尺度,模型能更高效地学习决策边界
model_standardized = SVC(kernel='linear')
model_standardized.fit(X_train_standardized, y_train)
y_pred_standardized = model_standardized.predict(X_test_standardized)
accuracy_standardized = accuracy_score(y_test, y_pred_standardized)# 结果展示:输出两种情况下的准确率,对比标准化对模型性能的提升
print(f'Accuracy with non - standardized data: {accuracy_non_standardized}')
print(f'Accuracy with standardized data: {accuracy_standardized}')# 可视化:绘制未标准化和标准化数据的分布情况,左图未标准化数据分布可能因尺度差异导致特征重要性失衡,右图标准化后数据分布在均值0附近,标准差1,便于SVM构建合理决策边界
plt.figure(figsize=(12, 5))plt.subplot(1, 2, 1)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train)
plt.title("Distribution of Non - Standardized Data")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")plt.subplot(1, 2, 2)
plt.scatter(X_train_standardized[:, 0], X_train_standardized[:, 1], c=y_train)
plt.title("Distribution of Standardized Data")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")plt.show()
在这段代码中,我们先生成二维虚拟分类数据集,随后训练两个 SVM 模型,一个基于未标准化数据,另一个基于标准化数据。通过对比两个模型的准确率,能清晰看到标准化对模型性能的影响。一般来说,标准化后的数据能使 SVM 等对尺度敏感的算法更好地收敛,提升分类准确率。
从图片中归一化与标准化的对比效果来看,标准化更适用于数据没有明确边界且存在异常值的情况,它能有效处理这类特征;而归一化则适用于需要严格边界的场景,有助于缩小特征值的规模。在后续学习中,大家可以通过实际模型和数据集,利用准确率、均方误差等指标更具体地展示标准化和归一化对模型性能的不同影响。在实际应用中,选择哪种预处理方法要依据数据特性和所使用的模型来决定。
3. 小数定标归一化
在机器学习中,小数定标归一化是一种通过移动数据小数点位置来调整特征值比例的预处理方法,其核心目标是将数据缩放至特定范围(通常为 - 1 到 1 或 0 到 1),使绝对值最大的数据点变为不大于 1 的数。该方法的数学逻辑紧密依赖于数据集中属性值的最大绝对值,通过对数运算和数值缩放实现特征尺度的统一。
3.1 核心原理与公式推导
小数定标归一化的核心思想是:根据数据的最大绝对值确定小数点移动位数,使所有数据除以 10 的幂次后落入目标区间。
归一化公式:
其中:
- x 为原始数据值,
为归一化后的值;
- k 是由数据最大绝对值确定的小数点移动位数,计算公式为:
表示向上取整,
是以 10 为底的对数运算。
公式逻辑: 若数据的最大绝对值为 ,则
,向上取整后 k = 3,所有数据需除以
,使最大绝对值变为
,满足归一化要求。
3.2 计算步骤详解
-
计算最大绝对值: 遍历数据集,找出所有数值的绝对值最大值
。例如,数据集 [-50, 80, 30] 的最大绝对值为 80。
-
确定小数点移动位数 k: 对最大绝对值取以 10 为底的对数,结果向上取整。
- 若
,则
,向上取整后 (k = 2)。
- 若
-
应用归一化公式: 将每个原始值除以
。例如,原始值 80 归一化后为
,-50 归一化为 -50/100 = -0.5。
3.3 案例代码与注释
以下代码通过虚拟数据集演示小数定标归一化在线性回归中的应用,直观对比归一化前后的模型性能:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error# 生成虚拟数据集:特征X为0-100的随机数,标签y与X呈线性关系并添加高斯噪声
np.random.seed(0) # 固定随机种子确保结果可复现
X = np.random.rand(100, 1) * 100 # 生成100个0-100的数值作为特征
y = 3 * X.squeeze() + 4 + np.random.randn(100) # 真实关系:y=3X+4,叠加随机噪声模拟真实场景# 定义小数定标归一化函数
def decimal_scaling_normalization(data):max_abs = np.max(np.abs(data)) # 计算数据绝对值的最大值k = np.ceil(np.log10(max_abs)) if max_abs != 0 else 1 # 防止max_abs为0时对数运算出错return data / (10 ** k) # 对数据进行缩放# 应用归一化:将原始特征X转换为归一化后的X_normalized
X_normalized = decimal_scaling_normalization(X)# 划分训练集与测试集(20%数据用于测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
X_train_norm, X_test_norm = train_test_split(X_normalized, test_size=0.2, random_state=0)# 训练线性回归模型:分别使用原始数据和归一化数据
model = LinearRegression() # 原始数据模型
model.fit(X_train, y_train) # 直接使用0-100的特征训练model_norm = LinearRegression() # 归一化数据模型
model_norm.fit(X_train_norm, y_train) # 使用归一化后(0-0.1)的特征训练# 模型评估:计算均方误差(MSE)并可视化结果
y_pred = model.predict(X_test) # 原始数据模型预测
y_pred_norm = model_norm.predict(X_test_norm) # 归一化数据模型预测mse_original = mean_squared_error(y_test, y_pred) # 原始数据MSE
mse_normalized = mean_squared_error(y_test, y_pred_norm) # 归一化数据MSE# 可视化对比:左图为原始数据拟合效果,右图为归一化数据拟合效果
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.scatter(X_test, y_test, color='blue', label='真实数据') # 绘制测试集散点图
plt.plot(X_test, y_pred, color='red', label='模型预测') # 绘制原始数据模型的预测曲线
plt.title(f"原始数据拟合 (MSE: {mse_original:.2f})")
plt.xlabel("特征X")
plt.ylabel("标签y")plt.subplot(1, 2, 2)
plt.scatter(X_test_norm, y_test, color='green', label='真实数据') # 绘制归一化后特征的散点图
plt.plot(X_test_norm, y_pred_norm, color='red', label='模型预测') # 绘制归一化数据模型的预测曲线
plt.title(f"归一化数据拟合 (MSE: {mse_normalized:.2f})")
plt.xlabel("归一化特征X'")
plt.ylabel("标签y")plt.tight_layout()
plt.show()
3.4 结果解读
-
数值对比: 归一化前后的均方误差(MSE)可能接近,因为线性回归模型对特征尺度不敏感。但在梯度下降类算法(如逻辑回归、神经网络)中,归一化通常会显著加速收敛并提升稳定性。
-
可视化直观性: 左图中特征 X 范围为 0-100,右图中归一化特征 X' 范围为 0-0.1,但两者的模型预测曲线趋势一致。归一化的价值在于统一特征尺度,避免因数值范围差异导致算法优化困难(如梯度更新不稳定)。
注意:小数定标归一化适用于特征尺度差异大且需要保留原始数据分布形态的场景,尤其适合基于距离或梯度的算法。对于树模型(如随机森林),归一化通常非必需。
4. 均值归一化
均值归一化是机器学习中重要的数据预处理技术,旨在通过调整特征尺度提升算法性能。其核心思想是将特征数据转换为以 0 为中心、特定范围波动的分布,尤其适用于基于距离度量或梯度优化的算法(如 KNN、SVM)。
4.1 核心公式与数学逻辑
均值归一化的公式为: 其中:
是归一化后的值,x 是原始数据;
是特征的均值(
);
是特征的标准差(
)。
公式本质: 通过减去均值使数据中心化,再除以标准差实现尺度缩放,最终使特征服从均值为 0、标准差为 1 的标准正态分布。例如,若特征值为 [2, 4, 6],均值,标准差:
, 则归一化后为
。
4.2 计算步骤解析
-
计算统计量: 对每个特征分别计算均值
和标准差
。例如,特征向量
的均值
,标准差
。
-
标准化转换: 将每个原始值代入公式
。上述例子中,30 归一化后 为:
。
注意:该方法与 “Min-Max 归一化” 不同,后者将数据缩放到固定区间(如 0-1),而均值归一化保留了数据分布的形状,仅调整尺度和位置。
4.3 案例代码与逐行解析
以下代码通过 KNN 算法演示均值归一化的实际效果,对比归一化前后模型准确率:
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler # 导入标准化工具(此处用于实现均值归一化逻辑)
import matplotlib.pyplot as plt# 生成虚拟数据集:1000个样本,每个样本包含2个特征,标签为0或1
np.random.seed(0) # 固定随机种子确保结果可复现
X = np.random.rand(1000, 2) # 特征X服从均匀分布,范围0-1
y = np.random.randint(0, 2, 1000) # 标签y随机生成0/1,模拟二分类问题# 划分训练集(800样本)和测试集(200样本)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 未归一化时的KNN模型
knn = KNeighborsClassifier(n_neighbors=3) # 创建KNN分类器(3近邻)
knn.fit(X_train, y_train) # 直接使用原始特征训练模型(特征范围0-1)
predictions = knn.predict(X_test) # 对测试集预测
accuracy_without_normalization = accuracy_score(y_test, predictions) # 计算未归一化的准确率# 使用均值归一化(实际调用标准化工具,因均值归一化与标准化数学逻辑一致)
scaler = StandardScaler() # 创建标准化器(计算均值和标准差)
X_train_scaled = scaler.fit_transform(X_train) # 对训练集拟合并转换(减去均值,除以标准差)
X_test_scaled = scaler.transform(X_test) # 对测试集应用相同转换(避免数据泄漏)knn.fit(X_train_scaled, y_train) # 使用归一化后的特征重新训练模型
predictions = knn.predict(X_test_scaled) # 对归一化后的测试集预测
accuracy_with_normalization = accuracy_score(y_test, predictions) # 计算归一化后的准确率# 可视化对比归一化前后的准确率
plt.bar(['Unnormalized', 'Mean Normalization'], [accuracy_without_normalization, accuracy_with_normalization])
plt.ylabel('Accuracy')
plt.title('Comparison of the accuracy of the KNN algorithm before and after mean normalization')
plt.show()
4.4 代码逻辑与结果解读
-
数据生成与划分: 特征 X 为 0-1 的均匀随机数,标签 y 随机生成,模拟真实场景下特征尺度一致的情况(因 X 本身范围相近,归一化效果可能不显著,但可通过代码演示流程)。
-
均值归一化的实现:
StandardScaler
是 sklearn 中实现标准化的工具,其本质是均值归一化(减去均值,除以标准差)。fit_transform
方法对训练集计算均值和标准差并完成转换,transform
方法对测试集使用训练集的统计量,确保数据预处理的一致性(避免测试集信息泄漏)。
-
模型性能对比:
- 在特征尺度一致的虚拟数据中,归一化前后准确率可能接近,但在真实场景(如特征尺度差异大,如 “年龄(0-100)” 和 “收入(1000-1e6)”)中,KNN 等距离敏感算法的准确率会因归一化显著提升。
- 可视化柱状图直观展示归一化对模型性能的潜在优化作用,尤其适用于特征尺度影响距离计算的算法。
总结:均值归一化通过消除特征尺度差异,使基于距离或梯度的算法更高效地学习数据模式,是预处理阶段的关键步骤之一。
5. 单位长度归一化(特征向量标准化技术)
单位长度归一化是机器学习中特征缩放的关键预处理技术,核心目标是将数据集中的特征向量调整为单位长度,使不同特征在统一尺度下参与模型计算。该技术尤其适用于基于距离度量(如余弦相似度)或梯度优化的算法(如支持向量机、神经网络),通过消除特征尺度差异对模型性能的影响,提升训练效率与预测精度。
5.1 算法原理与公式推导
单位长度归一化的数学本质是将特征向量投影到单位超球面上,使每个向量的欧几里得范数(L2 范数)为 1。具体推导如下:
定义:对于特征向量 ,其单位长度归一化后的向量
满足:
其中,
为向量
的欧几里得范数,计算公式为:
归一化后向量的每个元素为:
几何意义:归一化后的向量方向不变,但长度缩放为 1,适用于仅关注特征方向(如相关性)而不关注绝对数值的场景。
5.2 计算步骤解析
- 计算欧几里得范数:对每个特征向量
,计算其 L2 范数
。
- 特征值缩放:将向量中每个元素除以其范数,得到单位长度向量
。
5.3 案例代码与详细解释
以线性回归为例,通过虚拟数据集演示单位长度归一化对模型性能的影响,并附可视化分析:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error# 创建虚拟数据集(100个样本,3个特征)
np.random.seed(0) # 固定随机种子确保可复现性
X = np.random.rand(100, 3) # 生成0-1均匀分布的原始特征矩阵
# 构造目标变量:真实权重为[1.5, -2.0, 1.0],添加高斯噪声
y = X @ np.array([1.5, -2.0, 1.0]) + np.random.randn(100) * 0.5 # 单位长度归一化:沿样本轴(axis=1)计算每个样本的L2范数,保持维度对齐(keepdims=True)
norm_X = X / np.linalg.norm(X, axis=1, keepdims=True)
# 原理:np.linalg.norm(X, axis=1) 返回每个样本的范数向量,keepdims=True使其形状为(100,1),可直接与X相除# 数据集划分:20%作为测试集,保持归一化前后样本索引一致
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
norm_X_train, norm_X_test = train_test_split(norm_X, test_size=0.2, random_state=42)# 模型训练:原始特征训练线性回归模型
model = LinearRegression()
model.fit(X_train, y_train) # 直接使用未归一化的特征训练# 归一化特征训练模型
norm_model = LinearRegression()
norm_model.fit(norm_X_train, y_train) # 使用单位长度归一化后的特征训练# 预测与评估
y_pred = model.predict(X_test) # 原始特征模型预测
norm_y_pred = norm_model.predict(norm_X_test) # 归一化特征模型预测# 均方误差(MSE)计算
mse = mean_squared_error(y_test, y_pred)
norm_mse = mean_squared_error(y_test, norm_y_pred)# 结果输出:对比归一化前后的预测误差
print("MSE without normalization:", mse)
print("MSE with unit length normalization:", norm_mse)# 可视化分析
plt.figure(figsize=(18, 6))# 子图1:预测值与实际值对比
plt.subplot(1, 3, 1)
plt.scatter(y_test, y_pred, label='Without Normalization', alpha=0.6) # 蓝色点表示未归一化预测
plt.scatter(y_test, norm_y_pred, color='red', label='With Normalization', alpha=0.6) # 红色点表示归一化后预测
plt.title("Predictions vs True Values")
plt.xlabel("True Values")
plt.ylabel("Predictions")
plt.legend()
# 说明:理想情况下预测点应沿对角线分布,红色点更集中于对角线,表明归一化后预测更准确# 子图2:预测误差分布对比
plt.subplot(1, 3, 2)
plt.hist(y_test - y_pred, bins=15, alpha=0.7, label='Without Normalization') # 原始误差分布
plt.hist(y_test - norm_y_pred, bins=15, alpha=0.7, color='red', label='With Normalization') # 归一化后误差分布
plt.title("Prediction Error Distribution")
plt.xlabel("Prediction Error")
plt.ylabel("Frequency")
plt.legend()
# 说明:红色直方图更窄且集中于0附近,表明归一化后误差更小、分布更集中# 子图3:特征值分布对比
plt.subplot(1, 3, 3)
for i in range(X.shape[1]): # 遍历3个特征# 原始特征分布(蓝色)plt.hist(X[:, i], bins=15, alpha=0.5, label=f'Feature {i+1} Original')# 归一化后特征分布(红色)plt.hist(norm_X[:, i], bins=15, alpha=0.5, color='red', label=f'Feature {i+1} Normalized')
plt.title("Feature Distributions")
plt.xlabel("Feature Value")
plt.ylabel("Frequency")
plt.legend()
# 说明:原始特征分布在0-1区间(因rand生成),归一化后特征绝对值集中在0-1,且每个样本的特征向量长度为1
可视化结果解读
- 预测值对比:归一化后预测值(红色点)更贴近实际值(对角线),表明模型泛化能力提升。
- 误差分布:归一化后的预测误差(红色直方图)更集中于 0 附近,且方差更小,说明模型稳定性增强。
- 特征分布:原始特征值在 0-1 区间(由
np.random.rand
生成),归一化后特征值绝对值被压缩至 0-1,且每个样本的特征向量满足。
结论:单位长度归一化通过消除特征尺度差异,显著提升了线性回归模型的预测精度与稳定性,验证了数据预处理在机器学习中的关键作用。
最后
归一化是梯度下降类算法的刚需,对树模型影响有限
先验知识决定方法选择:图像像素用 Min-Max,金融数据用 Z-score
工程实现中务必遵循 “训练集拟合,测试集转换” 原则,避免数据泄漏
通过深入理解归一化的数学原理与算法适配性,可显著提升模型训练效率与泛化能力,尤其在多特征、高维数据场景中,归一化是通往高性能模型的必经之路。
下面给个流程图方便你们更好的理解: