1. LightGBM简介

1.1 简介

LightGBM是的XGBoost的升级版,与XGBoost有近似精度的前提下,又大大提高了训练速度。

  • LightGBM的主要优点:

    1. 简单易用。提供了主流的Python\C++\R语言接口,用户可以轻松使用LightGBM建模并获得相当不错的效果。
    2. 高效可扩展。在处理大规模数据集时高效迅速、高准确度,对内存等硬件资源要求不高。
    3. 鲁棒性强。相较于深度学习模型不需要精细调参便能取得近似的效果。
    4. LightGBM直接支持缺失值与类别特征,无需对数据额外进行特殊处理
  • LightGBM的主要缺点:

    1. 相对于深度学习模型无法对时空位置建模,不能很好地捕获图像、语音、文本等高维数据。
    2. 在拥有海量训练数据,并能找到合适的深度学习模型时,深度学习的精度可以遥遥领先LightGBM。

1.2 应用

LightGBM在机器学习与数据挖掘领域有着极为广泛的应用。据统计LightGBM模型自2016到2019年在Kaggle平台上累积获得数据竞赛前三名三十余次,其中包括CIKM2017 AnalytiCup、IEEE Fraud Detection等知名竞赛。这些竞赛来源于各行各业的真实业务,这些竞赛成绩表明LightGBM具有很好的可扩展性,在各类不同问题上都可以取得非常好的效果。

同时,LightGBM还被成功应用在工业界与学术界的各种问题中。例如金融风控、购买行为识别、交通流量预测、环境声音分类、基因分类、生物成分分析等诸多领域。虽然领域相关的数据分析和特性工程在这些解决方案中也发挥了重要作用,但学习者与实践者对LightGBM的一致选择表明了这一软件包的影响力与重要性。

2. 实战

2.1 大体思路

本次实战的大体思路为:

  1. 给定特定场次的数据:击杀数、死亡数、金币数量、经验值、等级……等信息
  2. 通过01中给定的数据,预测本场次是否为蓝方获胜
  3. 需要注意的是,LightGBM可以支持缺项数据,无需额外处理

2.2 数据准备

  • 数据集:train.csv

  • 数据准备阶段的常规思路如下:

    1. 首先确定是否存在数据不平衡的问题

    比如,数据中99%的是蓝方获胜,1%是红方获胜,那么这种数据估计难以起到训练的效果

    1. 可以利用热力图剔除相关性极强的特征
    2. 利用小提琴图分析某个特征与是否获胜之间的相关性
    3. 利用散点图进一步分析
    4. 去除与结论关联性不大的特征
    5. 对相关性较高的特征,进行组合
    6. 训练模型
    7. 评估模型
    8. 参数优化
    9. 评估模型

    2.3 代码讲解

    读取数据

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
#%%
df = pd.read_csv("3_dataset/high_diamond_ranked_10min.csv")
df

数据常用统计

拿到数据之后,一般会info(),valuecount()和describe()等函数初步查看数据的分布。

y = df.blueWins
y
# %%
df.info()

从info的结果中可以看到,各个数据的notnull都是相同的,说明没有空数据。无需进行填充处理。

df.describe()

从数据的describe可以查看数据的常见统计量(计数、均值、标准差、最小值、最大值,和四分位值)

y = df.blueWins
y#%%
y.value_counts()

从以上数据分布中可知,数据的正负样本数量基本一致,不存在数据不平衡的问题

数据清洗

首先我们需要去掉与结果无关的特征列,比如gameId,blueWins.


drop_cols = ["gameId","blueWins"]
x = df.drop(drop_cols,axis=1)
x.describe()

从上图的结果中可以看到:

  • 我们发现不同对局中插眼数和拆眼数的取值范围存在明显差距,甚至有前十分钟插了250个眼的异常值。
  • 我们发现EliteMonsters的取值相当于Deagons + Heralds。
  • 我们发现TotalGold 等变量在大部分对局中差距不大。
  • 我们发现两支队伍的经济差和经验差是相反数。
  • 我们发现红队和蓝队拿到首次击杀的概率大概都是50%

其实我并没有发现,是天池原文作者发现的


## 根据上面的描述,我们可以去除一些重复变量,比如只要知道蓝队是否拿到一血,我们就知道红队有没有拿到,可以去除红队的相关冗余数据。
drop_cols = ['redFirstBlood','redKills','redDeaths','redGoldDiff','redExperienceDiff', 'blueCSPerMin','blueGoldPerMin','redCSPerMin','redGoldPerMin']
x.drop(drop_cols, axis=1, inplace=True)

可视化描述数据

data = x
data_std = (data - data.mean())/data.std()
data = pd.concat([y, data_std.iloc[:, 0:9]], axis=1)
data = pd.melt(data, id_vars="blueWins",var_name="Features", value_name="Values")fig, ax = plt.subplots(1, 2, figsize=(15, 5))# 绘制小提琴图sns.violinplot(x="Features", y="Values", hue="blueWins", data=data,split=True, inner="quart", ax=ax[0], palette="Blues")
fig.autofmt_xdate(rotation=45)

首先,先让数据正则化一下。

我们知道,如果 X ∼ N ( μ , σ ) X \sim N(\mu,\sigma) X∼N(μ,σ) , 那么 X − μ σ ∼ N ( 0 , 1 ) \frac{X-\mu}{\sigma} \sim N(0,1) σX−μ​∼N(0,1),代码中的前两行正是利用这这样一种特点来对数据进行正则化。

下面针对所有数据绘制一遍小提琴图:

data = x
data_std = (data - data.mean())/data.std()
data = pd.concat([y, data_std.iloc[:, 0:9]], axis=1)
data = pd.melt(data, id_vars="blueWins",var_name="Features", value_name="Values")fig, ax = plt.subplots(1, 2, figsize=(15, 5))# 绘制小提琴图sns.violinplot(x="Features", y="Values", hue="blueWins", data=data,split=True, inner="quart", ax=ax[0], palette="Blues")
fig.autofmt_xdate(rotation=45)data = x
data_std = (data - data.mean()) / data.std()
data = pd.concat([y, data_std.iloc[:, 9:18]], axis=1)
data = pd.melt(data, id_vars='blueWins', var_name='Features', value_name='Values')# 绘制小提琴图
sns.violinplot(x='Features', y='Values', hue='blueWins', data=data, split=True, inner='quart', ax=ax[1], palette='Blues')
fig.autofmt_xdate(rotation=45)plt.show()

小提琴图怎么看呢?见下图:

小提琴图 (Violin Plot)是用来展示多组数据的分布状态以及概率密度。这种图表结合了箱形图和密度图的特征,主要用来显示数据的分布形状。

从图中我们可以看出:

  • 击杀英雄数量越多更容易赢,死亡数量越多越容易输(bluekills与bluedeaths左右的区别)。
  • 助攻数量与击杀英雄数量形成的图形状类似,说明他们对游戏结果的影响差不多。
  • 一血的取得情况与获胜有正相关,但是相关性不如击杀英雄数量明显。
  • 经济差与经验差对于游戏胜负的影响较小。
  • 击杀野怪数量对游戏胜负的影响并不大

其实我并没有看出来,还是天池的原文作者看出来的


plt.figure(figsize=(18, 14))
sns.heatmap(round(x.corr(), 2), cmap="Blues", annot=True)
plt.show()

从热力图中可以看到相互关联强的特征。然后去除一部分。

#%%
# 去除冗余特征
drop_cols = ['redAvgLevel','blueAvgLevel']
x.drop(drop_cols, axis=1, inplace=True)sns.set(style='whitegrid', palette='muted')# 构造两个新特征
x['wardsPlacedDiff'] = x['blueWardsPlaced'] - x['redWardsPlaced']
x['wardsDestroyedDiff'] = x['blueWardsDestroyed'] - x['redWardsDestroyed']data = x[['blueWardsPlaced','blueWardsDestroyed','wardsPlacedDiff','wardsDestroyedDiff']].sample(1000)
data_std = (data - data.mean()) / data.std()
data = pd.concat([y, data_std], axis=1)
data = pd.melt(data, id_vars='blueWins', var_name='Features', value_name='Values')plt.figure(figsize=(10,6))
sns.swarmplot(x='Features', y='Values', hue='blueWins', data=data)
plt.xticks(rotation=45)
plt.show()

我们画出了插眼数量的散点图,发现不存在插眼数量与游戏胜负间的显著规律。猜测由于钻石分段以上在哪插眼在哪好排眼都是套路,所以数据中前十分钟插眼数拔眼数对游戏的影响不大。所以我们暂时先把这些特征去掉。

## 去除和眼位相关的特征
drop_cols = ['blueWardsPlaced','blueWardsDestroyed','wardsPlacedDiff','wardsDestroyedDiff','redWardsPlaced','redWardsDestroyed']
x.drop(drop_cols, axis=1, inplace=True)
x['killsDiff'] = x['blueKills'] - x['blueDeaths']
x['assistsDiff'] = x['blueAssists'] - x['redAssists']x[['blueKills','blueDeaths','blueAssists','killsDiff','assistsDiff','redAssists']].hist(figsize=(12,10), bins=20)
plt.show()

我们发现击杀、死亡与助攻数的数据分布差别不大。但是击杀减去死亡、助攻减去死亡的分布与原分布差别很大,因此我们新构造这么两个特征。

data = x[['blueKills','blueDeaths','blueAssists','killsDiff','assistsDiff','redAssists']].sample(1000)
data_std = (data - data.mean()) / data.std()
data = pd.concat([y, data_std], axis=1)
data = pd.melt(data, id_vars='blueWins', var_name='Features', value_name='Values')plt.figure(figsize=(10,6))
sns.swarmplot(x='Features', y='Values', hue='blueWins', data=data)
plt.xticks(rotation=45)
plt.show()

从上图我们可以发现击杀数与死亡数与助攻数,以及我们构造的特征对数据都有较好的分类能力。

一些特征的两两组合对于数据划分能力也有提升。


# %%
x["dragonDiff"] = x["blueDragons"] - x["redDragons"]
x["heraldDiff"] = x["blueHeralds"] - x["redHeralds"]
x["eliteDiff"] = x["blueEliteMonsters"] - x["redEliteMonsters"]data = pd.concat([y, x], axis=1)eliteGroup = data.groupby(['eliteDiff'])['blueWins'].mean()
dragonGroup = data.groupby(['dragonDiff'])['blueWins'].mean()
heraldGroup = data.groupby(['heraldsDiff'])['blueWins'].mean()fig , ax = plt.subplots(1,3,figsize=(15,4))eliteGroup.plot(kind="bar",ax=ax[0])
dragonGroup.plot(kind="bar",ax=ax[1])
heraldGroup.plot(kind="bar",ax=ax[2])print(eliteGroup)
print(dragonGroup)
print(heraldGroup)plt.show()

之后又判断了两个队伍是否拿到了龙,是否拿到了峡谷先锋、击杀大型野怪的数量差值,发现在游戏的前期拿到龙比拿到峡谷先锋更容易取得胜利。

x['towerDiff'] = x['blueTowersDestroyed'] - x['redTowersDestroyed']data = pd.concat([y, x], axis=1)towerGroup = data.groupby(['towerDiff'])["blueWins"]print(towerGroup.count())
print(towerGroup.mean())fig, ax = plt.subplots(1, 2, figsize=(15, 5))towerGroup.mean().plot(kind="line", ax=ax[0])
ax[0].set_title("Proportion of Blue Wins")
ax[0].set_ylabel("Proportion")towerGroup.mean().plot(kind="line",ax=ax[1])
ax[1].set_title("Count of Towers Destroyed")
ax[1].set_ylabel("Count")plt.show()

模型训练

数据划分

前面已经清洗完成的数据,在这里应该进行切分了。训练集:测试集 = 4:1


from sklearn.model_selection import train_test_split
data_target_part = y
data_feature_part = xx_train, x_test, y_train, y_test = train_test_split(data_feature_part, data_target_part, test_size=0.2, random_state=20210311)

模型训练


from lightgbm import LGBMClassifier
clf = LGBMClassifier()
clf.fit(x_train, y_train)

模型评估

对模型进行训练。因为lightgbm的强大,会发现数据训练的非常快。训练完成之后我们对结果进行预测。


train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)print(f"train_predict:{train_predict} \n test_predict:{test_predict}")

直接看两个数组没什么好玩的,我们应该看混淆矩阵

from sklearn import metricsprint(f"accuracy of train:{metrics.accuracy_score(y_train,train_predict)}")
print(f"accuracy of test:{metrics.accuracy_score(y_test,test_predict)}")confusion_matrix_result =  metrics.confusion_matrix(test_predict,y_test)
print(f"confusion_matrix:{confusion_matrix_result}")plt.figure()
sns.heatmap(confusion_matrix_result,annot=True,cmap="Blues")
plt.xlabel("Predict labels")
plt.ylabel("True labels")
plt.show()

混淆矩阵的结果如下图所示:

从热力图的颜色分布来看,这个结果还是可以接受的。

2.4 利用LightGBM进行特征选择

我们可以利用seaborn来直观的查看特征的重要性,来决定今后进行类似的任务的时候应该利用什么特征。


sns.barplot(y=data_feature_part.columns,x=clf.feature_importances_)

2.5 模型优化

模型优化的本质就是调整超参数。

LightGBM中包括但不限于下列对模型影响较大的参数:

  1. learning_rate

也叫eta,系统默认0.3

  1. num_leves

控制每棵树中最大叶子节点的数量

  1. feature_fraction

系统默认值为1,我们一般设置成0.8左右。用来控制每棵随机采用的列数的占比(每一列是一个特征)

  1. max-depth

系统默认值为6,一般取3-10之间。这个值为树的最大深度,用来控制过拟合。max-depth越大,模型的学习更加具体

常用的调参方法有贪心算法、网格调参、贝叶斯调参等。网格搜索是穷举,下面尝试网格搜索方法。


from sklearn.model_selection import GridSearchCVlearning_rate = [0.1,0.3,0.6]
feature_fraction = [0.5,0.8,1]
num_leves =  [16,32,64]
max_depth = [-1,3,5,8]parameters = {"learning_rate":learning_rate,"feature_fraction":feature_fraction,"num_leves":num_leves,"max_depth":max_depth
}model = LGBMClassifier(n_estimators = 50)clf = GridSearchCV(model,parameters,cv=3,scoring="accuracy",verbose=3,n_jobs=-1)
clf = clf.fit(x_train,y_train)clf.best_params_

最后形成的超参数集合如下:

优化后的模型重新评估

clf = LGBMClassifier(feature_fraction=1, learning_rate=0.1, max_depth=3, num_leves=16)
clf.fit(x_train,y_train)train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)print(f"train accuracy:{metrics.accuracy_score(y_train,train_predict)}")
print(f"test accuracy:{metrics.accuracy_score(y_test,test_predict)}")confusion_matrix_result = metrics.confusion_matrix(y_test,test_predict)
print(f"confusion matrix:{confusion_matrix_result}")plt.figure(figsize=(8,6))
sns.heatmap(confusion_matrix_result,annot=True,cmap="Blues")
plt.xlabel("Predicted labels")
plt.ylabel("True labels")
plt.show()

龙珠计划-机器学习-day03-基于LightGBM的分类预测相关推荐

  1. 机器学习算法(七): 基于LightGBM的分类预测(基于英雄联盟10分钟数据判断红蓝方胜负)

    机器学习算法(七)基于LightGBM的分类预测 1. 实验室介绍 1.1 LightGBM的介绍 LightGBM是2017年由微软推出的可扩展机器学习系统,是微软旗下DMKT的一个开源项目,由20 ...

  2. 机器学习应用篇(七)——基于LightGBM的分类预测

    机器学习应用篇(七)--基于LightGBM的分类预测 文章目录 机器学习应用篇(七)--基于LightGBM的分类预测 一.Introduction 1 LightGBM的优点 2 LightGBM ...

  3. 机器学习训练营-基于XGBoost的分类预测学习笔记

    文章目录 前言 一.学习知识点概要 二.学习内容 1 XGBoost的应用及优缺点 1.1 XGBoost的应用 1.2 XGBoost的优缺点 2 基于天气数据集的XGBoost分类实战 2.1 目 ...

  4. 机器学习(三):基于LightGBM的分类预测

    LightGBM介绍 LightGBM是2017年由微软推出的可扩展机器学习系统,是微软旗下DMKT的一个开源项目,由2014年首届阿里巴巴大数据竞赛获胜者之一柯国霖老师带领开发.它是一款基于GBDT ...

  5. 基于LightGBM的分类预测

    一.学习知识点概要 1.1 LightGBM的介绍 1). 2017年经微软推出,XGBoost的升级版 2). 模型精度: 两个模型精度相当 3). 训练速度: LightGBM训练的速度更快 =& ...

  6. A.机器学习入门算法[七]:基于英雄联盟数据集的LightGBM的分类预测

    [机器学习入门与实践]入门必看系列,含数据挖掘项目实战:数据融合.特征优化.特征降维.探索性分析等,实战带你掌握机器学习数据挖掘 专栏详细介绍:[机器学习入门与实践]合集入门必看系列,含数据挖掘项目实 ...

  7. 天池龙珠计划机器学习训练营机器学习基础知识学习笔记--Task03

    天池龙珠计划机器学习训练营–Task03重点记录 LightGBM的介绍 LightGBM的主要优点: 简单易用.提供了主流的Python\C++\R语言接口,用户可以轻松使用LightGBM建模并获 ...

  8. 重修-龙珠计划机器学习训练营task3-LightGBM学习笔记

    文章标题:龙珠计划机器学习训练营task3-LightGBM学习笔记 一.学习知识点概要 LightGBM是2017年由微软推出的可扩展机器学习系统,是微软旗下DMKT的一个开源项目,由2014年首届 ...

  9. 重修-龙珠计划机器学习训练营task1-part2学习笔记

    文章标题:龙珠计划机器学习训练营task1-part2学习笔记 一.学习知识点概要 利用鸢花数据(iris)进行逻辑回归方法的训练,该数据集一共包含5个变量,其中4个特征变量,1个目标分类变量.共有1 ...

最新文章

  1. 创建 OVS vlan101 并部署 instance - 每天5分钟玩转 OpenStack(139)
  2. 2021-11-09类作为成员变量类型
  3. python 端口扫描
  4. (转)PHP利用Curl、socket、file_get_contents POST数据
  5. iPadOS 14.7和macOS 11.5,以及操作系统更新的安全说明
  6. android5.1 xposed,Xposed框架oppo下载
  7. 1433端口被运营商封锁的解决方法
  8. Opencv python 直方图处理
  9. CAR-T细胞治疗最新进展(2021年12月)
  10. 天图投资冲刺港股:资产管理规模249亿 投了小红书与奈雪
  11. webstrom怎么配置git并提交
  12. Bootstrap实战 - 响应式布局
  13. linux 循环一段ip区间,Shell脚本实现判断IP地址是否在一个ip段内代码分享
  14. 开发c语言系统怎么分工,C语言专业课程设计工资统一标准管理系统.doc
  15. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之二、会中智能
  16. 步进电机替换伺服电机如何计算?
  17. Mac电脑远程连接Windows桌面Microsoft Remote Desktop
  18. 淘宝(客户端)上的店家里面的视频是如何下载的
  19. 中兴oltc320用户手册_中兴C320C300 V2版本OLT开局配置手册
  20. 武汉智能网联道路智能化建设规范

热门文章

  1. myBatis框架和Spring框架的整合
  2. element-wise product operation
  3. PHP中利用EXIF函数集来显示单反照片的EXIF信息
  4. HDU Problem H [ 大魔王 矩阵三角模型变式 ]——基础dp变式
  5. Iptables 规则用法小结
  6. PL/SQL永久注册码
  7. 深入理解Netfilter和iptables
  8. Oracle 物化视图(MV)详解
  9. MTU的概念,什么是路径MTU? MTU发现机制,TraceRoute(了解)
  10. Unity自定义mesh绘制