即feature scaling
当样本的一个特征与另一个特征之间的数值差距过大,样本之间的距离计算容易被大数值(较大的量纲)的特征主导,直接计算距离会导致不能均衡反映每一个特征对于样本之间距离计算的重要程度,如下图所示。
所以需要将数据进行归一化。
解决方案
最值归一化(normalization)
把所有数据映射到0-1之间
该方法受适用于有明显边界的情况(成绩),明显边界指的是数据样本之间的差值,不是特别大。即大家都比较均匀的分布在一个空间内。而不是一群人在一小块地方,一个人在特别远的一个地方(收入)。也就是受outliter(离群点)影响比较大。否则归一化后会形成有偏的数据。
自己实现案例:
import numpy as np
x = np.random.randint(1, 100, size=100)
new_x = (x - np.mean(x)) / (np.max(x) - np.min(x))
print(x)
print(new_x)
对于矩阵的话就把特征一列一列取出来就行
sklearn实现
from sklean.preprocession import MinMaxScaler
均值方差归一化/标准化(standardization)
把所有的数据归一到均值为0,方差为1的分布中。适用于数据分布没有明显的边界:即有可能存在极端数据值。也同样也适用于有明显边界的情况。
所以一般来说,我们 直接使用这个万能的标准化 就可以了。
公式:
S指的是方差,注意的是,不论是标准化还是最值归一化,他们都是对单列数据进行归一化。
sklearn实现案例
类实现
import numpy as np
class StandardScaler:
def __init__(self):
self.mean_ = None
self.mean_ = 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 eqal 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.std_[col]
return resX