• ML--数据表达与特征工程


    ML–数据表达与特征工程

    主要涉及的知识点有:

    • 使用哑变量对类型特征进行转化
    • 对数据进行装箱处理
    • 几种常用的数据"升维"方法
    • 常用的自动特征选择方法

    一.数据表达

    1.使用哑变量转化类型特征

    哑变量(Dummy Variables),也被称为虚拟变量,是一种在统计学和经济领域非常常用的,用来把某些类型变量转化为二值变量的方法,在回归分析中的使用尤其广泛

    # 导入pandas
    import pandas as pd
    # 手工输入一个数据表
    fruits=pd.DataFrame({'数值特征':[5,6,7,8,9],
                         '类型特征':['西瓜','香蕉','橘子','苹果','葡萄']
                        })
    
    # 显示
    display(fruits)
    
    数值特征 类型特征
    0 5 西瓜
    1 6 香蕉
    2 7 橘子
    3 8 苹果
    4 9 葡萄

    下面我们使用get_dummies来将类型特征转化为只有0和1的二值数值特征,输入代码如下

    # 转化数据表中的字符串为数值
    fruits_dum=pd.get_dummies(fruits)
    
    # 显示转化后的数据表
    display(fruits_dum)
    
    数值特征 类型特征_橘子 类型特征_苹果 类型特征_葡萄 类型特征_西瓜 类型特征_香蕉
    0 5 0 0 0 1 0
    1 6 0 0 0 0 1
    2 7 1 0 0 0 0
    3 8 0 1 0 0 0
    4 9 0 0 1 0 0

    假如我们就是希望把数值特征也进行get_dummies转换怎么办?没问题,我们可以先将数值特征转换为字符串,然后通过get_dummiescolumns参数来转换

    # 令程序将数值也看作字符串
    fruits['数值特征']=fruits['数值特征'].astype(str)
    
    # 再用get_dummies转化字符串
    fruits_dum2=pd.get_dummies(fruits,columns=['数值特征'])
    
    display(fruits_dum2)
    
    类型特征 数值特征_5 数值特征_6 数值特征_7 数值特征_8 数值特征_9
    0 西瓜 1 0 0 0 0
    1 香蕉 0 1 0 0 0
    2 橘子 0 0 1 0 0
    3 苹果 0 0 0 1 0
    4 葡萄 0 0 0 0 1

    注意 实际上,如果我们不用fruits[‘数值特征’]=fruits[‘数值特征’].astype(str)这行代码把数值转换为字符串类型,依然会得到同样的结果。但是在大规模数据集中,还是建议大家进行转换字符串的操作,避免产生不可预料的错误

    2.对数据进行装箱处理

    首先我们生成许多随机数点在图像中

    # 导入numpy
    import numpy as np
    # 导入画图工具
    import matplotlib.pyplot as plt
    # 生成随机数列
    rnd=np.random.RandomState(38)
    x=rnd.uniform(-5,5,size=50)
    
    # 向数据中添加噪声
    y_no_noise=(np.cos(6*x)+x)
    X=x.reshape(-1,1)
    y=(y_no_noise+rnd.normal(size=len(x)))/2
    
    plt.plot(X,y,'o',c='r')
    
    plt.show()
    

    output_13_0.png

    下面我们分别用MLPKNN算法对这个数据集进行回归分析

    # 导入神经网络
    from sklearn.neural_network import MLPRegressor
    # 导入KNN
    from sklearn.neighbors import KNeighborsRegressor
    
    # 生成一个等差数列
    line=np.linspace(-5,5,1000,endpoint=False).reshape(-1,1)
    # 分别用两种算法拟合数据
    mlpr=MLPRegressor().fit(X,y)
    knr=KNeighborsRegressor().fit(X,y)
    
    # 绘制图形
    plt.plot(line,mlpr.predict(line),label='MLP')
    plt.plot(line,knr.predict(line),label='KNN')
    plt.plot(X,y,'o',c='r')
    plt.legend(loc='best')
    
    plt.show()
    

    output_15_0.png

    [结果分析] MLP产生的回归线非常接近线性模型的结果,而KNN则相对更复杂一些,它视图覆盖更多的数据点

    接下来我们对数据进行一下"装箱处理(binning)",这种处理方法也称为"离散化处理(discretization)"

    # 设置箱体数为11
    bins=np.linspace(-5,5,11)
    
    # 将数据进行装箱操作
    target_bin=np.digitize(X,bins=bins)
    
    # 打印装箱数据范围
    print('装箱数据范围:
    {}'.format(bins))
    
    # 打印前十个数据的特征值
    print('
    前十个数据点的特征值:
    {}'.format(X[:10]))
    
    # 找到它们所在的箱子
    print('
    前十个数据点所在的箱子:
    {}'.format(target_bin[:10]))
    
    装箱数据范围:
    [-5. -4. -3. -2. -1.  0.  1.  2.  3.  4.  5.]
    
    前十个数据点的特征值:
    [[-1.1522688 ]
     [ 3.59707847]
     [ 4.44199636]
     [ 2.02824894]
     [ 1.33634097]
     [ 1.05961282]
     [-2.99873157]
     [-1.12612112]
     [-2.41016836]
     [-4.25392719]]
    
    前十个数据点所在的箱子:
    [[ 4]
     [ 9]
     [10]
     [ 8]
     [ 7]
     [ 7]
     [ 3]
     [ 4]
     [ 3]
     [ 1]]
    

    由于我们在生成这个实验数据集的时候,是在-5到5之间随机生成了50个数据点,因此我们在生成"箱子"(如果觉得这么叫有点土的话,也可以叫它"容器")的时候,也指定范围是从-5到5之间,生成11个元素的等差数列,这样每两个数值之间就形成一个箱子,一共10个

    [结果分析] 从结果中可以看到,第一个箱子是-5到-4之间,第二个箱子是-4到-3之间,以此类推。第1个数据点-1.1522688所在的箱子是第4个,第2个数据点3.59707847所在的箱子是第9个,以此类推

    接下来我们要做的事情,就是用新的方法来表达已经装箱的数据,所要用到的方法就是scikit-learn的独热编码OneHotEncoderOneHotEncoderpandasget_dummies功能基本上是一样的,但是OneHotEncoder目前只能用于整型数值的类型变量

    # 导入独热编码
    from sklearn.preprocessing import OneHotEncoder
    
    onehot=OneHotEncoder(sparse=False)
    onehot.fit(target_bin)
    
    # 使用独热编码转化数据
    X_in_bin=onehot.transform(target_bin)
    
    print('装箱后的数据形态:{}'.format(X_in_bin.shape))
    print('
    装箱后的前十个数据点:{}'.format(X_in_bin[:10]))
    
    装箱后的数据形态:(50, 10)
    
    装箱后的前十个数据点:[[ 0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]
     [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]
     [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.]
     [ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]
    
    
    E:Anacondaenvsmytensorflowlibsite-packagessklearnpreprocessing\_encoders.py:368: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values.
    If you want the future behaviour and silence this warning, you can specify "categories='auto'".
    In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly.
      warnings.warn(msg, FutureWarning)
    

    [结果分析] 虽然数据集中样本的数量仍然是50个,但特征数变成了10个。这是因为我们生成的箱子是10个,而新的数据点的特征是用其所在的箱子号码来表示的

    我们用MLPKNN算法重新进行回归分析

    # 使用独热编码进行数据表达
    new_line=onehot.transform(np.digitize(line,bins=bins))
    
    # 使用新的数据来训练模型
    new_mlpr=MLPRegressor().fit(X_in_bin,y)
    new_knr=KNeighborsRegressor().fit(X_in_bin,y)
    
    # 绘制图形
    plt.plot(line,new_mlpr.predict(new_line),label='New MLP')
    plt.plot(line,new_knr.predict(new_line),label='New KNN')
    
    plt.plot(X,y,'o',c='r')
    
    plt.legend(loc='best')
    
    plt.show()
    

    output_25_0.png

    注意 这种对于样本数据进行装箱的操作对于基于决策树的算法(如随机森林,梯度上升决策树,当然也包括决策树本身)没有太多的作用,因为这算法本身就是不停在拆分样本的特征数据,所以不需要再使用装箱操作

    二.数据"升维"

    1.向数据集添加交互式特征

    介绍两种在统计建模中常用的方法–交互式特征(Interaction Features)多项式特征(Polynomial Features)

    # 手工生成两个数组
    array_1=[1,2,3,4,5]
    array_2=[6,7,8,9,0]
    
    # 使用hstack将两个数组进行堆叠
    array_3=np.hstack((array_1,array_2))
    
    print('将数组2添加到数据1中后得到:{}'.format(array_3))
    
    将数组2添加到数据1中后得到:[1 2 3 4 5 6 7 8 9 0]
    

    接下来我们继续用之前的数据集来进行实验,看对特征进行交互式操作会对模型产生什么样的影响

    # 将原始数据和装箱后的数据进行堆叠
    X_stack=np.hstack([X,X_in_bin])
    print(X_stack.shape)
    
    (50, 11)
    
    # 将数据进行堆叠
    line_stack=np.hstack([line,new_line])
    
    # 重新训练模型
    mlpr_interact=MLPRegressor().fit(X_stack,y)
    
    plt.plot(line,mlpr_interact.predict(line_stack),label='MLP for interaction')
    plt.ylim(-4,4)
    
    for vline in bins:
        plt.plot([vline,vline],[-5,5],':',c='k')
    plt.legend(loc='lower right')
    plt.plot(X,y,'o',c='r')
    
    plt.show()
    

    output_33_0.png

    # 使用新的堆叠方式处理数据
    X_multi=np.hstack([X_in_bin,X*X_in_bin])
    
    print(X_multi.shape)
    print(X_multi[0])
    
    (50, 20)
    [ 0.         0.         0.         1.         0.         0.         0.         0.
      0.         0.        -0.        -0.        -0.        -1.1522688 -0.        -0.
     -0.        -0.        -0.        -0.       ]
    
    # 重新训练模型
    mlpr_multi=MLPRegressor().fit(X_multi,y)
    line_multi=np.hstack([new_line,line*new_line])
    
    plt.plot(line,mlpr_multi.predict(line_multi),label='MLP Regressor')
    plt.ylim(-4,4)
    
    for vline in bins:
        plt.plot([vline,vline],[-5,5],':',c='gray')
    plt.legend(loc='lower right')
    plt.plot(X,y,'o',c='r')
    
    plt.show()
    

    output_35_0.png

    2.向数据集添加多项式特征

    # 导入多项式特征工具
    from sklearn.preprocessing import PolynomialFeatures
    
    # 向数据添加多项式特征
    poly=PolynomialFeatures(degree=20,include_bias=False)
    X_poly=poly.fit_transform(X)
    
    print(X_poly.shape)
    
    (50, 20)
    

    在这段代码中,首先我们指定了PolynomialFeaturesdegree参数为20,这样可以生成20个特征。include_bias设定为False,如果设定为True的话,PolynomialFeatures只会为数据集添加数值为1的特征

    print('原始数据集中的第一个样本特征:
    {}'.format(X[0]))
    print('
    处理后的数据集中的第一个样本特征:
    {}'.format(X_poly[0]))
    
    原始数据集中的第一个样本特征:
    [-1.1522688]
    
    处理后的数据集中的第一个样本特征:
    [ -1.1522688    1.3277234   -1.52989425   1.76284942  -2.0312764
       2.34057643  -2.6969732    3.10763809  -3.58083443   4.1260838
      -4.75435765   5.47829801  -6.3124719    7.27366446  -8.38121665
       9.65741449 -11.12793745  12.82237519 -14.77482293  17.02456756]
    
    # 打印多项式特征处理的方式
    print('PolynomialFeatures对原始数据的处理:
    {}'.format(poly.get_feature_names()))
    
    PolynomialFeatures对原始数据的处理:
    ['x0', 'x0^2', 'x0^3', 'x0^4', 'x0^5', 'x0^6', 'x0^7', 'x0^8', 'x0^9', 'x0^10', 'x0^11', 'x0^12', 'x0^13', 'x0^14', 'x0^15', 'x0^16', 'x0^17', 'x0^18', 'x0^19', 'x0^20']
    
    # 导入线性回归
    from sklearn.linear_model import LinearRegression
    
    # 使用处理后的数据训练线性回归模型
    LNR_poly=LinearRegression().fit(X_poly,y)
    
    line_poly=poly.transform(line)
    
    plt.plot(line,LNR_poly.predict(line_poly),label='Linear Regressor')
    plt.xlim(np.min(X)-0.5,np.max(X)+0.5)
    plt.xlim(np.min(y)-0.5,np.max(y)+0.5)
    
    plt.plot(X,y,'o',c='r')
    plt.legend(loc='lower right')
    
    plt.show()
    

    output_41_0.png

  • 相关阅读:
    演示Eclipse插件实现代码提示和补全
    重拾《 两周自制脚本语言 》- Eclipse插件实现语法高亮
    Kindle Windows版本 中文字体修改工具
    MD5加密算法原理及实现
    Spring boot 发送邮件示例
    ubuntu下svn的命令使用
    数据库的分区、分表、分库、分片的简介
    Vue 入门之目录结构介绍
    MQTT简单介绍与实现
    SVN使用规范
  • 原文地址:https://www.cnblogs.com/LQ6H/p/10425433.html
Copyright © 2020-2023  润新知