Python数据预处理-数据标准化(归一化)及数据特征转换

一、数据标准化(归一化)

首先,数据标准化处理主要包括数据同趋化处理(中心化处理)和无量纲化处理。
同趋化处理主要解决不同性质数据问题,对不同性质指标直接加总不能正确反映不同作用力的综合结果,须先考虑改变逆指标数据性质,使所有指标对测评方案的作用力同趋化,再加总才能得出正确结果。
无量纲化处理主要为了消除不同指标量纲的影响,解决数据的可比性,防止原始特征中量纲差异影响距离运算(比如欧氏距离的运算)。它是缩放单个样本以具有单位范数的过程,这与标准化有着明显的不同。简单来说,标准化是针对特征矩阵的列数据进行无量纲化处理,而归一化是针对数据集的行记录进行处理,使得一行样本所有的特征数据具有统一的标准,是一种单位化的过程。
即标准化会改变数据的分布情况,归一化不会,标准化的主要作用是提高迭代速度,降低不同维度之间影响权重不一致的问题。

数据标准化(归一化)的方法有很多种,常用的有"最小-最大标准化"、"Z-score标准化"和"按小数定标标准化"等等。经过标准化处理后,原始数据均转换为无量纲化指标测评值,即各指标值都处于同一个数量级别上,可以进行综合测评分析。

本篇只介绍常用的三种常见的转换方法:

1. 极值法(区间缩放法)

    线性比例变换法:正向指标:y = (x)/(max),即新数据=(原数据)/(最大值)。
                                 负向指标:y = (min)/(x),即新数据=(最小值)/(原数据)。

    极差变换法:正向指标:y = (x- min)/(max - min),即新数据=(原数据-最小值)/(最大值-最小值)。
                          负向指标:y = (max - x)/(max - min),即新数据=(最大值-原数据)/(最大值-最小值)。
    使用这种方法的目的包括:
       1、即0-1标准化,又称最大值-最小值标准化,核心要义是将原始指标缩放到0~1之间的区间内,但不改变原始数据的分布
       1、对于方差非常小的属性可以增强其稳定性;
       2、维持稀疏矩阵中为0的条目。

2. 比重法

    L2正则化:y = x/sqrt(Σx^2),即新数据=(原数据)/sqrt(平方和),被称为L2正则转换。
    正则化则是通过范数规则来约束特征属性,通过正则化我们可以降低数据训练处来的模 型的过拟合可能,和机器学习中所讲述的L1、L2正则的效果一样。在进行正则化 操作的过程中,不会改变数据的分布情况,但是会改变数据特征之间的相关特性。

3. 标准化
    Z-score:y = (x - mean)/σ,基于原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化,经过处理的数据符合标准正态分布,即均值为0,标准差为1。

4. 二值化

对于定量数据(特征取值连续),根据给定的阈值将其进行转换,如果大于阈值赋值为1,否则赋值为0;对于定性数据(特征取值离散,也有可能是文本数据),根据给定规则将其进行转换,符合规则的赋值为1,否则赋值为0。

二、特征转换

特征转换主要指将原始数据中的字段数据进行转换操作,从而得到适合进行算法 模型构建的输入数据(数值型数据),在这个过程中主要包括但不限于以下几种数据的处理: 文本数据转换为数值型数据、缺省值填充、定性特征属性哑编码、定量特征属性二值化、特征标准化与归一化

  • 文本特征属性转换:机器学习的模型算法均要求输入的数据必须是数值型的,所以对于文本类型的特 征属性,需要进行文本数据转换,也就是需要将文本数据转换为数值型数据。常 用方式如下: 词袋法(BOW/TF)、TF-IDF(Term frequency-inverse document frequency)、HashTF、Word2Vec(主要用于单词的相似性考量)。
  • 缺省值填充:缺省值是数据中最常见的一个问题,处理缺省值有很多方式,主要包括以下四个 步骤进行缺省值处理: 确定缺省值范围->去除不需要的字段->填充缺省值内容->重新获取数据。
  • 哑编码(OneHotEncoder):也称哑变量处理,对于定性的数据(也就是分类的数据),可以采用N位的状态寄存器来对N个状态进行编码,每个状态都有一个独立的寄存器位,并且在任意状态下只有一位有效;是一种常用的将特征数字化的方式。比如有一个特征属性:['male','female'],那么male使用向量[1,0]表示,female使用[0,1]表
  • 二值化:第一节已经说明。
  • 标准化(归一化):第一节已经说明。
# Python相关代码:
# 注意:代码只是展示方法,并不是连贯的,实际数据处理的时候需要调整
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
import pandas as pd
import numpy as np

# 数据标准化(归一化)
iris = load_iris()
iris_data = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])
iris_data['Species'] = iris['target']
# 将字符串转化为数字,用pd.Categorical
# pd.Categorical(data)
# iris_data['Species'] = iris_data["Species"].map({0:"setosa",1:"versicolor",2:"virginica"})
X, y = iris_data.iloc[:, :-1], iris_data.iloc[:, -1]
train_data, test_data, train_target, test_target = train_test_split(X, y, test_size=0.25, stratify=y)

# 数据清洗
# 重复值处理
print('存在' if any(train_data.duplicated()) else '不存在', '重复观测值')
train_data.drop_duplicates()
# 缺失值处理
print('存在' if any(train_data.isnull()) else '不存在', '缺失值')
train_data.dropna()  # 直接删除记录
train_data.fillna(method='ffill')  # 前向填充
train_data.fillna(method='bfill')  # 后向填充
train_data.fillna(value=2)  # 值填充
train_data.fillna(value={'sepal length (cm)':train_data['sepal length (cm)'].mean()})  # 统计值填充
# 异常值处理
data1 = train_data['sepal length (cm)']
# 标准差监测
xmean = data1.mean()
xstd = data1.std()
print('存在' if any(data1>xmean+2*xstd) else '不存在', '上限异常值')
print('存在' if any(data1<xmean-2*xstd) else '不存在', '下限异常值')
# 箱线图监测
q1 = data1.quantile(0.25)
q3 = data1.quantile(0.75)
up = q3+1.5*(q3-q1)
dw = q1-1.5*(q3-q1)
print('存在' if any(data1> up) else '不存在', '上限异常值')
print('存在' if any(data1< dw) else '不存在', '下限异常值')
data1[data1>up] = data1[data1<up].max()
data1[data1<dw] = data1[data1>dw].min()
# 0-1标准化
X_train_minmax = preprocessing.minmax_scale(train_data, feature_range=(0, 1), axis=0, copy=True)  # 直接用标准化函数
min_max_scaler = preprocessing.MinMaxScaler()  # 也可以用标准化类,然后调用方法
X_train_minmax2 = min_max_scaler.fit_transform(train_data)

# z-score标准化
X_train_zs = preprocessing.scale(train_data, axis=0, with_mean=True, with_std=True, copy=True)  # 直接用标准化函数
zs_scaler = preprocessing.StandardScaler()  # 也可以用标准化类,然后调用方法
X_train_zs2 = zs_scaler.fit_transform(train_data)

# 归一化处理
X_train_norm = preprocessing.normalize(train_data, norm='l2', axis=1)  # 直接用标准化函数
normalizer = preprocessing.Normalizer()  # 也可以用标准化类,然后调用方法
X_train_norm2 = normalizer.fit_transform(train_data)

# 数据的缩放比例为绝对值最大值,并保留正负号,即在区间[-1, 1]内。唯一可用于稀疏数据scipy.sparse的标准化
X_train_ma = preprocessing.maxabs_scale(X, axis=0, copy=True)

# 通过 Interquartile Range(IQR) 标准化数据,即四分之一和四分之三分位点之间
X_train_rb = preprocessing.robust_scale(train_data, axis=0, with_centering=True, with_scaling=True, copy=True)

# 二值化
X_train_binary = preprocessing.binarize(train_data, threshold=0, copy=True)  # 按照阈值threshold将数据转换成成0-1,小于等于threshold为 0

# 亚编码操作
encoder = preprocessing.OneHotEncoder()
X_OH = encoder.fit_transform(train_data)  #
df = pd.DataFrame(X_OH.toarray())
print(df.head(5))

# 缺失值插补
x = [[np.nan, '1', '3'], [np.nan, '3', '5']]
imputer = preprocessing.Imputer(missing_values='NaN', strategy='mean', axis=1)
y = imputer.fit_transform(x)

# 根据分位点将特征转换成均匀分布或正态分布
# preprocessing.quantile_transform()
# 和 OneHotEncoder 类似,将类别特征转换为多维二元特征,并将每个特征扩展成用一维表示
# preprocessing.label_binarize()
# 多项式转换
# preprocessing.PolynomialFeatures
# 增加一列伪特征
# preprocessing.add_dummy_feature()
# 核函数
# a=preprocessing.KernelCenterer

最后简要介绍下增维/降维方法,以及特征选择相关建议,后续如果用上会在详细补充:
1. 增唯方法
多项式扩展:多项式数据变换主要是指基于输入的特征数据按照既定的多项式规则构建更多的 输出特征属性,比如输入特征属性为[a,b],当设置degree为2的时候,那么输出 的多项式特征为[1, a, b, a^2, ab, b^2]
核函数:高维空间到低维空间的映射
GBDT+LR:认为每个样本在决策树落在决策树的每个叶子上就表示属于一个类别, 那么我们可以进行基于GBDT或者随机森林的维度扩展,经常我们会将其应用在GBDT将数据进行维度扩充, 然后使用LR进行数据预测。

2. 降维方法

PCA、LDA

3. 特征选择

在选择模型的过程中,通常从两方面来选择特征:
    1. 特征是否发散:如果一个特征不发散,比如方差接近于0,也就是说这样的特征对于样本的区分没有什么作用。
    2. 特征与目标的相关性:如果与目标相关性比较高,应当优先选择。
    特征选择的方法主要有以下三种:

  • Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,从而选择特征;常用方法包括方差选择法、相关系数法、卡方检验、 互信息法等。
  • Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征或者排除若干特征;常用方法主要是递归特征消除法。
  • Embedded:嵌入法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权重系数,根据系数从大到小选择特征;常用方法主要是基于惩罚项的特征选择法。

部分内容参考网址:https://cloud.tencent.com/developer/article/1111767

发布了49 篇原创文章 · 获赞 95 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/Trisyp/article/details/89371094