机器学习实践(2.1)LightGBM分类任务

前言

LightGBM也属于Boosting集成学习模型(还有前面文章的XGBoost),LightGBM和XGBoost同为机器学习的集大成者。相比越来越流行的深度神经网络,LightGBM和XGBoost能更好的处理表格数据,并具有更强的可解释性,还具有易于调参、输入数据不变性等优势。

机器学习实践(1.2)XGBoost回归任务

机器学习实践(2.2)LightGBM回归任务

❤️ 本文完整脚本点此链接 百度网盘链接 获取 ❤️

结论先行
当使用 from lightgbm import LGBMClassifier 的模型进行训练时,使用的是sklearn中的 LGBMClassifier类,该方法中无需特意指定分类类别,方法自带类别数量_n_classes的计算,并根据数量指定了_objective参数,简而言之:该方法会自动判别是多分类还是二分类任务,无需特殊说明。

之所以特殊强调from lightgbm import LGBMClassifier 是要区别于import lightgbm as lgb 的调用,本人更建议使用前者。

下方代码取自 sklearn.py 的 class LGBMModel(_LGBMModelBase)…和class LGBMClassifier(_LGBMClassifierBase, LGBMModel)…

# class LGBMModel(_LGBMModelBase)......
"""
objective : str, callable or None, optional (default=None)
Specify the learning task and the corresponding learning objective or
a custom objective function to be used (see note below).
Default: 'regression' for LGBMRegressor, 'binary' or 'multiclass' for LGBMClassifier, 'lambdarank' for LGBMRanker.
"""  

# class LGBMClassifier(_LGBMClassifierBase, LGBMModel)......
def fit(self, X, y,
	# ......
	self._classes = self._le.classes_
	self._n_classes = len(self._classes)
	
	if self._n_classes > 2:
	    # Switch to using a multiclass objective in the underlying LGBM instance
	    ova_aliases = {"multiclassova", "multiclass_ova", "ova", "ovr"}
	    if self._objective not in ova_aliases and not callable(self._objective):
	        self._objective = "multiclass"
# ......

一.轻松实现多分类

1.1导入第三方库、数据集

# 导入第三方库,包括分类模型、数据集、数据集分割方法、评估方法
from lightgbm import LGBMClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score, precision_score, recall_score, f1_score, \
    classification_report
import lightgbm as lgb

# 导入sklearn的鸢尾花卉数据集,作为模型的训练和验证数据
data = datasets.load_iris()

# 数据划分,按照7 3分切割数据集为训练集和验证集,其中最终4个结果依次为训练数据、验证数据、训练数据的标签、验证数据的标签
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.3,random_state=123)

sklearn的鸢尾花卉数据集共150个数据样本,73切分后,训练集105个数据样本,验证集45个数据样本。数据集中包括 样本特征data(4个特征)、样本标签target(3类标签)、标签名称target_names([‘setosa’, ‘versicolor’, ‘virginica’])、特征名称feature_names([‘sepal length (cm)’, ‘sepal width (cm)’, ‘petal length (cm)’, ‘petal width (cm)’])、以及数据集位置filename(~~~\anaconda\lib\site-packages\sklearn\datasets\data\iris.csv)

数据集的 部分数据 如下:
在这里插入图片描述
数据集的 标签数据 及 标签名称 如下:在这里插入图片描述
数据集文件所在本地地址
在这里插入图片描述

1.2原参数模型训练、验证

# 默认参数的模型
model = LGBMClassifier()

# 模型训练
model.fit(X_train, y_train)

# 模型对验证数据做预测 y_pred 预测结果,y_proba 预测各类别概率,y_pred 是softmax(y_proba) 的结果 
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)

# print(y_pred)
# print(y_test.tolist())

# 为了便于观察验证数据的预测结果,写个循环传个参
for m, n, p in zip(y_proba, y_pred, y_test):
    if n == p:
        q = '预测正确'
    else:
        q = '预测错误'
        print('预测概率为{0}, 预测概率为{1}, 真实结果为{2}, {3}'.format(m, n, p, q))

# 准确率
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:%.2f%%' % (accuracy * 100))

打印运行结果如下
在这里插入图片描述

1.3修改模型参数、训练、保存、加载、验证

"""修改模型参数"""
model = LGBMClassifier(
    boosting_type='dart',  # 基学习器 gbdt:传统的梯度提升决策树; dart:Dropouts多重加性回归树
    n_estimators=20,  # 迭代次数
    learning_rate=0.1,  # 步长
    max_depth=5,  # 树的最大深度
    min_child_weight=1,  # 决定最小叶子节点样本权重和
    min_split_gain=0.1,  # 在树的叶节点上进行进一步分区所需的最小损失减少
    subsample=0.8,  # 每个决策树所用的子样本占总样本的比例(作用于样本)
    colsample_bytree=0.8,  # 建立树时对特征随机采样的比例(作用于特征)典型值:0.5-1
    random_state=27,  # 指定随机种子,为了复现结果
    importance_type='gain',  # 特征重要性的计算方式,split:分隔的总数; gain:总信息增益
)

"""模型训练"""
model.fit(X_train, y_train)

"""模型保存"""
model.booster_.save_model('lgb_multi_model.txt')

"""模型加载"""
clf = lgb.Booster(model_file='lgb_multi_model.txt')
# 设置模型的类别数
# 在 LightGBM 中,lgb.Booster 的 load_model() 方法加载的模型默认情况下无法进行 predict_proba() 操作。predict_proba() 方法用于获取预测样本属于各个类别的概率。
# 如需使用 predict_proba() 方法,需要在保存模型时使用参数 num_class 来指定模型的类别数,以便正确加载模型
num_class = n_classes  # 假设模型共有两个类别
clf.params['num_class'] = num_class

"""预测验证数据"""
def soft_max(pred, n_class):
    if n_class == 2:
        max_index = 0 if pred < 0.5 else 1
    else:
        max_value = max(pred)
        max_index = pred.index(max_value)

    return max_index

# 结果预测
y_pred = clf.predict(X_test).tolist()
y_pred = [soft_max(y, n_classes) for y in y_pred]
# 预测概率
y_proba = clf.predict(X_test, num_iteration=clf.best_iteration)

# 为了便于观察验证数据的预测结果,写个循环传个参
for m, n, p in zip(y_proba, y_pred, y_test):
    if n == p:
        q = '预测正确'
    else:
        q = '预测错误'
        print('预测概率为{0}, 预测概率为{1}, 真实结果为{2}, {3}'.format(m, n, p, q))

# 准确率
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:%.2f%%' % (accuracy * 100))

模型验证结果如下
在这里插入图片描述
模型参数可见保存的模型文件 lgb_multi_model.txt
在这里插入图片描述

1.4模型调参

这里采用mutual_info_score作为网格搜索GridSearchCV中的多分类调参评分标准,二分类可以使用roc_auc。更详细内容见 附加1 的文章内容,XGBoost调参和LightGBM调参并没有什么两样。

"""模型调参"""
def parameters():
    # learning_rate[default=0.3, alias: eta],range: [0,1]
    # learning_rate:一般这时候要调小学习率来测试,学习率越小训练速度越慢,模型可靠性越高,但并非越小越好
    params = {'learning_rate': [0.01, 0.05, 0.07, 0.1, 0.2, 0.25, 0.3, 0.4]}

    # 其他参数设置,每次调参将确定的参数加入
    fine_params = {'n_estimators': 20, 'max_depth': 5}
    return params, fine_params


def model_adjust_parameters(cv_params, other_params):
    # 模型调参
    model_ap = LGBMClassifier(**other_params)
    # sklearn提供的调参工具,训练集k折交叉验证(消除数据切分产生数据分布不均匀的影响)
    optimized_param = GridSearchCV(estimator=model_ap, param_grid=cv_params, scoring='mutual_info_score', cv=5, verbose=1)
    # 模型训练
    optimized_param.fit(X_train, y_train)
    # 对应参数的k折交叉验证平均得分
    means = optimized_param.cv_results_['mean_test_score']
    params = optimized_param.cv_results_['params']
    for mean, param in zip(means, params):
        print("mean_score: %f,  params: %r" % (mean, param))
    # 最佳模型参数
    print('参数的最佳取值:{0}'.format(optimized_param.best_params_))
    # 最佳参数模型得分
    print('最佳模型得分:{0}'.format(optimized_param.best_score_))


params_v, fine_params_v = parameters()
model_adjust_parameters(params_v, fine_params_v)

简单调参结果如下:
在这里插入图片描述

二.实现二分类同样简单

2.1导入数据集、训练、验证

导入数据集、训练、验证 与多分类完全一样,唯一需要改变的是将数据标签由n_classes>2转为n_classes=2

# 数据划分
X_train, X_test, y_train, y_test = ......  
# 接

# 训练集和验证集的标签都改成0和1
y_train = [1 if y > 0 else 0 for y in y_train]

y_test = [1 if y > 0 else 0 for y in y_test]

# 计算训练数据类别
n_classes = len(set(y_train))

# 接
# 默认参数的模型
model = LGBMClassifier()
......

2.2再做模型训练和验证

内容与1.2和1.3完全一致,不再赘述,直接看结果
二分类任务预测概率有两个,预测概率通过sigmoid做出预测结果。多分类预测概率有多个,预测概率通过softmax做出预测结果。
在这里插入图片描述

2.3重要结论映证

"""模型保存"""
model.booster_.save_model('lgb_multi_model.txt')

"""模型加载"""
clf = lgb.Booster(model_file='lgb_multi_model.txt')

"""模型参数打印"""
model_params = clf.dump_model()

print('模型参数值-开始'.center(20, '='))
# lightgbm模型参数直接打开模型文件查看更为方便
print(model_params)
print('模型参数值-结束'.center(20, '='))

下图展示 lgb_multi_model.txt 模型参数 objective=binary sigmoid:1 明显区别于多分类任务,映证了最前面的结论。
在这里插入图片描述

三.模型评估

评估方法更详细解释,见附加3的文章内容

def metrics_sklearn(class_num, y_valid, y_pred_, y_prob):
    """模型效果评估"""
    # 准确率
    # 准确度 accuracy_score:分类正确率分数,函数返回一个分数,这个分数或是正确的比例,或是正确的个数,不考虑正例负例的问题,区别于 precision_score
    # 一般不直接使用准确率,主要是因为类别不平衡问题,如果大部分是negative的 而且大部分模型都很容易判别出来,那准确率都很高, 没有区分度,也没有实际意义(因为negative不是我们感兴趣的)
    accuracy = accuracy_score(y_valid, y_pred_)
    print('Accuracy:%.2f%%' % (accuracy * 100))

    # 精准率
    if class_num == 2:
        precision = precision_score(y_valid, y_pred_)
    else:
        precision = precision_score(y_valid, y_pred_, average='macro')
    print('Precision:%.2f%%' % (precision * 100))

    # 召回率
    # 召回率/查全率R recall_score:预测正确的正样本占预测正样本的比例, TPR 真正率
    # 在二分类任务中,召回率表示被分为正例的个数占所有正例个数的比例;如果是多分类的话,就是每一类的平均召回率
    if class_num == 2:
        recall = recall_score(y_valid, y_pred_)
    else:
        recall = recall_score(y_valid, y_pred_, average='macro')
    print('Recall:%.2f%%' % (recall * 100))

    # F1值
    if class_num == 2:
        f1 = f1_score(y_valid, y_pred_)
    else:
        f1 = f1_score(y_valid, y_pred_, average='macro')
    print('F1:%.2f%%' % (f1 * 100))

    # auc曲线下面积
    # 曲线下面积 roc_auc_score 计算AUC的值,即输出的AUC(二分类任务中 auc 和 roc_auc_score 数值相等)
    # 计算auc,auc就是曲线roc下面积,这个数值越高,则分类器越优秀。这个曲线roc所在坐标轴的横轴是FPR,纵轴是TPR。
    # 真正率:TPR = TP/P = TP/(TP+FN)、假正率:FPR = FP/N = FP/(FP+TN)
    # auc:不支持多分类任务 计算ROC曲线下的面积
    # 二分类问题直接用预测值与标签值计算:auc = roc_auc_score(Y_test, Y_pred)
    # 多分类问题概率分数 y_prob:auc = roc_auc_score(Y_test, Y_pred_prob, multi_class='ovo') 其中multi_class必选
    if class_num == 2:
        auc = roc_auc_score(y_valid, y_pred_)
    else:
        auc = roc_auc_score(y_valid, y_prob, multi_class='ovo')
        # auc = roc_auc_score(y_valid, y_prob, multi_class='ovr')
    print('AUC:%.2f%%' % (auc * 100))

    # 评估效果报告
    print(classification_report(y_test, y_pred, target_names=['0:setosa', '1:versicolor', '2:virginica']))


"""模型效果评估"""
metrics_sklearn(n_classes, y_test, y_pred, y_proba)

多分类模型效果评估结果入下图所示
在这里插入图片描述
本文完整脚本点此链接 百度网盘链接 获取

附加——深入学习集成学习

附加1.模型调参、训练、保存、评估和预测

见《XGBoost模型调参、训练、评估、保存和预测》 ,包含模型脚本文件

附加2.算法原理

见《XGBoost算法原理及基础知识》 ,包括集成学习方法,XGBoost模型、目标函数、算法,公式推导等

附加3.分类任务的评估指标值详解

见《分类任务评估1——推导sklearn分类任务评估指标》,其中包含了详细的推理过程;
见《分类任务评估2——推导ROC曲线、P-R曲线和K-S曲线》,其中包含ROC曲线、P-R曲线和K-S曲线的推导与绘制;

附加4.模型中树的绘制和模型理解

见《Graphviz绘制模型树1——软件配置与XGBoost树的绘制》,包含Graphviz软件的安装和配置,以及to_graphviz()和plot_trees()两个画图函数的部分使用细节;
见《Graphviz绘制模型树2——XGBoost模型的可解释性》,从模型中的树着手解释XGBoost模型,并用EXCEL构建出模型。

附加5.集成学习实践

见机器学习实践(1.1)XGBoost分类任务,包含二分类、多分类任务以及多分类的评估方法;
见机器学习实践(1.2)XGBoost回归任务,包含回归任务模型训练、评估(R2、MSE);
见机器学习实践(2.2)LightGBM回归任务,包含LightGBM模型的调参、训练、保存、调用、评估。

❤️ 机器学习内容持续更新中… ❤️


声明:本文所载信息不保证准确性和完整性。文中所述内容和意见仅供参考,不构成实际商业建议,可收藏可转发但请勿转载,如有雷同纯属巧合。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka的基本概念及其关键原理

Apache Kafka是一种分布式事件存储和流处理平台。该项目旨在提供一个统一的、高吞吐量、低延迟的平台&#xff0c;用于处理实时数据流。 •Kafka可以通过Kafka Connect连接到外部系统&#xff08;用于数据导入/导出&#xff09;&#xff0c;并提供Kafka Streams库用于流处理应用…

回溯算法组合问题之77组合

题目&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 题目链接&#xff1a;77. 组合 - 力扣&#xff08;LeetCode&#xff09; 示例&#xff1a; 解法&#xff1a; 回溯法三部曲&#xff1a; &a…

简易评分系统

目录 一、实验目的 二、操作环境 三、实验内容和过程 1.实验内容 2.代码 2.1 用户验证功能 2.2 菜单函数 2.3 评分功能 四、结果分析 总体的输出结果&#xff1a; 保存文件成功截图&#xff1a; 五、小结 一、实验目的 1.巩固和提高学生学过的基础理论和专业知识&am…

55 # 实现可写流

先在 LinkedList.js 给链表添加一个移除方法 class Node {constructor(element, next) {this.element element;this.next next;} }class LinkedList {constructor() {this.head null; // 链表的头this.size 0; // 链表长度}// 可以直接在尾部添加内容&#xff0c;或者根据…

java贪心算法案例

1.零钱找回问题 这个问题在我们的日常生活中就更加普遍了。假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4, c5, c6张。现在要用这些钱来支付K元&#xff0c;至少要用多少张纸币&#xff1f;用贪心算法的思想&#xff0c;很显然&#xff0c;每一步…

计算机网络 day7 扫描IP脚本 - 路由器 - ping某网址的过程

目录 network 和 NetworkManager关系&#xff1a; 实验&#xff1a;编写一个扫描脚本&#xff0c;知道本局域网里哪些ip在使用&#xff0c;哪些没有使用&#xff1f; 使用的ip对应的mac地址都要显示出来 计算机程序执行的两种不同方式&#xff1a; shell语言编写扫描脚本 …

漏洞攻击 --- TCP -- 半开攻击、RST攻击

TCP半开攻击&#xff08;半连接攻击&#xff09; --- syn攻击 &#xff08;1&#xff09;定义&#xff1a; sys 攻击数据是DOS攻击的一种&#xff0c;利用TCP协议缺陷&#xff0c;发送大量的半连接请求&#xff0c;耗费CPU和内存资源&#xff0c;发生在TCP三次握手中。 A向B…

为什么ConcurrentHashMap不允许插入null值而HashMap可以?

为什么ConcurrentHashMap不允许插入null值而HashMap可以&#xff1f; 文章目录 为什么ConcurrentHashMap不允许插入null值而HashMap可以&#xff1f;HashMap源码ConcurrentHashMap源码为什么ConcurrentHashMap需要加空值校验呢&#xff1f;二义性问题测试代码代码分析测试结果结…

LangChain + Embedding + Chromdb,关联使用ChatGLM的本地搭建训练平台教程

一.介绍 OpenAI 在国内用户注册会遇到各种阻力&#xff0c;目前可行的方法是使用本地数据集的功能实现联网搜索并给出回答&#xff0c;提炼出TXT、WORD 文档里的内容。 现在主流的技术是基于强大的第三方开源库&#xff1a;LangChain 。 文档地址&#xff1a;&#x1f99c;…

win11安装redis步骤详解

文章目录 一、redis的安装与下载1、下载2、解压3、启动redis4、测试是否安装成功 二、将redis加入到windows的服务中三、常用的redis服务命令 安装可参考的资料&#xff1a;https://www.runoob.com/redis/redis-install.html 一、redis的安装与下载 1、下载 下载地址&#xf…

提示工程师:如何写好Prompt

提示工程由来 提示工程是一门相对较新的学科&#xff0c;用于开发和优化提示以有效地将语言模型 (LM) 用于各种应用程序和研究主题。 研究人员使用提示工程来提高 LLM 在广泛的常见和复杂任务&#xff08;例如问题回答和算术推理&#xff09;上的能力。 开发人员使用提示工程…

120、仿真-51单片机温湿度光照强度C02 LCD1602 报警设计(Proteus仿真+程序+元器件清单等)

方案选择 单片机的选择 方案一&#xff1a;STM32系列单片机控制&#xff0c;该型号单片机为LQFP44封装&#xff0c;内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ&#xff0c;在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

【Docker】Docker安装与操作

docker的安装与命令 一、安装 docker1. 安装依赖包2. 信息查看 二、Docker 镜像操作1. 搜索镜像2. 获取镜像3. 镜像加速下载4. 查看镜像相关信息5. 删除镜像6. 上传镜像7. 存出和载入镜像 三、Docker 容器操作1. 创建容器2. 查看容器3. 启动容器4. 停止容器5. 进入容器6. 容器与…

SpringBoot整合SpringCloudStream3.1+版本Kafka

SpringBoot整合SpringCloudStream3.1版本Kafka 下一节直通车 SpringBoot整合SpringCloudStream3.1版本的Kafka死信队列 为什么用SpringCloudStream3.1 Springcloud架构提供&#xff0c;基于spring生态能够快速切换市面上常见的MQ产品3.1后使用配置文件的形式定义channel&am…

# Linux下替换删除文件中的颜色等控制字符的方法

Linux下替换删除文件中的颜色等控制字符的方法 文章目录 Linux下替换删除文件中的颜色等控制字符的方法1 Linux下的控制字符&#xff08;显示的文字并不是他本身&#xff09;&#xff1a;2 颜色字符范例&#xff1a;3 替换4 最后 我们在shell编程显示输出时&#xff0c;会定义文…

Linux的时间函数

2023年7月19日&#xff0c;周三下午 我今天基于GitHub搭建了自己的博客网站&#xff0c;欢迎大家来我的个人博客网站阅读我的博客 巨龙之路的GitHub个人博客 (julongzhilu.github.io) 目录 time函数原型使用方法ctime函数原型使用方法疑惑gmtime、 localtime函数原型什么是分…

WEB:FlatScience

背景知识 sql注入 SQLite数据库知识 SQLite3注入方法 题目 用dirsearch进行扫描&#xff0c;下面几个关键目录&#xff1a;robots.txt&#xff0c;login.php&#xff0c;admin.php&#xff0c;剩下的目录就是一些pdf格式的论文了 一个一个访问并查看源代码&#xff0c;在查看l…

常用API学习06(Java)

Biglnteger public BigInteger(int num, Random rnd) 获取随机大整数&#xff0c;范围&#xff1a;[0~2的num次方-1] public BigInteger(String val) 获取指定的大整数 public BigInteger(String val, int radix) 获取指定进制的大整数 public static BigInteg…

怎么给pdf文件加密?pdf文档如何加密

在数字化时代&#xff0c;保护个人和机密信息的重要性越来越受到关注。PDF&#xff08;Portable Document Format&#xff09;是一种广泛使用的文件格式&#xff0c;用于共享和存储各种类型的文档。然而&#xff0c;由于其易于编辑和复制的特性&#xff0c;保护PDF文件中的敏感…

一张表实现短视频“评论区“完整功能

前言 现如今&#xff0c;不管是哪种类型的应用&#xff0c;评论区都少不了。从工具类的到媒体信息流类的&#xff0c;评论留言都是最基本的互动环节。比如抖音短视频下&#xff0c;针对视频每个用户都可以发表自己的观点&#xff1b;而针对用户的评论&#xff0c;其他的用户又可…