简单的数据预处理和特征工程

本文参考《数据科学家联盟》饼干文章。

一、无量纲化:最值归一化、均值方差归一化及sklearn中的Scaler

在量纲不同的情况下,不能反映样本中每一个特征的重要程度时,将需要使用归一化方法。

一般来说解决方法为把所有的数据都映射到同一个尺度(量纲)上。

1、常用的数据归一化有两种:

最值归一化(normalization)

 把所有数据映射到0-1之间。最值归一化的使用范围是特征的分布具有明显边界的(分数0~100分、灰度0~255),受outlier的影响比较大

均值方差归一化(standardization):

 把所有数据归一到均值为0方差为1的分布中。适用于数据中没有明显的边界,有可能存在极端数据值的情况.

 2、sklearn中的Scaler

建模时要将数据集划分为训练数据集&测试数据集。

训练数据集进行归一化处理,需要计算出训练数据集的均值mean_train和方差std_train。

问题是:我们在对测试数据集进行归一化时,要计算测试数据的均值和方差么?

答案是否定的。在对测试数据集进行归一化时,仍然要使用训练数据集的均值train_mean和方差std_train。这是因为测试数据是模拟的真实环境,真实环境中可能无法得到均值和方差,对数据进行归一化。只能够使用公式(x_test - mean_train) / std_train并且,数据归一化也是算法的一部分,针对后面所有的数据,也应该做同样的处理.

因此我们要保存训练数据集中得到的均值和方差。

在sklearn中专门的用来数据归一化的方法:StandardScaler。

###下载数据集

import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split

iris = datasets.load_iris()
X = iris.data
y = iris.target
X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.2,random_state=666)

###归一化
from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
# 归一化的过程跟训练模型一样
standardScaler.fit(X_train)
standardScaler.mean_
standardScaler.scale_   # 表述数据分布范围的变量,替代std_

# 使用transform
X_train_standard = standardScaler.transform(X_train)
X_test_standard = standardScaler.transform(X_test)

二、缺失值处理

1、确定缺失值范围

对每个字段都计算其缺失值比例,然后按照缺失比例和字段重要性,分别制定策略,可用下图表示:

2、去除不需要的字段

建议清洗每做一步都备份一下,或者在小规模数据上试验成功再处理全量数据。

3、填充缺失内容

1)人工填充(filling manually)

根据业务知识来进行人工填充。

2)特殊值填充(Treating Missing Attribute values as Special values)

将空值作为一种特殊的属性值来处理,它不同于其他的任何属性值。如所有的空值都用“unknown”填充。一般作为临时填充或中间过程。

df['Feature'].fillna('unknown', inplace=True)

3)统计量填充

若缺失率较低(小于95%)且重要性较低,则根据数据分布的情况进行填充。

常用填充统计量:
  • 平均值:

    对于数据符合均匀分布,用该变量的均值填补缺失值。

  • 中位数:

    对于数据存在倾斜分布的情况,采用中位数填补缺失值。

  • 众数:

    离散特征可使用众数进行填充缺失值。

平均值填充法:

将初始数据集中的属性分为数值属性和非数值属性来分别进行处理。

# 以pandas库操作为例
display(df.head(10))
# 填充前数据
  Feature1    Feature2    Label
0    1.0           A          1
1    2.0           A          1
2    3.0           A          1
3    4.0           C          1
4    NaN        A          1
5    2.0           None          0
6    3.0           B          0
7    3.0           None          0
8    NaN           B          0
9    NaN        B          0

# 均值填充
df['Feature1'].fillna(df['Feature1'].mean(), inplace=True)

# 中位数填充
df['Feature2'].fillna(df['Feature2'].mode().iloc[0], inplace=True)

display(df.head(10))
# 填充后数据
    Feature1    Feature2    Label
0    1.000000    A            1
1    2.000000    A            1
2    3.000000    A            1
3    4.000000    C            1
4    2.571429    A            1
5    2.000000    A            0
6    3.000000    B            0
7    3.000000    A            0
8    2.571429    B            0
9    2.571429    B            0
条件平均值填充法(Conditional Mean Completer):

在该方法中,用于求平均值/众数/中位数并不是从数据集的所有对象中取,而是从与该对象具有相同决策属性值的对象中取得。

# 条件平均值填充
def condition_mean_fillna(df, label_name, feature_name):
    mean_feature_name = '{}Mean'.format(feature_name)
    group_df = df.groupby(label_name).mean().reset_index().rename(columns={feature_name: mean_feature_name})

    df = pd.merge(df, group_df, on=label_name, how='left')
    df.loc[df[feature_name].isnull(), feature_name] = df.loc[df[feature_name].isnull(), mean_feature_name]
    df.drop(mean_feature_name, inplace=True, axis=1)
    return df

df = condition_mode_fillna(df, 'Label', 'Feature2')

4)模型预测填充

使用待填充字段作为Label,没有缺失的数据作为训练数据,建立分类/回归模型,对待填充的缺失字段进行预测并进行填充。

最近距离邻法(KNN)

先根据欧式距离或相关分析来确定距离具有缺失数据样本最近的K个样本,将这K个值加权平均/投票来估计该样本的缺失数据。

from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor

def knn_missing_filled(x_train, y_train, test, k = 3, dispersed = True):
    '''
    @param x_train: 没有缺失值的数据集
    @param y_train: 待填充缺失值字段
    @param test: 待填充缺失值数据集
    '''
    if dispersed:
        clf = KNeighborsClassifier(n_neighbors = k, weights = "distance")
    else:
        clf = KNeighborsRegressor(n_neighbors = k, weights = "distance")

    clf.fit(x_train, y_train)
    return test.index, clf.predict(test)
回归(Regression)

基于完整的数据集,建立回归方程。对于包含空值的对象,将已知属性值代入方程来估计未知属性值,以此估计值来进行填充。当变量不是线性相关时会导致有偏差的估计。常用线性回归。

4)重新取数

如果某些指标非常重要又缺失率高,那就需要和取数人员或业务人员了解,是否有其他渠道可以取到相关数据。

三、处理分类型特征:编码与哑变量

参考链接:https://www.cnblogs.com/juanjiang/archive/2019/05/30/10948849.html

在机器学习中,大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,不能处理文字,在sklearn当中,除了专用来处理文字的算法,其他算法在fit的时候全部要求输入数组或矩阵,也不能够导入文字型数据(其实手写决策树和普斯贝叶斯可以处理文字,但是sklearn中规定必须导入数值型)。然而在现实中,许多标签和特征在数据收集完毕的时候,都不是以数字来表现的。比如说,学历的取值可以是["小学",“初中”,“高中”,"大学"],付费方式可能包含["支付宝",“现金”,“微信”]等等。在这种情况下,为了让数据适应算法和库,我们必须将数据进行编码,即是说,将文字型数据转换为数值型

 preprocessing.LabelEncoder:标签专用,能够将分类转换为分类数值

preprocessing.OrdinalEncoder:特征专用,能够将分类特征转换为分类数值

preprocessing.OneHotEncoder:独热编码,创建哑变量

四、处理连续型特征:二值化与分段

  • sklearn.preprocessing.Binarizer

  根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。

猜你喜欢

转载自www.cnblogs.com/zym-yc/p/11964148.html
今日推荐