zoukankan      html  css  js  c++  java
  • 简单的数据预处理和特征工程

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

    一、无量纲化:最值归一化、均值方差归一化及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。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。

  • 相关阅读:
    Reporting Services系列三:几个细节
    Tips&Tricks系列一:更改VS2005设置
    Reporting Services系列二:引用.NET DLL
    数据库基础系列之六:因空间不足导致IMP失败
    .NET基础示例系列之十四:C#导出建表语句及数据
    Reporting Services系列四:折叠报表
    数据库基础系列之七:IMP数据到指定的表空间
    .NET基础示例系列之十六:制做进程监视器
    .NET基础示例系列之十九:Dundas For ASP.NET
    .NET基础示例系列之十五:操作Excel
  • 原文地址:https://www.cnblogs.com/zym-yc/p/11964148.html
Copyright © 2011-2022 走看看