机器学习 | 深入集成学习的精髓及实战技巧挑战
目录
xgboost算法简介
泰坦尼克号乘客生存预测(实操)
lightGBM算法简介
《绝地求生》玩家排名预测(实操)
xgboost算法简介
XGBoost全名叫极端梯度提升树,XGBoost是集成学习方法的王牌,在Kaggle数据挖掘比赛中,大部分获胜者用了XGBoost。XGBoost在绝大多数的回归和分类问题上表现的十分顶尖,接下来将较详细的介绍XGBoost的算法原理。
最优模型构建方法:构建最优模型的一般方法是最小化训练数据的损失函数。用字母L表示损失:

其中,F是假设空间,假设空间是在已知属性和属性可能取值的情况下,对所有可能满足目标的情况的一种毫无遗漏的假设集合。
上述公式称为经验风险最小化,训练得到的模型复杂度较高。当训练数据较小时,模型很容易出现过拟合问题。
为了降低模型的复杂度,常采用下式:

上述公式称为结构风险最小化,结构风险最小化的模型往往对训练数据以及未知的测试数据都有较好的预测。
目标函数:即损失函数,通过最小化损失函数来构建最优模型。由前面可知,损失函数应加上表示模型复杂度的正则项,且XGBoost对应的模型包含了多个CART树,因此,模型的目标函数为:

上述公式是正则化的损失函数,其中yi是模型的实际输出结果,yi^是模型的输出结果,等式右边第一部分是模型的训练误差,第二部分是正则化项,这里的正则化项是K棵树的正则化项相加而来的。
CART树的介绍:下图为第K棵CART树,确定一棵CART树需要确定两部分:

第一部分就是树的结构,这个结构将输入样本映射到一个确定的叶子节点上,记为fk(x);
第二部分就是各个叶子节点的值,q(x)表示输出的叶子节点序号,wq(x)表示对应叶子节点序号的值。由定义得:
树的复杂度定义:XGBoost法对应的模型包含了多棵cart树,定义每棵树的复杂度:

树的复杂度举例:
假设我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示:

就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以:
1)小男孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2+0.9=2.9。
2)爷爷的预测分数同理:-1+(-0.9)= -1.9。
具体如下图所示:

如下例树的复杂度表示:

如果想使用 xgboost 的话,需要终端执行如下命令进行安装:
pip install xgboost -i https://pypi.mirrors.ustc.edu.cn/simple
xgboost虽然被称为kaggle比赛神奇,但是,我们要想训练出不错的模型,必须要给参数传递合适的值。 xgboost中封装了很多参数,主要由三种类型构成:通用参数(generalparameters),Booster参数(boosterparameters)和学习目标参数(taskparameters)
通用参数:主要是宏观函数控制

Booster参数:取决于选择的Booster类型,用于控制每一步的booster(tree,regressiong)



学习目标参数:控制训练目标的表现

泰坦尼克号乘客生存预测(实操)
泰坦尼克号沉没是历史上最臭名昭着的沉船之一。1912年4月15日,在她的处女航中,泰坦尼克号在与冰山相撞后沉没,在2224名乘客和机组人员中造成1502人死亡。这场耸人听闻的悲剧震惊了国际社会,并为船舶制定了更好的安全规定。造成海难失事的原因之一是乘客和机组人员没有足够的救生艇。尽管幸存下沉有一些运气因素,但有些人比其他人更容易生存,例如妇女,儿童和上流社会。在这个案例中,我们要求您完成对哪些人可能存活的分析。特别是,我们要求您运用机器学习工具来预测哪些乘客幸免于悲剧。
我们参考kaggle平台提供的案例:网址 :
我们提取到的数据集中的特征包括票的类别,是否存活,乘坐班次,年龄,登陆home.dest,房间,船和性别等。数据来自:数据集 :
经过观察数据得到:
1)坐班是指乘客班(1,2,3),是社会经济阶层的代表。
2)其中age数据存在缺失。
接下来我们借助 jupyter 工具进行构建我们这个预测,方便我们观察:
导入需要的模块:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier
获取数据:

数据基本处理:
# 2.数据基本处理
# 2.1确定特征值,目标值
x = titan[["pclass", "age", "sex"]]
y = titan["survived"]# 2.2缺失值处理
x["age"].fillna(value=titan["age"].mean(), inplace=True)# 2.3数据集的划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22, train_size=0.2)

特征工程—字典特征抽取:特征出现类别符号需进行one-hot编码处理x.to_dict(orient="records")需要将数组特征转换成字典数据:
x_train = x_train.to_dict(orient="records")
x_test = x_test.to_dict(orient="records")
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

机器学习—xgboost模型训练:这段代码使用了 XGBoost 框架中的 XGBClassifier 类,用于构建一个基于 XGBoost 算法的分类模型。整个过程实现了一个监督学习的分类算法:
# 4.1初步模型训练
from xgboost import XGBClassifier
xg = XGBClassifier()
xg.fit(x_train, y_train)
XGBoost 以其高效性、准确性和可拓展性等方面的优点而闻名,在很多数据科学任务中都被广泛使用:

这段代码是在对 XGBoost 模型中的 max_depth 参数进行调优。max_depth 参数代表每棵树的最大深度,它控制了树的复杂度,过大的值可能会导致过拟合,而过小的值可能会导致欠拟合。为了找到最佳的 max_depth 值,代码使用了一个循环来尝试不同的深度值,并记录每个深度值对应的模型得分:

最后对所得的数据结果进行一个可视化展示:

lightGBM算法简介
LightGBM 是一种梯度提升框架中的基于决策树的机器学习算法。它是由微软研究院开发的,旨在提供高效、快速和准确的模型训练和预测。其演进过程如下:

AdaBoost算法:AdaBoost是一种提升树的方法,和三个臭皮匠,赛过诸葛亮的道理一样。特点:
改变训练数据的权重或概率分布,提高前一轮被弱分类器错误分类的样本的权重,降低前一轮被分对的权重;
将弱分类器组合成一个强分类,采取”多数表决”的方法.加大分类错误率小的弱分类器的权重,使其作用较大,而减小分类错误率大的弱分类器的权重,使其在表决中起较小的作用。
GBDT算法:GBDT和其它Boosting算法一样,通过将表现一般的几个模型(通常是深度固定的决策树)组合在一起来集成一个表现较好的模型。GradientBoosting通过负梯度来识别问题,通过计算负梯度来改进模型,即通过反复地选择一个指向负梯度方向的函数,该算法可被看做在函数空间里对目标函数进行优化。其缺点如下:
1)空间消耗大:样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这里需要消耗训练数据两倍的内存。
2)时间上也有较大的开销:在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。
3)对内存(cache)优化不友好:在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化;同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。
lightGBM原理:lightGBM主要基于以下方面优化,提升整体特特性:
基于Histogram(直方图)的决策树算法
基本思想是:先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图;在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点:

使用直方图算法有很多优点。首先,最明显就是内存消耗的降低,直方图算法不仅不需要额外存储预排序的结果,而且可以只保存特征离散化后的值,而这个值一般用8位整型存储就足够了,内存消耗可以降低为原来的1/8:

然后在计算上的代价也大幅降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#data#feature)优化到O(k#features)。
Lightgbm的Histogram(直方图)做差加速
一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。利用这个方法,LightGBM可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍:

带深度限制的Leaf-wise的叶子生长策略
Level-wise便利一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。
实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

Leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。
因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

直接支持类别特征
实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化到多维的0/1特征,降低了空间和时间的效率。
而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。
在Expo数据集上的实验,相比0/1展开的方法,训练速度可以加速8倍,并且精度一致。目前来看,LightGBM是第一个直接支持类别特征的GBDT工具。
直接支持高效并行
LightGBM还具有支持高效并行的优点。LightGBM原生支持并行学习,目前支持特征并行和数据并行的两种。
特征并行的主要思想是在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。
数据并行则是让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。
lightGBM算法详细使用:对于lightGBM的使用,这里需要终端执行如下命令进行安装:
pip install lightgbm -i https://pypi.mirrors.ustc.edu.cn/simple
对于lightGBM参数有以下相关内容的介绍:
Control Parameters
| ControlParameters | 含义 | 用法 |
|---|---|---|
| max_depth | 树的最大深度 | 当模型过拟合时,可以考虑首先降低max_depth |
| min_data_in_leaf | 叶子可能具有的最小记录数 | 默认20,过拟合时用 |
| feature_fraction | 例如为0.8时,意味着在每次迭代中随机选择80%的参数来建树 | boosting为random forest时用 |
| bagging_fraction | 每次迭代时用的数据比例 | 用于加快训练速度和减小过拟合 |
| early_stopping_round | 如果一次验证数据的一个度量在最近的early_stopping_round回合中没有提高模型将停止训练 | 加速分析,减少过多迭代 |
| lambda | 指定正则化 | 0~1 |
| min_gain_to_split | 描述分裂的最小 gain | 控制树的有用的分裂 |
| max_cat_group | 在group边界上找到分割点 | 当类别数量很多时,找分割点很容易过拟合时 |
| n_estimators | 最大迭代次数 | 最大迭代数不必设置过大,可以在进行一次迭代后,根据最佳迭代数设置 |
Core Parameters
| Core Parameters | 含义 | 用法 |
|---|---|---|
| Task | 数据的用途 | 选择train或者predict |
| application | 模型的用途 | 选择regression:回归时,binary:二分类时,multiclass:多分类时 |
| boosting | 要用的算法 | gbdt, rf:random forest, dart:DropoutsmeetMultipleAdditiveRegressionTrees, goss: Gradient-based One-Side Sampling |
| num_boost_round | 迭代次数 | 通常100+ |
| learning_rate | 学习率 | 常用0.1,0.001,0.003... |
| num_leaves | 叶子数量 | 默认31 |
| device | cpu 或者 gpu | |
| metric | mae:mean absolute error, mse:mean squared error, binary_logloss:loss for binary classification, multi_logloss:lossformulti classification |
IO parameter
| IO parameter | 含义 |
|---|---|
| max_bin | 表示feature将存入的bin的最大数量 |
| categorical_feature | 如果categorical_features=0,1,2,则列0,1,2是categorical变量 |
| ignore_column | 与categorical_features类似,只不过不是将特定的列视为categorical,而是完全忽略 |
| save_binary | 这个参数为true时,则数据集被保存为二进制文件,下次读数据时速度会变快 |
接下来我们借助鸢尾花数据集对 LightGBM 的进行一个基本使用:
下面这段代码实现了在 iris 数据集上使用 LightGBM 进行回归任务的训练和评估过程。模型在训练过程中会监控验证集的表现,当连续5次迭代模型性能没有提升时,会提前停止训练。最后输出模型在测试集上的准确率:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
from lightgbm import early_stopping# 读取数据
iris = load_iris()
data = iris.data
target = iris.target# 数据基本处理
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)# 模型训练
gbm = lgb.LGBMRegressor(objective="regression", learning_rate=0.05, n_estimators=20, device="gpu") # n_estimators为迭代次数
gbm.fit(x_train, y_train, eval_set=[(x_test, y_test)], eval_metric="l1", callbacks=[early_stopping(5)])# 模型评估
acc = gbm.score(x_test, y_test)
print(f"LightGBM 模型准确率为:{acc*100:.4f}%")
最终呈现的效果如下:

下面这段代码实现了在 iris 数据集上使用 GridSearchCV 进行参数网格搜索调参,并基于最优参数重新训练 LightGBM 回归模型的过程,并输出最优参数下模型在测试集上的准确率。这样可以帮助找到最佳的超参数组合,从而提高模型性能:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
from lightgbm import early_stopping# 读取数据
iris = load_iris()
data = iris.data
target = iris.target# 数据基本处理
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)# 通过网格搜索进行训练
estimators = lgb.LGBMRegressor(num_leaves=31)
param_grid = {"learning_rate": [0.01, 0.1, 1],"n_estimators": [20, 40, 60, 80]
}
gbm = GridSearchCV(estimators, param_grid, cv=5)
# 模型训练
gbm.fit(x_train, y_train)
# 输出模型最优参数
print(f"通过网格搜索,LightGBM回归模型的最优参数为:\r\n{gbm.best_params_}")# 基于最优参数再进行模型训练
gbm = lgb.LGBMRegressor(objective="regression", learning_rate=0.1, n_estimators=40, device="gpu") # n_estimators为迭代次数
gbm.fit(x_train, y_train, eval_set=[(x_test, y_test)], eval_metric="l1", callbacks=[early_stopping(5)])acc = gbm.score(x_test, y_test)
print(f"基于最优参数的 LightGBM 模型准确率为:{acc*100:.4f}%")
最终呈现的结果如下:

《绝地求生》玩家排名预测(实操)
绝地求生(Playerunknown'sBattlegrounds),俗称吃鸡,是一款战术竞技型射击类沙盒游戏。

这款游戏是一款大逃杀类型的游戏,每一局游戏将有最多100名玩家参与,他们将被投放在绝地岛(battlegrounds)上,在游戏的开始时所有人都一无所有。玩家需要在岛上收集各种资源,在不断缩小的安全区域内对抗其他玩家,让自己生存到最后。

本作拥有很高的自由度,玩家可以体验飞机跳伞、开越野车、丛林射击、抢夺战利品等玩法,小心四周埋伏的敌人,尽可能成为最后1个存活的人。该游戏中,玩家需要在游戏地图上收集各种资源,并在不断缩小的安全区域内对抗其他玩家,让自己生存到最后。
本项目提供大量匿名的《PUBG》游戏统计数据。其格式为每行包含一个玩家的游戏后统计数据,列为数据的特征值。
数据来自所有类型的比赛:单排,双排,四排;不保证每场比赛有 100 名玩家,每组最多 4 名玩家。

数据集下载:PUBG Finish Placement Prediction ,登录账号之后,点击rule后接收规则:

然后再点击data数据当中,下载相应的数据集:

数据集当中的字段解释如下:
Id:用户 id
groupId:所处小队 id
matchId:该场比赛 id
assists:助攻数
boosts:使用能量、道具数量
DBNOs:击倒敌人数量
headshotKills:爆头数
heals:使用治疗药品数量
killPlace:本场比赛杀敌排行
killPoints:Elo 杀敌排名
kills:杀敌数
killStreaks:连续杀敌数
longestKill:最远杀敌距离
matchDuration:比赛时长
matchType:比赛类型(小组人数)
maxPlace:本场最差名次
numGroups:小组数量
rankPoints:Elo 排名
revives:救活队友的次数
rideDistance:驾车距离
roadKills:驾车杀敌数
swimDistance:游泳距离
teamKills:杀死队友的次数
vehicleDestorys:毁坏载具的数量
walkDistance:步行距离
weaponsAcquired:手机武器的数量
winPoints:Elo 胜率排名
winPlacePerc:百分比排名 —— 这是一个百分位获胜排名,其中1对应第一名,0对应比赛中最后一名
项目评估方式:你必须创建一个模型,根据他们的最终统计数据预测玩家的排名,从1(第一名)到0(最后一名)。最后结果通过平均绝对误差(MAE)进行评估,即通过预测的winPlacePerc和真实的winPlacePerc之间的平均绝对误差。关于MAE:

项目实现:在接下来的分析中,我们将分析数据集,检测异常值。然后我们通过随机森林模型对其训练,并对对该模型进行了优化。以下是本次案例的具体步骤实现:
获取数据,基本数据查看:
# 导入数据基本处理阶段需要用到的api
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

以下是查看数据进行的一些场景操作:
train.head() # 数据集头部前五行
train.tail() # 数据集尾部前五行
train.describe() # 数据集整体描述
train.info() # 数据集字段信息
train.shape # 数据集整体有多少数据
np.unique(train["matchId"]).shape # 查看一共有多少场比赛
np.unique(train["groupId"]).shape # 查看一共有多少组
下面是这些命令的操作得到的具体数据展现:

数据基本处理:
寻找训练集当中是否存在缺失值:
# 查看缺失值,通过下面方法查看
pd.isnull(train).any()
查看目标值,我们发现有一条样本,比较特殊,其“winplaceperc"的值为NaN,也就是目标值是缺失值。

# 寻找缺失值行
train[train["winPlacePerc"].isnull()]
发现只有这一条数据存在缺失值:

接下来对缺失值进行删除操作:

查看每场比赛参加的人数:处理完缺失值之后,我们看一下每场参加的人数会有多少呢,是每次都会匹配100个人,才开始游戏吗?

# 通过绘制图像,查看每局开始人数
# 通过seaborn下的countplot方法,可以直接绘制统计过数量之后的直方图
plt.figure(figsize=(20, 8))
sns.countplot(train['playersJoined'])
plt.grid()
plt.show()

通过观察,发现一局游戏少于 75 个玩家的情况是很罕见的,大部分游戏都是在 96 人左右的时候才开始。我们限制每局开始人数大于等于 75,再进行绘制:
# 再次绘制每局参加人数的直方图
plt.figure(figsize=(20, 4))
sns.countplot(train['playersJoi
plt.grid()
plt.show()

规范化输出部分数据:现在我们统计了“每局玩家数量”,那么我们就可以通过“每局玩家数量”来进一步考证其它特征,同时对其规范化设置试想:一局只有70个玩家的杀敌数,和一局有100个玩家的杀敌数,应该是不可以同时比较的,可以考虑的特征值包括:(1)kills (杀敌数)(2)damageDealt(总伤害)(3)maxPlace(本局最差名次)(4)matchDuration(比赛时长)
# 对部分特征值进行规范化处理
train["killsNorm"] = train["kills"] * ((100 - train["playersJoined"]) / 100 + 1)
train["damageDealtNorm"] = train["damageDealt"] * ((100 - train["damageDealt"]) / 100 + 1)
train["maxPlaceNorm"] = train["maxPlace"] * ((100 - train["maxPlace"]) / 100 + 1)
train["matchDurationNorm"] = train["matchDuration"] * ((100 - train["matchDuration"]) / 100 + 1)# 比较经过规范化的特征值和原始特征值的值
to_show = ['Id', 'kills', 'killsNorm', 'damageDealt', 'damageDealtNorm', 'maxPlace', 'maxPlaceNorm', 'matchDuration', "matchDurationNorm"]train[to_show][0:11]
呈现的结果如下所示:

部分变量合成:此处我们把特征:heals(使用治疗药品数量)和boosts(能量、道具使用数量)合并成一个新的变量,命名:"healsandboosts",这是一个探索性过程,最后结果不一定有用,如果没有实际用处,最后再把它删除。

异常值处理: 一些行中的数据统计出来的结果非常反常规,那么这些玩家肯定有问题,为了训练模型的准确性,我们会把这些异常数据剔除
删除有击杀,但是完全没有移动的玩家:这类型玩家肯定是存在异常情况(挂**),我们把这些玩家删除。通过以下操作,识别出玩家在游戏中有击杀数,但是全局没有移动:
下面代码首先使用布尔索引来选择 train 中所有被标记为作弊者的行。然后再使用 drop 方法来删除这些行,并使用 inplace=True 参数来指定在原地修改 DataFrame 对象。

删除驾车杀敌数异常的数据:

删除一局中杀敌数超过30人的玩家数据:
# 首先绘制玩家杀敌数的统计图
plt.figure(figsize=(10, 4), dpi=200)
sns.countplot(x=train["kills"])
plt.ylabel("达到的玩家人数")
plt.xlabel("击杀数")
plt.show()

# 再删除一局中杀敌数超过 30 人的玩家数据
train.drop(train[train["kills"] > 30].index, inplace=True)
删除爆头率异常数据:
# 创建爆头率变量
train["headshot_rate"] = train["headshotKills"] / train["kills"]# 对于那些没有击杀记录的玩家,他们的爆头率将被设置为 0
train["headshot_rate"] = train["headshot_rate"].fillna(0)# 绘制爆头率统计图
plt.figure(dpi=300)
sns.displot(train["headshot_rate"], bins=10, kde=False)
plt.ylabel("达到的玩家人数")
plt.xlabel("爆头率∈[0,1]")
plt.show()

# 删除爆头率异常的数据(爆头率 = 1 且击杀 > 9)
train.drop(train[(train["headshot_rate"] == 1) & (train["kills"] > 9)].index, inplace=True)
删除最远杀敌距离异常数据:
# 绘制远距离杀敌直方图
plt.figure(dpi=300)
sns.displot(train["longestKill"], bins=10, kde=False)
plt.ylabel("达到的玩家人数")
plt.xlabel("远距离杀敌数")
plt.show()

# 删除杀敌距离 ≥ 1km 的玩家
train.drop(train[train["longestKill"] >= 1000].index, inplace=True)
删除关于运动距离的异常值:
# 距离整体描述
train[["walkDistance", "rideDistance", "swimDistance", "totalDistance"]].describe()

# a. 删除行走距离异常的数据
train.drop(train[train["walkDistance"] >= 10000].index, inplace=True)# b. 删除载具行驶距离异常的数据
train.drop(train[train["rideDistance"] >= 20000].index, inplace=True)# c. 删除游泳距离异常的数据
train.drop(train[train["swimDistance"] >= 20000].index, inplace=True)
武器收集异常值处理:
# 绘制武器收集直方图
plt.figure(dpi=300)
sns.displot(train["weaponsAcquired"], bins=10, kde=False)
plt.ylabel("达到的玩家人数")
plt.xlabel("武器收集数量")
plt.show()

# 删除武器收集异常的数据
train.drop(train[train["weaponsAcquired"] >= 80].index, inplace=True)
删除使用治疗药品数量异常值:
# 绘制使用治疗药品数量直方图
plt.figure(figsize=(20, 10), dpi=300)
sns.displot(train["heals"], bins=10, kde=False)
plt.ylabel("达到的玩家人数")
plt.xlabel("使用治疗药品数量")
plt.savefig("./data/snsdisplot.png", dpi=300)
plt.show()


类别型数据处理:
对比赛类型 one-hot 处理:

对 groupId,matchId 等数据进行处理:

数据截取:

确定特征值和目标值:

分割训练集和测试集:

机器学习(模型训练)和评估:
初步使用随机森林进行模型训练:

再次使用随机森林,进行模型训练:





使用 LightGBM 对模型进行训练:

模型初次尝试结果如下:


模型二次调优:
from sklearn.model_selection import GridSearchCV# 定义模型
model = lgbm.LGBMRegressor(num_leaves=31, device="gpu")
param_grid_lst = {"learning_rate": [0.01, 0.05, 0.1, 0.15, 0.2], "n_estimators": [20, 50, 100, 200, 300, 500]}model = GridSearchCV(estimator=model, param_grid=param_grid_lst, cv=5, n_jobs=-1, verbose=2)
model.fit(x_train, y_train)
得到如下结果,过程相当耗费时间:
Fitting 5 folds for each of 30 candidates, totalling 150 fits
GridSearchCV(cv=5, estimator=LGBMRegressor(device='gpu'), n_jobs=-1,
param_grid={'learning_rate': [0.01, 0.05, 0.1, 0.15, 0.2],
'n_estimators': [20, 50, 100, 200, 300, 500]},
verbose=2)
# 最优模型预测
y_pred = model.predict(x_test)
acc = model.score(x_test, y_test)
loss = mean_absolute_error(y_test, y_pred)
print(f"LGBMRegressor 网格交叉搜索最优模型准确率为:{acc*100:.4f}%")
print(f"LGBMRegressor 网格交叉搜索最优模型损失为:{loss:.4f}")# LGBMRegressor 网格交叉搜索最优模型准确率为:93.5980%
# LGBMRegressor 网格交叉搜索最优模型损失为:0.0553
# 查看网格搜索/交叉验证的结果
print("Best parameters:", model.best_params_)
print("Best score:", model.best_score_)
print("Best estimator:", model.best_estimator_)
print("CV results:", model.cv_results_)# 结果如下
Best parameters: {'learning_rate': 0.15, 'n_estimators': 500}Best score: 0.9359144823173906Best estimator: LGBMRegressor(device='gpu', learning_rate=0.15, n_estimators=500)CV results: {'mean_fit_time': array([14.34503574, 20.01631103, 25.97441425, 43.4136445 , 60.82093949,89.25930433, 11.62595191, 16.23543158, 25.54000373, 36.26000762,49.61888871, 66.26681533, 11.1753377 , 15.24283795, 20.54040017,30.36953435, 41.37112398, 52.48080788, 11.32525654, 16.418437 ,19.51573868, 29.89882855, 37.1528873 , 48.23137908, 10.68091936,13.80297165, 19.0142149 , 26.71594262, 33.4341989 , 34.97594118]), 'std_fit_time': array([0.89452845, 0.69153922, 1.30721953, 0.59971748, 1.47560355,1.69149272, 0.38846451, 0.26956315, 0.66550434, 0.40090513,0.64625266, 0.58125147, 0.81862829, 0.39151642, 0.25658152,1.89966286, 1.02374619, 2.16053993, 0.59936112, 1.262003 ,1.13085383, 1.16485342, 0.86350695, 0.98988553, 0.4670428 ,0.35239315, 0.6680641 , 0.72602143, 0.32089537, 3.72148617]), 'mean_score_time': array([1.5022016 , 1.42152162, 2.12359066, 4.06432238, 5.19431663,8.55703535, 1.32677093, 2.00913296, 2.52904983, 4.60726891,6.05252767, 9.39462171, 1.47626009, 1.72542372, 2.56810923,4.31121016, 6.6386538 , 9.39059463, 1.7088644 , 2.02408352,2.97478876, 4.52777481, 5.31689487, 7.65328541, 1.4070025 ,1.96806068, 2.37317958, 3.95138211, 4.22260122, 4.59180803]), 'std_score_time': array([0.26366997, 0.10020396, 0.14991592, 0.1966688 , 0.1009084 ,0.25914634, 0.12654092, 0.30676004, 0.37853699, 0.23382102,0.23462405, 0.40300067, 0.06112725, 0.07371341, 0.09753172,0.1741567 , 0.7262754 , 1.32623107, 0.21834994, 0.25155977,0.23926274, 0.52417874, 0.21302958, 0.12573272, 0.12746464,0.20380246, 0.0958619 , 0.18764002, 0.30194442, 0.14234936]), 'param_learning_rate': masked_array(data=[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.05, 0.05, 0.05,0.05, 0.05, 0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.15,0.15, 0.15, 0.15, 0.15, 0.15, 0.2, 0.2, 0.2, 0.2, 0.2,0.2],mask=[False, False, False, False, False, False, False, False,False, False, False, False, False, False, False, False,False, False, False, False, False, False, False, False,False, False, False, False, False, False],fill_value='?',dtype=object), 'param_n_estimators': masked_array(data=[20, 50, 100, 200, 300, 500, 20, 50, 100, 200, 300, 500,20, 50, 100, 200, 300, 500, 20, 50, 100, 200, 300, 500,20, 50, 100, 200, 300, 500],mask=[False, False, False, False, False, False, False, False,False, False, False, False, False, False, False, False,False, False, False, False, False, False, False, False,False, False, False, False, False, False],fill_value='?',dtype=object), 'params': [{'learning_rate': 0.01, 'n_estimators': 20}, {'learning_rate': 0.01, 'n_estimators': 50}, {'learning_rate': 0.01, 'n_estimators': 100}, {'learning_rate': 0.01, 'n_estimators': 200}, {'learning_rate': 0.01, 'n_estimators': 300}, {'learning_rate': 0.01, 'n_estimators': 500}, {'learning_rate': 0.05, 'n_estimators': 20}, {'learning_rate': 0.05, 'n_estimators': 50}, {'learning_rate': 0.05, 'n_estimators': 100}, {'learning_rate': 0.05, 'n_estimators': 200}, {'learning_rate': 0.05, 'n_estimators': 300}, {'learning_rate': 0.05, 'n_estimators': 500}, {'learning_rate': 0.1, 'n_estimators': 20}, {'learning_rate': 0.1, 'n_estimators': 50}, {'learning_rate': 0.1, 'n_estimators': 100}, {'learning_rate': 0.1, 'n_estimators': 200}, {'learning_rate': 0.1, 'n_estimators': 300}, {'learning_rate': 0.1, 'n_estimators': 500}, {'learning_rate': 0.15, 'n_estimators': 20}, {'learning_rate': 0.15, 'n_estimators': 50}, {'learning_rate': 0.15, 'n_estimators': 100}, {'learning_rate': 0.15, 'n_estimators': 200}, {'learning_rate': 0.15, 'n_estimators': 300}, {'learning_rate': 0.15, 'n_estimators': 500}, {'learning_rate': 0.2, 'n_estimators': 20}, {'learning_rate': 0.2, 'n_estimators': 50}, {'learning_rate': 0.2, 'n_estimators': 100}, {'learning_rate': 0.2, 'n_estimators': 200}, {'learning_rate': 0.2, 'n_estimators': 300}, {'learning_rate': 0.2, 'n_estimators': 500}], 'split0_test_score': array([0.28454907, 0.54923917, 0.76022635, 0.88293465, 0.91060857,0.9244634 , 0.76505124, 0.90190306, 0.92444864, 0.93187006,0.93394925, 0.93529471, 0.88553821, 0.92402019, 0.93150503,0.93446068, 0.9352919 , 0.93604723, 0.91159903, 0.92893752,0.93328694, 0.93504886, 0.93565664, 0.93623854, 0.91960025,0.93077007, 0.93357905, 0.93492508, 0.93552697, 0.93608738]), 'split1_test_score': array([0.28436306, 0.54875665, 0.75954484, 0.88222918, 0.91018844,0.92418283, 0.76438739, 0.90153518, 0.92425756, 0.9319695 ,0.934071 , 0.93554092, 0.8849283 , 0.92402688, 0.93171493,0.93470062, 0.93560521, 0.93640918, 0.91033221, 0.92893088,0.93318294, 0.93526183, 0.9358338 , 0.93635082, 0.91873591,0.93101601, 0.93364595, 0.93507168, 0.93551916, 0.93595913]), 'split2_test_score': array([0.2843355 , 0.54855371, 0.75959117, 0.88183133, 0.91004533,0.92409252, 0.764491 , 0.90155836, 0.92413334, 0.93163902,0.93377787, 0.93513166, 0.88560984, 0.92399051, 0.93142455,0.93422112, 0.93510549, 0.93571943, 0.91129593, 0.92855244,0.93301829, 0.93474559, 0.93526989, 0.93578894, 0.91839872,0.93037481, 0.93342368, 0.93463735, 0.93512018, 0.93561078]), 'split3_test_score': array([0.28416371, 0.54822298, 0.75871174, 0.88129364, 0.90952787,0.923619 , 0.76384192, 0.90058734, 0.92375681, 0.93143612,0.93350314, 0.93487847, 0.88453036, 0.92307768, 0.93082085,0.93394062, 0.9348608 , 0.93564594, 0.90959224, 0.92776206,0.9324688 , 0.93431994, 0.93499641, 0.93558379, 0.91865493,0.93035951, 0.93341205, 0.93466532, 0.93519394, 0.93567325]), 'split4_test_score': array([0.28496283, 0.54958736, 0.76029536, 0.8823003 , 0.91004134,0.92396112, 0.76498543, 0.90173034, 0.92393124, 0.93143822,0.93352341, 0.93492248, 0.88570397, 0.92331548, 0.9307633 ,0.93378324, 0.93464401, 0.93540764, 0.91073014, 0.92823403,0.93259306, 0.93435349, 0.93502704, 0.93561031, 0.91849981,0.93000466, 0.93288866, 0.93428614, 0.93477511, 0.93522242]), 'mean_test_score': array([0.28447483, 0.54887197, 0.75967389, 0.88211782, 0.91008231,0.92406378, 0.7645514 , 0.90146286, 0.92410552, 0.93167058,0.93376493, 0.93515365, 0.88526213, 0.92368615, 0.93124573,0.93422126, 0.93510148, 0.93584588, 0.91070991, 0.92848339,0.93291001, 0.93474594, 0.93535676, 0.93591448, 0.91877793,0.93050501, 0.93338988, 0.93471711, 0.93522707, 0.93571059]), 'std_test_score': array([0.00027289, 0.00048629, 0.00057283, 0.000543 , 0.00034602,0.00027679, 0.00044094, 0.00045743, 0.00024232, 0.00021868,0.00022569, 0.00024475, 0.00045591, 0.00040693, 0.00038279,0.00033398, 0.00033383, 0.0003481 , 0.0007108 , 0.00044581,0.00032355, 0.0003724 , 0.00033574, 0.00032033, 0.00042761,0.0003521 , 0.00026616, 0.00026972, 0.00028002, 0.00030113]), 'rank_test_score': array([30, 29, 28, 26, 23, 19, 27, 24, 18, 14, 11, 6, 25, 20, 15, 10, 7,2, 22, 17, 13, 8, 4, 1, 21, 16, 12, 9, 5, 3])}
模型三次调优:
acc_lst = []
loss_lst = []
n_estimators_lst = [50, 100, 300, 500, 1000]for n in n_estimators_lst:lgbmr = lgbm.LGBMRegressor(boosting_type="gbdt", num_leaves=31,max_depth=5, learning_rate=0.1,n_estimators=n, min_child_samples=20, n_jobs=-1, device="gpu")lgbmr.fit(x_train, y_train, eval_set=[(x_test, y_test)], eval_metric="l1", callbacks=[early_stopping(5)])y_pred = lgbmr.predict(x_test)acc = lgbmr.score(x_test, y_test)loss = mean_absolute_error(y_test, y_pred)acc_lst.append(acc)loss_lst.append(loss)print(f"[n_estimators = {n}] LGBMRegressor 模型准确率为:{acc*100:.4f}%")print(f"[n_estimators = {n}] LGBMRegressor 模型损失为:{loss:.4f}\r\n")


接下来可以调整 max_depth 参数:
acc_lst = []
loss_lst = []
max_depth_lst = [1, 3, 5, 7, 9, 11]for n in max_depth_lst:lgbmr = lgbm.LGBMRegressor(boosting_type="gbdt", num_leaves=31,max_depth=n, learning_rate=0.1,n_estimators=1000, min_child_samples=20, n_jobs=-1, device="gpu")lgbmr.fit(x_train, y_train, eval_set=[(x_test, y_test)], eval_metric="l1", callbacks=[early_stopping(5)])y_pred = lgbmr.predict(x_test)acc = lgbmr.score(x_test, y_test)loss = mean_absolute_error(y_test, y_pred)acc_lst.append(acc)loss_lst.append(loss)print(f"[max_depth = {n}] LGBMRegressor 模型准确率为:{acc*100:.4f}%")print(f"[max_depth = {n}] LGBMRegressor 模型损失为:{loss:.4f}\r\n")# 绘图展示结果
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4), dpi=200)acc_lst_percent = [i * 100 for i in acc_lst]
axes[0].scatter(max_depth_lst, acc_lst_percent, color='red', zorder=10)
axes[0].plot(max_depth_lst, acc_lst_percent)
axes[0].set_xlabel("max_depth")
axes[0].set_ylabel("准确率")axes[1].scatter(max_depth_lst, loss_lst, color='red', zorder=10)
axes[1].plot(max_depth_lst, loss_lst)
axes[1].set_xlabel("max_depth")
axes[1].set_ylabel("Loss")
plt.show()print(f"最优 max_depth 为:{max_depth_lst[np.argmin(loss_lst)]}")

最佳模型性能如下:
best_model = lgbm.LGBMRegressor(boosting_type="gbdt", num_leaves=31,max_depth=7, learning_rate=0.10, n_estimators=1000, min_child_samples=20, n_jobs=-1, device="gpu")
best_model.fit(x_train, y_train, eval_set=[(x_test, y_test)], eval_metric="l1", callbacks=[early_stopping(5)])
y_pred = best_model.predict(x_test)
acc = best_model.score(x_test, y_test)
loss = mean_absolute_error(y_test, y_pred)
acc_lst.append(acc)
loss_lst.append(loss)
print(f"LGBMRegressor 最佳模型准确率为:{acc*100:.4f}%")
print(f"LGBMRegressor 最佳模型损失为:{loss:.4f}\r\n")# 结果如下
Training until validation scores don't improve for 5 rounds
Early stopping, best iteration is:
[729] valid_0's l1: 0.0550691 valid_0's l2: 0.00599729
LGBMRegressor 最佳模型准确率为:93.6428%
LGBMRegressor 最佳模型损失为:0.0551
模型调优两种方式对比:在上面的代码中,我们在循环中对不同的参数进行了调优。在每次循环中,您都使用了一个不同的单一参数值来训练一个 LGBMRegressor 模型,并计算了模型的准确率和损失。
这种方法比使用 GridSearchCV 快,是因为我们只调整了一个参数,而且只尝试了 有限个 个不同的值。相比之下,GridSearchCV 会对多个参数进行调优,并且会尝试每个参数的所有可能值。因此,使用 GridSearchCV 需要更多的计算。
但是,我们需要注意的是,这种方法只能调整一个参数,而且只能尝试有限个值。如果我们想要同时调整多个参数,并且尝试更多的值,那么使用 GridSearchCV 或其他自动调参方法可能会更方便。
algorithm_names = ["RandomForestRegressor", "[重新划分数据集后] RandomForestRegressor", "LGBMRegressor", "[GridSearchCV] LGBMRegressor", "[手动调参] LGBMRegressor"]
x_label = [f"算法{i}" for i in range(1, len(algorithm_names) + 1)]
accs = [91.9824, 92.3205, 92.4044, 93.5980, 93.6428]
losses = [0.0618, 0.0601, 0.0607, 0.0553, 0.0551]fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6), dpi=200)
for x, y, label in zip(x_label, accs, algorithm_names):axes[0].scatter(x, y, zorder=10, label=label)
axes[0].plot(x_label, accs)
axes[0].set_xlabel("learning_rate")
axes[0].set_ylabel("Accuracy")
axes[0].set_title("不同算法准确率对比")
axes[0].legend()for x, y, label in zip(x_label, losses, algorithm_names):axes[1].scatter(x, y, zorder=10, label=label)
axes[1].plot(x_label, losses)
axes[1].set_xlabel("learning_rate")
axes[1].set_ylabel("Loss")
axes[1].set_title("不同算法损失对比")
axes[1].legend()
plt.show()

相关文章:
机器学习 | 深入集成学习的精髓及实战技巧挑战
目录 xgboost算法简介 泰坦尼克号乘客生存预测(实操) lightGBM算法简介 《绝地求生》玩家排名预测(实操) xgboost算法简介 XGBoost全名叫极端梯度提升树,XGBoost是集成学习方法的王牌,在Kaggle数据挖掘比赛中,大部分获胜者用了XGBoost。…...
SNMP(简单网络管理协议)介绍
简介 作为系统管理员的重要工作之一是收集关于服务器和基础设施的准确信息。有许多工具和选项可用于收集和处理这种类型的信息。其中许多工具都是建立在一种称为SNMP的技术之上。 SNMP代表简单网络管理协议。这是服务器可以共享有关其当前状态的信息的一种方式,也…...
Spring中常见的设计模式
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性、更具有灵活、优雅,而Spring中共有九种常见的设计模式 工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于…...
【MySQL】——数值函数的学习
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Z1fAnfrxGD7I5gqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…...
LLMs模型选择,LLMs复读机问题,LLMs长文本处理方案
为什么会出现 LLMs 复读机问题? LLMs 复读机问题(LLMs Parroting Problem)是指大型语言模型(LLMs)在生成文本时可能出现的重复或重复先前输入内容的现象。出现LLMs复读机问题可能有以下几个原因: 数据偏差…...
LeetCode.144. 二叉树的前序遍历
题目 144. 二叉树的前序遍历 分析 这道题目是比较基础的题目,我们首先要知道二叉树的前序遍历是什么? 就是【根 左 右】 的顺序,然后利用递归的思想,就可以得到这道题的答案,任何的递归都可以采用 栈 的结构来实现…...
Redis复制
文章目录 1.Redis复制是什么2.Redis能干嘛3.权限细节4.基本操作命令5.常用三招5.1 一主二仆5.2 薪火相传5.3 反客为主 6.复制原理和工作流程7.复制的缺点 1.Redis复制是什么 就是主从复制,master以写为主,Slave以读为主。当master数据变化的时候&#x…...
C++入门学习(二十七)跳转语句—break语句
1、与switch语句联合使用 C入门学习(二十三)选择结构-switch语句-CSDN博客 #include <iostream> #include <string> using namespace std;int main() { int number;cout<<"请为《斗萝大路》打星(1~5※):" &…...
Spark安装(Yarn模式)
一、解压 链接:https://pan.baidu.com/s/1O8u1SEuLOQv2Yietea_Uxg 提取码:mb4h tar -zxvf /opt/software/spark-3.0.3-bin-hadoop3.2.tgz -C /opt/module/spark-yarn mv spark-3.0.3-bin-hadoop3.2/ spark-yarn 二、配置环境变量 vim /etc/profile…...
1.4 Binance_interface API U本位合约行情
Binance_interface API U本位合约行情 Github地址PyTed量化交易研究院 1. API U本位合约行情接口总览 方法解释Pathget_ping测试服务器连通性 PING/fapi/v1/pingget_time获取服务器时间/fapi/v1/timeget_exchangeInfo获取交易规则和交易对/fapi/v1/exchangeInfoget_depth深度…...
单片机学习笔记---AT24C02(I2C总线)
目录 有关储存器的介绍 存储器的简介 存储器简化模型 AT24C02介绍 AT24C02引脚及应用电路 I2C总线介绍 I2C电路规范 开漏输出模式和弱上拉模式 其中一个设备的内部结构 I2C通信是怎么实现的 I2C时序结构 起始条件和终止条件 发送一个字节 接收一个字节 发送应答…...
c++恶魔轮盘制造第1期输赢
小常识,恶魔叫DEALER。 赢了很简单 void sheng() { cout<<"你获胜了!";MessageBox(NULL,TEXT("你的钱~~~~~~给你"),TEXT("DEALER"),MB_OK);system("pause");system("cls"); } 输了我用了个选…...
60-JS-Ajax
ajax取数据的一种手段,局部刷新,例如弹幕 1.ajax的使用,创建ajax对象,发起对服务器请求 2.核心对象XMLHttpRequest对象(简称XHR) CSS:Cascading Style Sheets(层叠样式表) HTML:Hypertext Markup Language(超文本标记语言) 3.发起对服务器的请求 浏览器方式请求:打…...
C# Avalonia 折线图
线图开发在C# Avalonia框架中可以通过多种方式实现。由于Avalonia旨在成为跨平台的UI框架,您可以利用多种库和方法来绘制折线图。以下是一个简单的例子,展示了如何在Avalonia应用程序中创建一个基本的折线图。 首先,您需要在Avalonia项目中包…...
Vue3中Setup概述和使用(三)
一、引入Setup 1、Person.Vue 与Vue3编写简单的App组件(二) 中的区别是:取消data、methods等方法,而是将数据和方法定义全部放进setup中。 <template><div class"person"><h1>姓名:{{name}}</h1><h1>年龄:{{age}}</h…...
hexo 博客搭建以及踩雷总结
搭建时的坑 文章置顶 安装一下这个依赖 npm install hexo-generator-topindex --save然后再文章的上面设置 top: number,数字越大,权重越大,也就是越靠顶部 hexo 每次推送 nginx 都访问不到 宝塔自带的 nginx 的 config 里默认的角色是 …...
WordPress后台编辑个人资料页面直接修改用户名插件Change Username
前面跟大家介绍了『如何修改WordPress后台管理员用户名?推荐2种简单方法』一文,但是对于新站长或者有很多用户的站长来说,操作有点复杂,所以今天向大家推荐一款可以直接在WordPress后台编辑个人(用户)资料页…...
ssm+vue的医药垃圾分类管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。
演示视频: ssmvue的医药垃圾分类管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结…...
LLM大模型基本概念,及其相关问题汇总(1)
什么是涌现?为什么会出现涌现? "大模型的涌现能力"这个概念可能是指大型神经网络模型在某些任务上表现出的出乎意料的能力,超出了人们的预期。出现的原因从结论上来看,是模型不够好,导致的原因主要是&#…...
【已解决】pt文件转onnx后再转rknn时得到推理图片出现大量锚框变花屏
前言 环境介绍: 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx,再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn,rknn模型能正常转换,…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
机器学习复习3--模型评估
误差与过拟合 我们将学习器对样本的实际预测结果与样本的真实值之间的差异称为:误差(error)。 误差定义: ①在训练集上的误差称为训练误差(training error)或经验误差(empirical error&#x…...



