具体将这种归一化算法用在我们机器学习过程中的时候有一个很重要的注意事项。
对应我们原始数据集,我们要将他们拆分成训练数据集和测试数据集
如果我们要用归一化数据来训练我们的模型显然我们先要对训练数据集进行归一化处理
我们相应就要求出我们训练数据集对于的均值mean_train 方差std_train
最终我们要那我们这个模型来预测数据,对于这个测试数据集也要进行归一化处理
那么对于测试数据集如何归一化处理,(我们对整个测试数据集求下他的均值mean_test和std_test,用这两个值进行归一化,然后将这个测试数据集送给模型进行预测不就可以了吗? ×错)
我们正确的做法是,应该吧测试数据集使用训练数据及的mean_train和std_train相应进行归一化
来得到均值方差归一化的结果
原因在于:我们划分了一部分原始数据作为测试数据集,对于这部分测试集我们确实很容易得到他的均值和方差,但是我们训练出这个模型是为了让他使用在正式环境中,可是很多时候在真实环境中,我们是无法得到所有测试数据相应的均值和方差的
举个简单例子:比如对应鸢尾花识别来说,虽然我们可以得到测试数据中所有的鸢尾花相应的平均的特征,但是在实际使用的时候,我只是每次来一朵花,请问来的这朵花对应的均值和方差是多少?我们是无法获得这样的统计数据的。因此实际上在统计数据中来了新的鸢尾花我们要将这朵新的鸢尾花他的特征归一化只能让他减去我们训练数据集对应的mean_train再除以训练数据集对应的方差。另外一点将数据进行归一化也是算法的一部分,换句话说我们可以理解成算法就包括把所有的数据减去mean_train再除以std_train针对后面来的所有数据我们应该也使用同样的方式来进行处理然后来测试他的准确度,得到的才是我们自己做的这个算法他对应的准确度
测试数据是模拟真实环境
·真实环境很有可能无法得到所有测试数据的均值和方差
·对数据的归一化也是算法的一部分
理解上面这一点我们就知道了我们需要:保存训练数据集得到的均值和方差
为了方便进行这部操作在scikit-learn对于数据归一化使用Scalar
sickit-learn封装里面就是想办法让Scalar这个类和我们的机器学习算法这个类使用的流程是一致的
这个是Scaler这个类的使用流程
整个过程就是我们将训练数据集传入这个类中,这个Scalar也有一个fit算法
这个fit算法就是求出这个训练数据集对应的一些统计指标,比如说均值和方差
之后我们Scaler保存了关键信息再来其他的样例之后,我们的Scalar就可以对输入的样例进行tranform得到相应的输出结果
我们整个流程其实就是对机器学习来说的predict改成了transform这样我们就可以方便地使用我们的这个Scalar对后续的样本进行归一化进而在送进自己的机器学习算法中进行预测处理
我们就这10行矩阵并没有归一化处理
我们现在归一化处理
我们分成训练数据及和测试数据集
我们用scikit-learn中的StandardScaler来进行均值方差归一化的相应Scaler
从这个包中加载StandardScaler
preprocessing顾名思义就是数据预处理
我们的Scalar在归一化实际上就是在预处理中这样一个包中夹在我们StandardScaler
我们有了这个类首先来创立这个类的实例叫做standardScaler
输入fit后把自身返回回来
现在我们的standardScaler中存放了我们均值方差归一化所对应的关键的信息,根据我们的X_train计算出来的
包括均值(下划线表示用户穿进去的数据计算出来的变量,用户可以随时从外面进行查询)
这是方差
不过提示了std_将被弃用
叫做scale_,其实scale可以理解成描述数据分布范围的一个变量
我们用transform方法对我们的数据进行处理
他的返回矩阵就是怼整个X矩阵进行归一化处理的结果
但是X_train本身实际没有改变
一定要用赋值语句才会改变
我们同样用这个StandardScaler对我们X_test
我们现在对归一化的数据进行kNN分类
看到我们分类的准确度是100%
因为我们鸢尾花数据集比较小
当我们用归一化的数据集来训练我们算法我们在具体预测的时候 我们的测试数据集必须同样的进行归一化处理。
我们绝对不能不进行归一化处理
调用原来的只有1/3准确率,因为我们传进去的测试数据集没有归一化处理
我们实现自己的StandardScaler
import numpy as np
class StandardScaler:
//用户不需要传入任何信息,我们只需要将mean设置None同时scale=None注意下划线
def __init__(self):
self.mean_ = None
self.scale_ = None
//只处理二维数据
def fit(self, X):
"""根据训练数据集X获得数据的均值和方差"""
assert X.ndim == 2, "The dimension of X must be 2"
self.mean_ = np.array([np.mean(X[:,i]) for i in range(X.shape[1])])
self.scale_ = np.array([np.std(X[:,i]) for i in range(X.shape[1])])
return self
def transform(self, X):
"""将X根据这个StandardScaler进行均值方差归一化处理"""
assert X.ndim == 2, "The dimension of X must be 2"
assert self.mean_ is not None and self.scale_ is not None, \
"must fit before transform!"
assert X.shape[1] == len(self.mean_), \
"the feature number of X must be equal to mean_ and std_"
resX = np.empty(shape=X.shape, dtype=float)
for col in range(X.shape[1]):
resX[:,col] = (X[:,col] - self.mean_[col]) / self.scale_[col]
return resX