机器学习:数据归⼀化(Scaler)
数据归⼀化(Feature Scaling)
⼀、为什么要进⾏数据归⼀化
原则:样本的所有特征,在特征空间中,对样本的距离产⽣的影响是同级的;
问题:特征数字化后,由于取值⼤⼩不同,造成特征空间中样本点的距离会被个别特征值所主导,⽽受其它特征的影响⽐较⼩;
例:特征1 = [1, 3, 2, 6, 5, 7, 9],特征2 = [1000, 3000, 5000, 2000, 4000, 8000, 3000],计算两个样本在特征空间的距离时,主要被特征2所决定;
定义:将所有的数据(具体操作时,对每⼀组特征数据进⾏分别处理)映射到同⼀个尺度中;
归⼀化的过程,是算法的⼀部分;
⼆、数据归⼀化的⽅法
1)最值归⼀化(normalization)
1、思路:把所有数据映射到0~1之间;
2、公式:
正则化 归一化 # x为数据集中每⼀种特征的值;
# 将数据集中的每⼀种特征都做映射;
3、特点:多适⽤于分布有明显边界的情况;如考试成绩、⼈的⾝⾼、颜⾊的分布等,都有范围;⽽不是些没有范围约定,或者范围⾮常⼤的数据;
# 明显边界:同⼀特征的数据⼤⼩相差不⼤;不会出现⼤部分数据在0~200之间,有个别数据在100000左右;
4、缺点:受outlier影响较⼤;
2)Z-score(standardization)
1、思路:把所有数据归⼀到均值为0⽅差为1的分布中;
2、公式:Xscale = (X - Xmean ) / σ
# Xmean:特征的均值(均值就是平均值);
# σ:每组特征值的标准差;
# X:每⼀个特征值;
# Xscale:归⼀化后的特征值;
3、特点1:使⽤于数据分布没有明显的边界;(有可能存在极端的数据值)
# 归⼀化后,数据集中的每⼀种特征的均值为0,⽅差为1;
4、优点(相对于最值归⼀化):即使原数据集中有极端值,归⼀化有的数据集,依然满⾜均值为0⽅差为1,不会形成⼀个有偏的数据;
三、训练数据集的归⼀化
1)最值归⼀化:
import numpy as np
# 对⼀维向量做归⼀化
x = np.random.randint(0, 100, size = 100)
x = np.array(x, dtype=float)
x = (x - np.min(x)) / (np.max(x) - np.min(x))
# 对⼆维矩阵做归⼀化
X = np.random.randint(0, 100, (50, 2))
X = np.array(X, dtype=float)
# 分别对每⼀列进⾏最值归⼀化,⽅式与向量做最值归⼀化⼀样
2)均值⽅差归⼀化:
import numpy as np
X2 = np.random.randint(0, 100, (50, 2))
X2 = np.array(X2, dtype=float)
X2[:,0] = (X2[:,0] - np.mean(X2[:,0])) / np.std(X2[:,0])
X2[:,1] = (X2[:,1] - np.mean(X2[:,1])) / np.std(X2[:,1])
# np.mean(array):求向量的平均值;
# np.std(array):求向量的标准差;
四、测试数据集的归⼀化
1)问题
训练数据集归⼀化,⽤于训练模型,测试数据集如何归⼀化?
2)⽅案
不能直接对测试数据集按公式进⾏归⼀化,⽽是要使⽤训练数据集的均值和⽅差对测试数据集归⼀化; 3)原因
原因1:真实的环境中,数据会源源不断输出进模型,⽆法求取均值和⽅差的;
原因2:训练数据集是模拟真实环境中的数据,不能直接使⽤⾃⾝的均值和⽅差;
原因3:真实环境中,⽆法对单个数据进⾏归⼀化;
# 对数据的归⼀化也是算法的⼀部分;
4)⽅式
(X_test - mean_train) / std_train
1. X_test:测试数据集;
2. mean_train:训练数据集的均值;
3. std_train:训练数据集的标准差;
五、使⽤scikit-learn中的Scaler类
1)调⽤的步骤
scikit-learn中将训练数据集的均值和⽅差封装在了类Scalar中;
1. fit:根据训练数据集获取均值和⽅差,scikit-learn中返回⼀个Scalar对象;
2. transform:对训练数据集、测试数据集进⾏归⼀化;
2)代码实现
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 1)归⼀化前,将原始数据分割
ain_test_split import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, seed = 666)
# 2)导⼊均值⽅差归⼀化模块:StandardScaler
from sklearn.preprocessing import StandardScaler
# 实例化,不需要传⼊参数
standardScaler = StandardScaler()
# 3)fit过程:返回StandardScaler对象,对象内包含训练数据集的均值和⽅差
# fit过程,传⼊训练数据集;
standardScaler.fit(X_train)
# 输出:StandardScaler(copy=True, with_mean=True, with_std=True)
# fit后可通过standardScaler查看均值和标准差
# an_:查看均值
# standardScaler.scale_:查看标准差
# 4)transform:对训练数据集和测试数据集进⾏归⼀化,分别传⼊对应的数据集
# 归⼀化并没有改变训练数据集,⽽是⼜⽣成⼀个新的矩阵,除⾮将新⽣成的数据集赋给原数据集,⼀般不改变原数据
X_train_standard = ansform(X_train)
X_test_standard = ansform(X_test)
# 接下来就是使⽤归⼀化后的数据集训练并测试模型
3)注意
1. 步骤:数据分割——导⼊并实例化归⼀化模块——fit(得到均值和⽅差)——transform(得到归⼀化后的数据集);
2. 实例化StandardScaler()时,不需要传⼊参数;
3. 归⼀化并没有改变数据集,⽽是⼜⽣成⼀个新的矩阵,⼀般不要改变原数据;
4)实现scikit-learn的StandardScaler类中的内部逻辑
import numpy as np
class StandardScaler:
def__init__(self):
self.scale_ = None
def fit(self, X):
"""根据训练数据集获取均值和标准差"""
assert X.ndim == 2,"the dimension of X must be 2"
self.scale_ = np.array([np.std(X[:,i]) for i in range(0,X.shape[1])])
return self
def transform(self, X):
"""将X根据这个StandardScaler进⾏均值⽅差归⼀化处理"""
assert X_train.ndim == 2, "the dimension of X_train must be 2"
an_ is not None and self.scale_ is not None,\
"must fit before transform"
assert X.shape[1] == an_),\
"the feature number of X must be equal to mean_ and std_"
reasX = np.empty(shape=X.shape, dtype=float)
for col in range(X.shape[1]):
resX[:,col] = (X[:,col] - an_[col]) / self.scale_[col]
return resX
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论