• 【机器学习】阿里云天池竞赛——工业蒸汽量预测(6)


    机器学习经典赛题:工业蒸汽量预测(6):特征优化

    6.1 特征优化的方法

    好的特征对于模型性能有着至关重要的影响。可以通过合成特征、对特征做简单变换、用决策树创造新特征、特征组合等方法对特征进行优化。

    6.1.1 合成特征

    从一个或者多个输入特征衍生来的特征(标准化和缩放法创建的特征不算),主要包含以下几个类型:
    (1)将一个特征与其本身或者其他特征相乘(特征组合)
    (2)两个特征相除
    (3)对连续特征进行分箱,以分为多个区间分箱。

    6.1.2 特征的简单变换

    1. 数值特征的变换和组合
      常用的数值特征的变换和组合如下:
      (1)多项式特征(polynomial feature)
      (2)比例特征(ratio feature): X 1 / X 2 X1/X2 X1/X2
      (3)绝对值(absolute value)
      (4) m a x ( X 1 , X 2 ) max(X1,X2) max(X1,X2), m i n ( X 1 , X 2 ) min(X1,X2) min(X1,X2), X1 or X2
    2. 类别特征与数值特征的组合
      用N1和N2表示数值特征,C1和C2表示类别特征,利用pandas的groupby创建以下几种新特征(其中,C2还可以是离散化了的N1):
      (1)中位数:median(N1)_by(C1)
      (2)算数平均数:mean(N1)_by(C1)
      (3)众数:mode(N1)_by(C1)
      (4)最小值:min(N1)_by(C1)
      (5)最大值:max(N1)_by(C1)
      (6)标准差:std(N1)_by(C1)
      (7)方差:var(N1)_by(C1)
      (8)频数:freq(C2)_by(C1)
      注意:freq(C1)不需要进行groupby操作也有意义。
      如果讲这种方法和线性组合等基础特征工程结合(仅用于决策树),则可以得到更多有意义的特征,如下:
      (1)N1-median(N1)_by(C1)
      (2)N1-mean(N1)_by(C1)

    6.1.3 用决策树创造新特征

    在决策树系列(单棵决策树、GBDT、随机森林)的算法中,由于每一个样本都会被映射到决策树的一片叶子上,因此可以把样本经过每一棵决策树映射后的index(自然数)或one-hot-vector(哑编码得到的稀疏矢量)作为一项新的特征加入模型中
    具体实现采用sklearn和xgboost中的apply()和decision_path()。

    6.1.4 特征组合

    特征组合是指将单独的特征进行组合(相乘或求笛卡尔积)而形成的合成特征,有助于表示非线性关系。

    1. 对非线性规律进行编码
      由于通过采用随机梯度下降法可以有效地训练线性模型,因此在使用扩展的线性模型时,辅以特征组合一直都是训练大规模数据集的有效方法。可以创建很多不同种类的特征组合,例如:

      • [A x B]:将两个特征的值相乘
      • [A x B x C x …]:几个特征的值相乘
      • [A x A]:对单个特征的值求平方形成的特征
    2. 组合独热向量
      机器学习模型很少会组合连续特征,但是却经常组合独热特征向量,将独特特征矢量的特征组合视为逻辑连接。例如country:usa AND language:spanish

    对大规模数据集使用特征组合时学习高度复杂模型的一种有效策略,而神经网络可提供另一种策略。

    1. 使用分桶特征列训练模型
      分桶特征:是以一定方式将连续型数据特征划分到不同的桶(箱)中,可以理解为对连续型特征的一种离散化处理。

    如果要为分桶特征定义特征列,可以使用bucketized_column( 而不是numerical_column),该列数字作为输入并使用boundaries参数中指定的分桶边界 将其转化为分桶特征

    6.2 特征优化实战

    6.2.1 导入数据

    import pandas as pd
    from sklearn.decomposition import PCA
    from sklearn.model_selection import KFold
    from sklearn.metrics import mean_squared_error
    import lightgbm as lgb
    import numpy as np
    
    train_data_file = "../data/zhengqi_train.txt"
    test_data_file = "../data/zhengqi_test.txt"
    train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8')
    test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6.2.2 特征构造方法

    #定义特征构造方法
    epsilon = 1e-5
    
    #组交叉特征,可以自己定义,如增加x*x/y,log(x)/y等
    func_dict = {
        'add': lambda x, y: x + y,
        'mins': lambda x, y: x - y,
        'div': lambda x, y: x / (y + epsilon),
        'multi': lambda x, y: x * y
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.2.3 特征构造函数

    #特征构造函数
    def auto_features_make(train_data, test_data, func_dict, col_list):
        train_data, test_data = train_data.copy(), test_data.copy()
        for col_i in col_list:
            for col_j in col_list:
                for func_name, func in func_dict.items():
                    for data in [train_data, test_data]:
                        func_features = func(data[col_i], data[col_j])
                        col_func_features = '-'.join([col_i, func_name, col_j])
                        data[col_func_features] = func_features
        return train_data, test_data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6.2.4 特征降维处理

    #基于PCA进行特征降维
    train_data2, test_data2 = auto_features_make(train_data, test_data, func_dict, col_list=test_data.columns)
    pca = PCA(n_components=500)
    train_data2_pca = pca.fit_transform(train_data2.iloc[:, 0:-1])
    test_data2_pca = pca.transform(test_data2)
    train_data2_pca = pd.DataFrame(train_data2_pca)
    test_data2_pca = pd.DataFrame(test_data2_pca)
    train_data2_pca['target'] = train_data2['target']
    x_train2 = train_data2[test_data2.columns].values
    y_train2 = train_data2['target']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.2.5 模型训练和评估

    使用LightGBM模型对新构造的特征进行模型训练和评估。

    #模型训练与评估
    #5折交叉检验
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=2019)
    
    #记录训练和预测MSE
    MSE_DICT = {'train_mse': [], "test_mse": []}
    
    #线下训练预测
    for i, (train_index, test_index) in enumerate(kf.split(x_train2)):
        #LGB模型
        lgb_reg = lgb.LGBMRegressor(
            learning_rate=0.01,
            max_depth=-1,
            n_estimators=5000,
            boosting_type='gbdt',
            random_state=2022,
            objective='regression',
        )
        #切分训练集和预测集
        x_train_kfold = x_train2[train_index]
        x_test_kfold = x_train2[test_index]
        y_train_kfold = y_train2[train_index]
        y_test_kfold = y_train2[test_index]
        #模型训练
        lgb_reg.fit(X=x_train_kfold,
                    y=y_train_kfold,
                    eval_set=[(x_train_kfold, y_train_kfold),
                              (x_test_kfold, y_test_kfold)],
                    eval_names=['train', 'test'],
                    early_stopping_rounds=100,
                    eval_metric='MSE',
                    verbose=50)
        #训练集和预测集预测
        y_train_kfold_predict = lgb_reg.predict(x_train_kfold, num_iteration=lgb_reg.best_iteration_)
        y_test_kfold_predict = lgb_reg.predict(x_test_kfold, num_iteration=lgb_reg.best_iteration_)
        print('第{}折 训练和预测 训练MSE 预测MSE'.format(i))
        train_mse = mean_squared_error(y_train_kfold_predict, y_train_kfold)
        print('-----\n', '训练MSE\n', train_mse, '\n-----')
        test_mse = mean_squared_error(y_test_kfold_predict, y_test_kfold)
        print('-----\n', '预测MSE\n', test_mse, '\n-----')
        MSE_DICT["train_mse"].append(train_mse)
        MSE_DICT['test_mse'].append(test_mse)
    print('-----\n', '训练MSE\n', MSE_DICT['train_mse'], '\n', np.mean(MSE_DICT['train_mse']), '\n-----')
    print('-----\n', '预测MSE\n', MSE_DICT['test_mse'], '\n', np.mean(MSE_DICT['test_mse']), '\n-----')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    运行结果:

    ...
    -----
     训练MSE
     [0.00017012122282987903, 0.003986113221006774, 0.004653503140174019, 1.6944261550293392e-05, 0.0019608822664788713] 
     0.002157512822407967 
    -----
    -----
     预测MSE
     [0.09929753449545065, 0.1250100344303853, 0.09311309275116833, 0.10307589284589647, 0.09883896847504547] 
     0.10386710459958923 
    -----
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    将代码运行得到的5折交叉验证的各折叠训练MSE、预测MSE及平均MSE,与上一节未作特征优化的结果(训练MSE平均值为0.006117279317883938,预测MSE平均值为0.10952066075608168)对比,可以发现MSE得到进一步降低。

    参考资料

    [1] 《阿里云天池大赛赛题解析——机器学习篇》

  • 相关阅读:
    javaee ssm框架整合例子 ssm例子,需要哪些依赖,配置文件如何配置
    AOSP编译系统演进:从Make到Ninja的技术升级(Android13)
    ve-plus:基于 vue3.x 桌面端UI组件库|vue3组件库
    C++ 基于boost.asio封装的日志库,支持输出到文件、控制台和syslog远程日志,支持变长参数的日志输出
    体验Windows自带远程桌面 局域网&外网
    基于avaSwing开发普通计算器程序 课程设计 大作业源码
    Web自动化测试怎么做?Web自动化测试的详细流程和步骤
    java-php-net-python-代驾网站计算机毕业设计程序
    重磅!由Linux面试出发,看清华大佬教你如何企业级运维实战
    【毕业设计】基于单片机的指纹识别考勤系统 - 物联网 stm32
  • 原文地址:https://blog.csdn.net/ARPOSPF/article/details/127340382