zoukankan      html  css  js  c++  java
  • 机器学习-数据的特征预处理

    数据的特征预处理

    单个特征

    (1)归一化

    归一化首先在特征(维度)非常多的时候,可以防止某一维或某几维对数据影响过大,也是为了把不同来源的数据统一到一个参考区间下,这样比较起来才有意义,其次可以程序可以运行更快。 例如:一个人的身高和体重两个特征,假如体重50kg,身高175cm,由于两个单位不一样,数值大小不一样。如果比较两个人的体型差距时,那么身高的影响结果会比较大,k-临近算法会有这个距离公式。

    min-max方法

    常用的方法是通过对原始数据进行线性变换把数据映射到[0,1]之间,变换的函数为:

    X′=x−minmax−minX^{'}{=}frac{x-min}{max-min}X=maxminxmin

    其中min是样本中最小值,max是样本中最大值,注意在数据流场景下最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。

    • min-max自定义处理

    这里我们使用相亲约会对象数据在MatchData.txt,这个样本时男士的数据,三个特征,玩游戏所消耗时间的百分比、每年获得的飞行常客里程数、每周消费的冰淇淋公升数。然后有一个 所属类别,被女士评价的三个类别,不喜欢、魅力一般、极具魅力。 首先导入数据进行矩阵转换处理

    import numpy as np
    
    def data_matrix(file_name):
      """
      将文本转化为matrix
      :param file_name: 文件名
      :return: 数据矩阵
      """
      fr = open(file_name)
      array_lines = fr.readlines()
      number_lines = len(array_lines)
      return_mat = zeros((number_lines, 3))
      # classLabelVector = []
      index = 0
      for line in array_lines:
        line = line.strip()
        list_line = line.split('	')
        return_mat[index,:] = list_line[0:3]
        # if(listFromLine[-1].isdigit()):
        #     classLabelVector.append(int(listFromLine[-1]))
        # else:
        #     classLabelVector.append(love_dictionary.get(listFromLine[-1]))
        # index += 1
      return return_mat
    

    输出结果为

    [[  4.09200000e+04   8.32697600e+00   9.53952000e-01]
     [  1.44880000e+04   7.15346900e+00   1.67390400e+00]
     [  2.60520000e+04   1.44187100e+00   8.05124000e-01]
     ...,
     [  2.65750000e+04   1.06501020e+01   8.66627000e-01]
     [  4.81110000e+04   9.13452800e+00   7.28045000e-01]
     [  4.37570000e+04   7.88260100e+00   1.33244600e+00]]
    

    我们查看数据集会发现,有的数值大到几万,有的才个位数,同样如果计算两个样本之间的距离时,其中一个影响会特别大。也就是说飞行里程数对于结算结果或者说相亲结果影响较大,但是统计的人觉得这三个特征同等重要,所以需要将数据进行这样的处理。

    这样每个特征任意的范围将变成[0,1]的区间内的值,或者也可以根据需求处理到[-1,1]之间,我们再定义一个函数,进行这样的转换。

    def feature_normal(data_set):
        """
        特征归一化
        :param data_set:
        :return:
        """
        # 每列最小值
        min_vals = data_set.min(0)
        # 每列最大值
        max_vals = data_set.max(0)
        ranges = max_vals - min_vals
        norm_data = np.zeros(np.shape(data_set))
        # 得出行数
        m = data_set.shape[0]
        # 矩阵相减
        norm_data = data_set - np.tile(min_vals, (m,1))
        # 矩阵相除
        norm_data = norm_data/np.tile(ranges, (m, 1)))
        return norm_data
    

    输出结果为

    [[ 0.44832535  0.39805139  0.56233353]
     [ 0.15873259  0.34195467  0.98724416]
     [ 0.28542943  0.06892523  0.47449629]
     ...,
     [ 0.29115949  0.50910294  0.51079493]
     [ 0.52711097  0.43665451  0.4290048 ]
     [ 0.47940793  0.3768091   0.78571804]]
    

    这样得出的结果都非常相近,这样的数据可以直接提供测试验证了

    • min-max的scikit-learn处理

    scikit-learn.preprocessing中的类MinMaxScaler,将数据矩阵缩放到[0,1]之间

    >>> X_train = np.array([[ 1., -1.,  2.],
    ...                     [ 2.,  0.,  0.],
    ...                     [ 0.,  1., -1.]])
    ...
    >>> min_max_scaler = preprocessing.MinMaxScaler()
    >>> X_train_minmax = min_max_scaler.fit_transform(X_train)
    >>> X_train_minmax
    array([[ 0.5       ,  0.        ,  1.        ],
           [ 1.        ,  0.5       ,  0.33333333],
           [ 0.        ,  1.        ,  0.        ]])
    

    (3)标准化

    常用的方法是z-score标准化,经过处理后的数据均值为0,标准差为1,处理方法是:

    X′=x−μσX^{'}{=}frac{x-mu}{sigma}X=σxμ

    其中μmuμ是样本的均值,σsigmaσ是样本的标准差,它们可以通过现有的样本进行估计,在已有的样本足够多的情况下比较稳定,适合嘈杂的数据场景

    sklearn中提供了StandardScalar类实现列标准化:

    In [2]: import numpy as np
    
    In [3]: X_train = np.array([[ 1., -1.,  2.],[ 2.,  0.,  0.],[ 0.,  1., -1.]])
    
    In [4]: from sklearn.preprocessing import StandardScaler
    
    In [5]: std = StandardScaler()
    
    In [6]: X_train_std = std.fit_transform(X_train)
    
    In [7]: X_train_std
    Out[7]:
    array([[ 0.        , -1.22474487,  1.33630621],
           [ 1.22474487,  0.        , -0.26726124],
           [-1.22474487,  1.22474487, -1.06904497]])
    

    (3)缺失值

    由于各种原因,许多现实世界的数据集包含缺少的值,通常编码为空白,NaN或其他占位符。然而,这样的数据集与scikit的分类器不兼容,它们假设数组中的所有值都是数字,并且都具有和保持含义。使用不完整数据集的基本策略是丢弃包含缺失值的整个行和/或列。然而,这是以丢失可能是有价值的数据(即使不完整)的代价。更好的策略是估算缺失值,即从已知部分的数据中推断它们。

    (1)填充缺失值 使用sklearn.preprocessing中的Imputer类进行数据的填充

    class Imputer(sklearn.base.BaseEstimator, sklearn.base.TransformerMixin)
        """
        用于完成缺失值的补充
    
        :param param missing_values: integer or "NaN", optional (default="NaN")
            丢失值的占位符,对于编码为np.nan的缺失值,使用字符串值“NaN”
    
        :param strategy: string, optional (default="mean")
            插补策略
            如果是“平均值”,则使用沿轴的平均值替换缺失值
            如果为“中位数”,则使用沿轴的中位数替换缺失值
            如果“most_frequent”,则使用沿轴最频繁的值替换缺失
    
        :param axis: integer, optional (default=0)
            插补的轴
            如果axis = 0,则沿列排列
            如果axis = 1,则沿行排列
        """
    
    >>> import numpy as np
    >>> from sklearn.preprocessing import Imputer
    >>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
    >>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
    Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
    >>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
    >>> print(imp.transform(X))                          
    [[ 4.          2.        ]
     [ 6.          3.666...]
     [ 7.          6.        ]]
    

    多个特征

    降维

    PCA(Principal component analysis),主成分分析。特点是保存数据集中对方差影响最大的那些特征,PCA极其容易受到数据中特征范围影响,所以在运用PCA前一定要做特征标准化,这样才能保证每维度特征的重要性等同。

    sklearn.decomposition.PCA

    class PCA(sklearn.decomposition.base)
       """
       主成成分分析
    
       :param n_components: int, float, None or string
           这个参数可以帮我们指定希望PCA降维后的特征维度数目。最常用的做法是直接指定降维到的维度数目,此时n_components是一个大于1的整数。
           我们也可以用默认值,即不输入n_components,此时n_components=min(样本数,特征数)
    
       :param whiten: bool, optional (default False)
          判断是否进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化。对于PCA降维本身来说一般不需要白化,如果你PCA降维后有后续的数据处理动作,可以考虑白化,默认值是False,即不进行白化
    
       :param svd_solver:
          选择一个合适的SVD算法来降维,一般来说,使用默认值就够了。
        """
    

    通过一个例子来看

    >>> import numpy as np
    >>> from sklearn.decomposition import PCA
    >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
    >>> pca = PCA(n_components=2)
    >>> pca.fit(X)
    PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
      svd_solver='auto', tol=0.0, whiten=False)
    >>> print(pca.explained_variance_ratio_)
    [ 0.99244...  0.00755...]
    
  • 相关阅读:
    原创:PHP编译安装配置参数说明
    原创 :xftp SFTP子系统申请已拒绝 请确保SSH链接的SFTP子系统设置有效
    原创:LNMP架构部署个人博客网站 禁止转载复制
    原创 :单刷深渊 在Linux中系统安装mysql实战直播
    原创:一键化部署百台服务器级别后端服务器
    原创 :nfs软件服务利用ansible实现一键化部署
    原创: rsync软件服务利用ansible实现一键化部署
    原创:100 台规模集群存储系统搭建及数据实时备份
    原创Couldn't read packet: Connection reset by peer 错误排查思路(推荐)
    原创:Docker在云家政的应用 谢绝复制粘贴内容
  • 原文地址:https://www.cnblogs.com/20183544-wangzhengshuai/p/14484929.html
Copyright © 2011-2022 走看看