由于翻译、以讹传讹以及一些巧合,这几个概念有点乱,尝试整理一下。
1. 归一化Normalization
有的翻译成正常化,可以理解,但翻译成标准化就离谱了。英文本身倒是没有一
,但从效果来看,做到了归一。能够归到0~1范围的,都可以叫做广义的归一化。
1.1 区间缩放
也叫缩放归一化,很好理解,x' = (x-min)/(max-min)
,显然区间映射到了[0, 1]
。
from sklearn.preprocessing import MinMaxScaler
MinMaxScaler().fit_transform(my_data)
也可以使用pandas
的操作:
df = (df - df.min()) / (df.max() - df.min())
1.2 狭义归一化normailize
一般对行向量进行操作,使之成为单位向量。
from sklearn.preprocessing import Normalizer
Normalizer().fit_transform(my_data)
处理成DataFrame
,可以验证一下:
df.apply(lambda row: sum(row**2), axis=1) # 全等于1
2. 标准化Standardization
一般指Z-score
标准化,是按照每列进行处理的,x' = (x-x.mean())/x.std()
,因为出现了标准差吧,所以叫标准化。减去均值把数据都移到了0周围,除以标准差(代表数据的差异幅度),消除了自身特征的尺度,各个维度的特征一视同仁,并且把太挤的散开,太散的聚起来。标准化后的数据均值为0,标准差为1。如果本身是正态分布的话,标准化后就变成标准正太分布。
from sklearn.preprocessing import StandardScaler
StandardScaler().fit_transform(my_data)
也可以使用pandas
的操作,注意样本标准差的区别:
# 默认为样本标准差ddof=1, 计算整体标准差, 可令ddof=0
df = (df - df.mean())/df.std(ddof=0)
也有叫做标准差归一化的,个人觉得不妥,因为根本没有归到一。
3. 正则化Regularization
这其实不属于数据的预处理,可以认为所有减小过拟合的手段都叫做正则化,比如损失函数里增加一个L2
范数正则项。混乱的原因猜测如下:
- 范数的英文叫
norm
,这跟归一化normalization
很像。 - 深度学习的
批量归一化
叫Batch Normalization
,是一种很重要的正则化方法。 - 正态分布的正态叫
normal
,切记:标准化之后不一定是正态分布。
4. 白化Whitening
主要是消除特征间的相关性,比之前的稍微复杂一些,以PCA
白化为例。首先作主成分分析PCA
,分离出方差大但互相不相关的特征,降维,把topK
不相关的成分,作为新的特征,然后把原数据映射到新的特征空间上。
from sklearn.decomposition import PCA
K = 5
pca = PCA(n_components=K, whiten=True)
result = pca.fit_transform(my_data)
另有ZCA
白化,不展开了。
5. 其它
5.1 离散化
最简单的二值化:
from sklearn.preprocessing import Binarizer
Binarizer(threshold=3).fit_transform(my_data)
可以用KBinsDiscretizer
进行离散化,也可以用pandas
的cut
或者qcut
进行分箱。
5.2 独热化
就是把值改成独热编码one-hot
,操作的时候注意,只对值比较少的列进行操作,不然一下子挤爆内存,可以统计一下频率,只对前几名进行编码,其它的统一给一个other
的分类。
from sklearn.preprocessing import OneHotEncoder
OneHotEncoder().fit_transform(my_data.reshape((-1,1)))
# <... in Compressed Sparse Row format>
还可以使用pd.get_dummies
进行独热化。
5.3 多值化
相对于独热化,可以叫做multi-hot
,也是形成0-1矩阵,这个没有直接的方法,需要多步操作。
import pandas as pd
df = pd.DataFrame([[1, 'a,b'], [2, 'b,c'], [3, 'a,c,d']],
columns=['num', 'types'])
# 统计出所有类型
all_types = []
for x in df.types:
all_types.extend(x.split(','))
unique_types = pd.unique(all_types)
# 构造矩阵,遍历赋值
dummies = pd.DataFrame(np.zeros((len(df), len(unique_types))),
columns=unique_types)
for i, type_ in enumerate(df.types):
indices = dummies.columns.get_indexer(type_.split(','))
dummies.iloc[i, indices] = 1
df = df.join(dummies.add_prefix('type_'))
效果如下:
image.png
网友评论