利用GBDT进行对表格类数据的机器学习的实战项目

news2024/11/28 0:48:44

一:题目简介

在数据集中,每个样本都对应一个葡萄牙大学的学生。原始数据集中共有4424名学生,。对于每个学生,我们获得了人口统计数据、宏观经济数据以及课程前两个学期的表现。目标是预测学生在三年或四年学习后的状态:是否毕业、仍在就读,或退学。题目提供了训练集,测试集和提交格式。

下载或观看数据集入口:‌‍⁠​‍‬‬‍‍‌⁠‌​​‌​​​‌​‬⁠​​​​‍​‬​⁠​‌​​⁠‬​​利用GBDT进行对表格类数据的机器学习的实战项目所需数据集 - 飞书云文档 (feishu.cn)

二:利用GBDT来进行机器学习对问题求解

本文要采取的方法是表格类比赛经典建模方法

数据EDA、特征工程、GBDT模型家族、交叉验证,模型融合

我们跳过数据EDA,直接先进入特征工程。

GBDT(Gradient Boosting Decision Tree,梯度提升决策树)是一种流行的机器学习算法,它主要用于回归和分类问题。GBDT 是一种集成学习算法,它通过构建和组合多个决策树来形成一个强大的预测模型。
以下是 GBDT 的一些关键特性:
基本原理
1. 迭代增强:GBDT 通过迭代地训练决策树来最小化损失函数。每一棵树都是为了纠正前一棵树的错误而构建的。
2. 梯度提升:算法的名字来源于它使用梯度下降法的近似来训练模型。在每次迭代中,算法计算损失函数关于当前模型的梯度,然后用一棵新的决策树来拟合这个梯度。
构建过程
1. 初始化:通常,GBDT 以一个常数预测(例如,回归问题的均值或分类问题的众数)开始。
2. 负梯度:在每次迭代中,算法计算当前损失函数的负梯度,这些梯度代表了当前模型的误差。
3. 决策树拟合:算法训练一个新的决策树来拟合这些负梯度(也称为残差)。
4. 更新模型:新训练的决策树用来更新模型,通常是通过加权求和的方式(树的预测乘以一个学习率)。
核心优势
1. 准确性:GBDT 在许多问题上都表现出很高的预测准确性。
2. 灵活性:它可以处理各种类型的数据,包括连续值和类别值。
3. 鲁棒性:GBDT 对于异常值不敏感,并且通常不需要太多的数据预处理。
关键参数
1. 树的数量:构建的决策树的数量,更多的树可能会提高模型的准确性,但也可能导致过拟合。
2. 树的大小:单个决策树的大小(深度或叶子节点数),控制模型的复杂度。
3. 学习率:也称为收缩率,它控制每棵树对最终模型的影响程度。
应用场景
GBDT 在各种应用中都非常流行,包括但不限于:
- 广告点击率预测
- 信用评分
- 异常检测
- 排序问题
常用实现
GBDT 有几个流行的开源实现,包括:
- XGBoost
- LightGBM
- CatBoost
这些库提供了高效的算法实现,并且支持并行计算和分布式计算,使得 GBDT 能够在大数据集上快速训练。
总的来说,GBDT 是一个强大的机器学习算法,它通过结合多个简单的决策树来构建一个复杂的、高准确度的预测模型。由于它的准确性和灵活性,GBDT 在工业界和学术界都得到了广泛的应用。

在开始之前,环境配置需要先用Python导入我们所需的库,sklearn集成了大多数机器学习库。

import pickle
import json
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import ExtraTreeClassifier
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold, StratifiedKFold
import lightgbm as lgb
import xgboost as xgb
import catboost as cb

1:特征工程

特征工程(FE)是将原始特征转化为更好的表达问题本质的特征。比如预测房价时,将房子的长宽组合成面积,就是更好的特征表达

GBDT类算法不需要做特征归一化或离散化

LightGBM/CatBoost可以处理类别特征,只需转成自然数即可; XGBoost则需要做OneHot编码,当 然也可尝试直接以自然数输入

可以通过观察数据的特征得到类别特征和数值特征。

数据简介入口:UCI Machine Learning Repository

先读入数据:

train_df = pd.read_csv('../input/train.csv', index_col=0)
test_df = pd.read_csv('../input/test.csv', index_col=0)
com_df = pd.concat([train_df, test_df], axis=0, ignore_index=False)

类别特征为:

ori_cat_feats = [
    'Marital status',
    'Application mode',
    'Application order',
    'Course',
    'Daytime/evening attendance',
    'Previous qualification',
    'Nacionality',
    'Mother\'s qualification',
    'Father\'s qualification',
    'Mother\'s occupation',
    'Father\'s occupation',
    'Displaced',
    'Educational special needs',
    'Debtor',
    'Tuition fees up to date',
    'Gender',
    'Scholarship holder',
    'International',
]

数值特征为:

ori_num_feats = [
    'Previous qualification (grade)',
    'Admission grade',
    'Age at enrollment',
    'Curricular units 1st sem (credited)',
    'Curricular units 1st sem (enrolled)',
    'Curricular units 1st sem (evaluations)',
    'Curricular units 1st sem (approved)',
    'Curricular units 1st sem (grade)',
    'Curricular units 1st sem (without evaluations)',
    'Curricular units 2nd sem (credited)',
    'Curricular units 2nd sem (enrolled)',
    'Curricular units 2nd sem (evaluations)',
    'Curricular units 2nd sem (approved)',
    'Curricular units 2nd sem (grade)',
    'Curricular units 2nd sem (without evaluations)',
    'Unemployment rate',
    'Inflation rate',
    'GDP',
]

然后清除列名中的特殊字符:

special_char = ["'", '/', ' ']
def normalize_feature_name(name):
    for c in special_char:
        name = name.replace(c, '_')
    name = name.replace('(', '').replace(')', '')
    return name

ori_all_feats = [normalize_feature_name(col) for col in ori_all_feats]
ori_cat_feats = [normalize_feature_name(col) for col in ori_cat_feats]
ori_num_feats = [normalize_feature_name(col) for col in ori_num_feats]

train_df.columns = train_df.columns.map(normalize_feature_name)
test_df.columns = test_df.columns.map(normalize_feature_name)

对分类特征以及预测的目标值进行数字编码,‘Graduate’ 被映射为 0,‘Enrolled’ 被映射为 1,而 ‘Dropout’ 被映射为 2。

for col in ori_cat_feats:
    com_df[col] = LabelEncoder().fit_transform(com_df[col])

label2code = {
    'Graduate': 0,
    'Enrolled': 1,
    'Dropout': 2,
}

code2label = {v: v for k, v in label2code.items()}
com_df['Target'] = com_df['Target'].map(label2code)

train_df = com_df.loc[train_df.index]
test_df = com_df.loc[test_df.index]

支持我们就完成了简易化的特征工程。

2:LightGBM模型建立与交叉验证(CV)

LightGBM是GBDT 有几个流行的开源实现。交叉验证是一种统计学方法,交叉验证涉及到将数据集分成几个较小的子集,并使用这些子集来训练和验证模型,用于评估机器学习模型在独立数据集上的预测性能。它是用来避免过拟合和提高模型泛化能力的一种技术。

如图为交叉验证的图解:

在LightGBM中,需要自定义参数,可以使用默认参数,也可以在网上找优秀的参数,也可以寻找软件开源包自动求参。

如下为一组适合本题的LightGBM参数:

params = {
    'num_threads': 32,
    'learning_rate': 0.01,
    'objective': 'multiclass',
    'num_class': 3,
    'num_leaves': 31,
    'min_data_in_leaf': 20,
    'bagging_freq': 1,
    'bagging_fraction': 0.8,
    'feature_fraction': 0.8,
    'metric': 'multi_error',
    'early_stopping_rounds': 400,
}

然后我们进行LightGBM实现与交叉验证(CV)实现:

def lgb_cv(params, train_df, test_df, feat_cols, cat_feat_cols, target_col, stratified=False, nfold=5, num_boost_round=10000):
    if stratified:
        folds = StratifiedKFold(n_splits=nfold, shuffle=True, random_state=42)
    else:
        folds = KFold(n_splits=nfold, shuffle=True, random_state=42)
        
    target = train_df[target_col]

    oof = np.zeros((train_df.shape[0], 3), dtype=np.float64)
    pred = np.zeros((test_df.shape[0], 3), dtype=np.float64)

    for i, (trn_idx, val_idx) in enumerate(folds.split(train_df.index, train_df[target_col].astype(int))):
        print(f'fold={i}', '- ' * 20)
        trn_data = lgb.Dataset(train_df.loc[trn_idx, feat_cols], label=target.loc[trn_idx], categorical_feature=cat_feat_cols)
        val_data = lgb.Dataset(train_df.loc[val_idx, feat_cols], label=target.loc[val_idx], categorical_feature=cat_feat_cols)
    
        model = lgb.train(params, trn_data, num_boost_round, valid_sets=val_data, callbacks=[lgb.log_evaluation(200)])
    
        oof[val_idx] = model.predict(train_df.loc[val_idx, feat_cols], num_iteration=model.best_iteration)
        pred += model.predict(test_df[feat_cols], num_iteration=model.best_iteration) / nfold

    cv = accuracy_score(target, oof.argmax(axis=-1))
    return cv, oof, pred

这个定义了一个可以实现LightGBM并得到,cv 是交叉验证的准确度得分,oof 是训练集样本的交叉验证预测结果,而 pred 是测试集样本的交叉验证预测结果。这些变量都是评估模型性能的重要指标。

cv, oof, pred = lgb_cv(params, train_df, test_df, ori_all_feats, ori_cat_feats, 'Target')
print(cv)
simple_cv, simple_oof, simple_pred = cv, oof, pred

然后我们可以得到交叉验证的准确度得分(cv值)为0.8337123291251731,cv是衡量评估模型性能的最重要的指标。

3:XGBoost模型建立与交叉验证(CV)

我们使用和LightGBM实现相同的步骤:

params = {
    # general parameters
    'nthread': 32,
    'objective': 'multi:softprob',
    'num_class': 3,
    'eval_metric': 'merror',
    # tuning parameters
    'learning_rate': 0.1259,
    'max_depth': 3,
    'min_child_weight': 85,
    'subsample': 0.987,
    'colsample_bytree': 0.5448,
    'reg_lambda': 7.138,
}

def xgb_cv(params, train_df, test_df, feat_cols, cat_feat_cols, target_col, stratified=False, nfold=5, num_boost_round=10000):
    if stratified:
        folds = StratifiedKFold(n_splits=nfold, shuffle=True, random_state=42)
    else:
        folds = KFold(n_splits=nfold, shuffle=True, random_state=42)
        
    target = train_df[target_col]

    oof = np.zeros((train_df.shape[0], 3), dtype=np.float64)
    pred = np.zeros((test_df.shape[0], 3), dtype=np.float64)

    for i, (trn_idx, val_idx) in enumerate(folds.split(train_df.index, train_df[target_col].astype(int))):
        print(f'fold={i}', '- ' * 20)
        trn_data = xgb.DMatrix(train_df.loc[trn_idx, feat_cols], label=target.loc[trn_idx], enable_categorical=True)
        val_data = xgb.DMatrix(train_df.loc[val_idx, feat_cols], label=target.loc[val_idx], enable_categorical=True)

        model = xgb.train(params, trn_data, num_boost_round, evals=[(trn_data, 'train'), (val_data, 'valid')], verbose_eval=200, early_stopping_rounds=400)
        
        oof[val_idx] = model.predict(val_data, iteration_range=(0, model.best_iteration + 1))
        
        tst_data = xgb.DMatrix(test_df[feat_cols], enable_categorical=True)
        pred += model.predict(tst_data, iteration_range=(0, model.best_iteration + 1)) / nfold

    cv = accuracy_score(target, oof.argmax(axis=-1))
    return cv, oof, pred

xgb_bo_cv, xgb_bo_oof, xgb_bo_pred = xgb_cv(params, fe_train_df, fe_test_df, null_imp_selected_feats, [], 'Target')

print(xgb_bo_cv)

最后得到XGBoost模型的cv值为0.8349407982435505

4:模型集成

这里的模型集成就是把我们之前得到的LightGBM和XGBoostt模型结合起来。模型集成有许多种方法,这里我们采用其中的一种:stacking,即每个模型预测的结果oof作为输 入,label作为目标,训练一个次级学习器,一般次级学习器会选一些简单的线性模型。

from sklearn.svm import SVC
svc = SVC()
trn_x = np.hstack([simple_oof, xgb_bo_oof])
tst_x = np.hstack([simple_pred,  xgb_bo_pred])
svc.fit(trn_x, train_df['Target'])
stacking_pred = svc.predict(tst_x)

然后我们可以按提交格式上传我们的预测结果:

sub_df = pd.read_csv('../input/sample_submission.csv')
pred = stacking_pred
sub_df['Target'] = pred
sub_df['Target'] = sub_df['Target'].map(code2label)
sub_df.to_csv('prob_stacking.csv', index=False, header=True)

这些步骤就是表格类数据的机器学习的经典做法。

5:模型提升

通过上述答案得到的结果已经是较为不错的答案。如果还想进一步探索和提高,可以在特征工程和调参方面采用一些高阶方法。

点下关注,分享更多有关AI,数据分析和量化金融实用教程和实战项目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2060476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机桥接模式下设置静态IP

虚拟机桥接模式下设置静态ip 1. 设置虚拟机网络适配器为桥接模式2. 配置 CentOS 虚拟机的静态 IP3. 重启网络服务4. 验证配置5. 网络测试 要将 CentOS 虚拟机的网络模式从 NAT 模式更改为桥接模式,并设置静态 IP 地址以与 Windows 内网保持在相同网段,你…

PPP简介

介绍PPP特性的定义和目的。 定义 PPP(Point-to-Point Protocol)协议是一种点到点链路层协议,主要用于在全双工的同异步链路上进行点到点的数据传输。 目的 PPP协议是在串行线IP协议SLIP(Serial Line Internet Protocol&#x…

vue---echarts环形图

1、完整代码直接可以cv <template><div id"main1"></div> </template><script> import * as echarts from echarts; // import { mapState } from vuex; // import { Alarm_Device } from ../utils/api.js; export default {name: P…

视频美颜SDK与直播美颜工具的架构设计与性能优化

本篇文章&#xff0c;小编将深入讲解视频美颜SDK与直播美颜工具的架构设计&#xff0c;并分享一些性能优化的实践经验。 一、视频美颜SDK的架构设计 视频美颜SDK的核心在于其模块化的设计思路。通常&#xff0c;视频美颜SDK由以下几个主要模块组成&#xff1a; 1.图像预处理…

【Qt】常用控件QCalendarWidget的使用

常用控件QCalendarWidget的使用 QCalendarWidget表示一个日历 核心属性 属性说明 selectDate 当前选中的⽇期 minimumDate 最⼩⽇期 maximumDate 最⼤⽇期 firstDayOfWeek 每周的第⼀天(也就是⽇历的第⼀列) 是周⼏. gridVisible 是否显⽰表格的边框 selectionMode…

AWS不同类型的EC2实例分别适合哪些场景?

Amazon Web Services&#xff08;AWS&#xff09;的弹性计算云&#xff08;EC2&#xff09;提供了多种实例类型&#xff0c;以满足不同的应用需求和工作负载。了解不同类型的 EC2 实例及其适用场景&#xff0c;可以帮助用户更好地优化性能和控制成本。九河云和大家一起了解一下…

Selenium + Python 自动化测试21(PO+HTML+Mail)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了PO模式并举例说明了基本的思路&#xff0c;今天我们继续学习。 本篇文章我们综合一下之前学习的内容&#xff0c;如先将PO模式和我们生成HTML报告融合起来&am…

gewe微信聊天机器人搭建教程

由于自身在机器人方面滚爬多年&#xff0c;现在收藏几个宝藏机器人 推荐一下自己常用的机器人&#xff1a; 适合有技术开发的公司&#xff0c;可以自主开发所需要的功能&#xff01;十分齐全 测试问文档&#xff1a;开发前必读 - GeWe开放平台 有需要的兄弟可以看一下&…

笔记 6 : 彭老师课本第 5 章 ,举例分析 IIC 编程,以及开启虚拟机

&#xff08;60&#xff09; 首先看 IIC 的陀螺仪的底板图&#xff0c;board 图&#xff1a; 以 GYRO_INT 为例去查找其对应的控制器&#xff1a; 继续查找 I2C_SCL5 以及 I2C_SDA5 : MPU6050 以及比较复杂&#xff0c;需要查看其手册&#xff0c;全英文版&#xff1a; 再…

iOS开发进阶(二十二):Xcode* 离线安装 iOS Simulator

文章目录 一、前言二、模拟器安装 一、前言 Xcode 15 安装包的大小相比之前更小&#xff0c;因为除了 macOS 的 Components&#xff0c;其他都需要动态下载安装&#xff0c;否则提示 iOS 17 Simulator Not Installed。 如果不安装对应的运行模拟库&#xff0c;真机和模拟器无法…

深入理解Java虚拟机(线程安全)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 线程安全 当多个线程同时访问一个对象时&#xff0c;如果不用考虑…

图片清晰修复有什么方法?归纳了三种

图片清晰修复有什么方法&#xff1f;图片清晰度的修复是一项常见的后期处理任务&#xff0c;尤其当原始照片由于各种原因如手抖、光线不足等出现模糊不清的情况时。下文将介绍三种不同的软件修复方法来帮助提高图片的清晰度和细节&#xff0c;让你的照片看起来更加生动和专业。…

Kubectl命令、初识pod、namespace

文章目录 一、Kubectl简介基础命令1.基本信息命令2.创建和更新资源命令3.删除资源命令4. 查看日志和调试命令5. 端口转发和复制文件命令6. 部署管理命令7. 伸缩命令8. 配置和上下文管理命令9.常用命令 二、Pod简介核心概念pod常见状态调度和初始化阶段容器创建和运行阶段异常状…

【案例52】oracle进程占用CPU100%分析实战

问题现象 Linux环境&#xff0c;数据库CPU一直处于100%。业务系统运行很慢。Top命令结果如下&#xff1a; 问题分析 方法1 根据上图中的oracle进程在操作系统对应的 PID号 : 如 6999,8100 等 通过下面的SQL,查询 select s.SQL_HASH_VALUE, s.SQL_ADDRESSfrom v$session …

PCB线宽和线间距设计PCB抄板

尽量加宽电源、地线宽度&#xff0c;最好是地线比电源线宽&#xff0c;它们的关系是&#xff1a;地线>电源线>信号线&#xff0c;通常信号线宽&#xff1a;0.2~0.3mm&#xff0c;最细宽度可达到0.05~0.07mm&#xff0c;电源线宽为1.2~2.5mm 一般宽度不宜小于0.2mm(8mi…

鹭鹰优化算法SBOA优化RBF神经网络的扩散速度实现多数入多输出数据预测,可以更改数据集(MATLAB代码)

一、鹭鹰优化算法介绍 鹭鹰优化算法&#xff08;Secretary Bird Optimization Algorithm, SBOA&#xff09;是一种新型的元启发式算法&#xff0c;它于2024年4月由Youfa Fu等人提出&#xff0c;并发表在SCI人工智能二区顶刊《Artificial Intelligence Review》上。该算法的灵感…

【机器学习】神经网络简介以及如何用Tensorflow构建一个简单的神经网络

引言 神经网络是一种模拟人脑神经元连接和工作方式的计算模型&#xff0c;它是深度学习的基础&#xff0c;并在机器学习领域中扮演着重要角色 文章目录 引言一、神经网络简介1.1 结构组成1.2 工作原理1.3 学习过程1.4 应用领域1.5 感知器1.6 功能特点1.7 总结 二、用Tensorflow…

根据 Web 服务器端的架构相关知识,将PHP改JAVA重构企业网站系统

目录 案例 【题目】 【问题 1】(7 分) 【问题 2】(8 分) 【问题 3】(10 分) 答案 【问题 1】解析 【问题 2】解析 【问题 3】解析 相关推荐 案例 阅读以下关于应用服务器的叙述&#xff0c;在答题纸上回答问题 1 至问题 3。 【题目】 某电子产品制造公司&#xff0c…

现有electron-quick-start把vue项目打包后的dist打包exe自定义最小化点击事件

1.preload.js里暴露接口 const { contextBridge, ipcRenderer } require(electron) contextBridge.exposeInMainWorld(electronAPI, {WindowMin: (data) > {ipcRenderer.send(window-min, data);} });2.vue文件处理 if(window.electronAPI){window.electronAPI.WindowMi…

12/24/30v/36转固定5v输出芯片

设计电源芯片的应用方案时&#xff0c;必须保证输入电压在DC6V至30V范围内&#xff0c;输出电压为固定的5V&#xff0c;同时电流需在200至300mA之间。在这种需求下&#xff0c;推荐使用AH1405芯片&#xff0c;因其输入电压范围宽&#xff08;6-40V&#xff09;&#xff0c;内置…