特征标准化
特征标准化:feature normalization
又叫数据标准化、正规化、正常化、归一化,normalization(或scale)
数据的偏差和跨度过大(特征量级相差过大,或明显不遵从高斯分布)会影响机器学习的效果,把数据正规化(标准化)后可以提升机器学习准确率
现实中的数据,特征之间的数据范围往往差距悬殊,
如果用线性回归方程预测房屋价格,a、b/c就是机器学习需要优化的参数
房屋预测价格 = a*离市中心距离 + b*楼层 + c*面积 + d
误差 = 预测价格 - 实际价格
- 机器学习计算预测值和实际值的差异,然后对误差做数学处理
- 上面公式里,面积很大,50-300,距离很小0.5-10(km),如果都参与运算,则距离对结果的贡献比面积大的多,
- (距离变化一点,价格变化不大,面积变化一点,价格变化很大
- 为了均衡各特征的跨度,使各特征数据跨度统一,需要正规化特征
import numpy as np
import matplotlib.pyplot as plt
np.set_printoptions(suppress=True) # 不用科学计数法输出数据(方便直观比较数据)
# 三个特征
X = np.array([[10, 2.7, 3.6],[-100, 5, -2],[120, 20, 40]])
X
array([[ 10. , 2.7, 3.6],
[-100. , 5. , -2. ],
[ 120. , 20. , 40. ]])
plt.figure(figsize=(11, 3))
plt.subplot(1,3,1)
plt.scatter(X[:, 0], X[:, 1])
plt.subplot(1,3,2)
plt.scatter(X[:, 0], X[:, 2])
plt.subplot(1,3,3)
plt.scatter(X[:, 1], X[:, 2])
<matplotlib.collections.PathCollection at 0x903b160>
output_3_1.png
方法1:
standard deviation normalization:
- 适合没有明显边界、可能有极端值的数据,如人群收入,大部分人很少,个别人很大
- 有明显边界的数据,如考试成绩,也适用于这种方法
将特征数据缩放成 平均值为0,方差为1
公式为:(x - x_mean) / x_std
忽略特征数据的原分布形状,移除每个特征的均值,划分离散特征的方差,实现数据中心化
# 手动正规化
X2 = (X - X.mean(axis=0)) / X.std(axis=0)
X2
array([[ 0. , -0.85170713, -0.55138018],
[-1.22474487, -0.55187146, -0.852133 ],
[ 1.22474487, 1.40357859, 1.40351318]])
plt.figure(figsize=(11, 3))
plt.subplot(1,3,1)
plt.scatter(X2[:, 0], X2[:, 1])
plt.subplot(1,3,2)
plt.scatter(X2[:, 0], X2[:, 2])
plt.subplot(1,3,3)
plt.scatter(X2[:, 1], X2[:, 2])
<matplotlib.collections.PathCollection at 0x62f8438>
output_6_1.png
自动正规化
from sklearn import preprocessing # 数据标准化模块
preprocessing.scale(X)
# 参数设置
# X:特征数据
# axis:数组的轴(维度)
# 将数据均值规范到0
# 将数据方差规范到1
preprocessing.scale(X, axis=0, with_mean=True, with_std=True)
array([[ 0. , -0.85170713, -0.55138018],
[-1.22474487, -0.55187146, -0.852133 ],
[ 1.22474487, 1.40357859, 1.40351318]])
方法2:
min max normalization:适用于数据有明显边界的情况,如学生成绩,边界为0-100分
将特征数据按比例缩放到0-1区间之间,(也可以是-1到1)
公式:(x - Min) / (Max - Min)
对于方差非常小的属性可以增强其稳定性
维持稀疏矩阵中为0的条目
X.max(), X.min()
(120.0, -100.0)
X3 = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X3
array([[0.5 , 0. , 0.13333333],
[0. , 0.13294798, 0. ],
[1. , 1. , 1. ]])
X3.max(), X3.min()
(1.0, 0.0)
plt.figure(figsize=(11, 3))
plt.subplot(1,3,1)
plt.scatter(X3[:, 0], X3[:, 1])
plt.subplot(1,3,2)
plt.scatter(X3[:, 0], X3[:, 2])
plt.subplot(1,3,3)
plt.scatter(X3[:, 1], X3[:, 2])
<matplotlib.collections.PathCollection at 0x9f4ce80>
output_14_1.png
# 自动计算
preprocessing.MinMaxScaler().fit_transform(X)
array([[0.5 , 0. , 0.13333333],
[0. , 0.13294798, 0. ],
[1. , 1. , 1. ]])