当前位置: 首页 > news >正文

机器学习 | 深入集成学习的精髓及实战技巧挑战

目录

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
devicecpu 或者 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入门学习&#xff08;二十三&#xff09;选择结构-switch语句-CSDN博客 #include <iostream> #include <string> using namespace std;int main() { int number;cout<<"请为《斗萝大路》打星(1~5※)&#xff1a;" &…...

Spark安装(Yarn模式)

一、解压 链接&#xff1a;https://pan.baidu.com/s/1O8u1SEuLOQv2Yietea_Uxg 提取码&#xff1a;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期输赢

小常识&#xff0c;恶魔叫DEALER。 赢了很简单 void sheng() { cout<<"你获胜了&#xff01;";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框架&#xff0c;您可以利用多种库和方法来绘制折线图。以下是一个简单的例子&#xff0c;展示了如何在Avalonia应用程序中创建一个基本的折线图。 首先&#xff0c;您需要在Avalonia项目中包…...

Vue3中Setup概述和使用(三)

一、引入Setup 1、Person.Vue 与Vue3编写简单的App组件(二) 中的区别是&#xff1a;取消data、methods等方法,而是将数据和方法定义全部放进setup中。 <template><div class"person"><h1>姓名:{{name}}</h1><h1>年龄:{{age}}</h…...

hexo 博客搭建以及踩雷总结

搭建时的坑 文章置顶 安装一下这个依赖 npm install hexo-generator-topindex --save然后再文章的上面设置 top: number&#xff0c;数字越大&#xff0c;权重越大&#xff0c;也就是越靠顶部 hexo 每次推送 nginx 都访问不到 宝塔自带的 nginx 的 config 里默认的角色是 …...

WordPress后台编辑个人资料页面直接修改用户名插件Change Username

前面跟大家介绍了『如何修改WordPress后台管理员用户名&#xff1f;推荐2种简单方法』一文&#xff0c;但是对于新站长或者有很多用户的站长来说&#xff0c;操作有点复杂&#xff0c;所以今天向大家推荐一款可以直接在WordPress后台编辑个人&#xff08;用户&#xff09;资料页…...

ssm+vue的医药垃圾分类管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的医药垃圾分类管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…...

LLM大模型基本概念,及其相关问题汇总(1)

什么是涌现&#xff1f;为什么会出现涌现&#xff1f; "大模型的涌现能力"这个概念可能是指大型神经网络模型在某些任务上表现出的出乎意料的能力&#xff0c;超出了人们的预期。出现的原因从结论上来看&#xff0c;是模型不够好&#xff0c;导致的原因主要是&#…...

【已解决】pt文件转onnx后再转rknn时得到推理图片出现大量锚框变花屏

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn&#xff0c;rknn模型能正常转换&#xff0c;…...

DevOps文章之 操作手册用户使用说明书

前言 最近主导了几个项目操作手册的编写。有新开发的项目&#xff0c;要重新编写操作手册&#xff1b;有中途接手别的项目&#xff0c;后来功能迭代&#xff0c;需要更新原操作手册&#xff1b;有客户对操作手册有意见&#xff0c;需要调整&#xff1b;零零散散写了数万字的手…...

【RT-DETR进阶实战】利用RT-DETR进行视频划定区域目标统计计数

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 Hello,各位读者,最近会给大家发一些进阶实战的讲解,如何利用RT-DETR现有的一些功能进行一些实战, 让我们不仅会改进RT-DETR,也能够利用RT-DETR去做一些简单的小工作,后面我也会将这些功能利用PyQt或者是…...

2.11学习总结

有效点对https://www.acwing.com/problem/content/description/5472/ 给定一个 n&#xfffd; 个节点的无向树&#xff0c;节点编号 1∼n1∼&#xfffd;。 树上有两个不同的特殊点 x,y&#xfffd;,&#xfffd;&#xff0c;对于树中的每一个点对 (u,v)(u≠v)(&#xfffd;,…...

以谷歌浏览器为例 讲述 JavaScript 断点调试操作用法

今天来说个比较实用的东西 用浏览器开发者工具 对 javaScript代码进行调试 我们先创建一个index.html 编写代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&…...

Vue前端框架--Vue工程项目问题总结{脚手架 Vue-cli}

Vue脚手架部署问题总结 我所遇到的一共两大问题 只有先执行npm install之后 才能run serve 否则会报错 vue-cli-serve不是内部或者外部的命令&#xff0c;也不是可运行的程序或者批处理文件的错误 1. 运行npm install会报错 2. 运行npm run serve报错 nodejs官网为 https://no…...

Unity2D 学习笔记 0.Unity需要记住的常用知识

Unity2D 学习笔记 0.Unity需要记住的常用知识 前言调整Project SettingTilemap相关&#xff08;创建地图块&#xff09;C#脚本相关程序运行函数private void Awake()void Start()void Update() Collider2D碰撞检测private void OnTriggerStay2D(Collider2D player)private void…...

vue3-应用规模化-单文件组件

单文件组件概念 Vue 的单文件组件 (即 *.vue 文件&#xff0c;英文 Single-File Component&#xff0c;简称 SFC) 是一种特殊的文件格式&#xff0c;使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中。下面是一个单文件组件的示例&#xff1a; <script setup…...

Redis -- 渐进式遍历

家&#xff0c;是心的方向。不论走多远&#xff0c;总有一盏灯为你留着。桌上的碗筷多了几双&#xff0c;笑声也多了几分温暖。家人团聚&#xff0c;是最美的风景线。时间&#xff1a;2024年 2月 8日 12:51:20 目录 前言 语法 示例 前言 试想一个场景,那就是在key非常多的…...

使用 C++23 从零实现 RISC-V 模拟器(3):指令解析

指令解析 这章内容进一解析更多的指令&#xff0c;此外将解析指令的过程拆分为一个单独的类&#xff0c;采用表格驱动的方式&#xff0c;将数据和逻辑分离&#xff0c;降低了 if else 嵌套层数过多。 这部分依旧改动不多&#xff0c;只增加了七个指令。此外代码中细碎的变动没…...

CSS Selector—选择方法,和html自动——异步社区的爬取(动态网页)——爬虫(get和post的区别)

这里先说一下GET请求和POST请求&#xff1a; post我们平时是要加data的也就是信息&#xff0c;你会发现我们平时百度之类的 搜索都是post请求 get我们带的是params&#xff0c;是发送我们指定的内容。 要注意是get和post请求&#xff01;&#xff01;&#xff01; 先说一下异…...

C语言 服务器编程-日志系统

日志系统的实现 引言最简单的日志类 demo按天日志分类和超行日志分类日志信息分级同步和异步两种写入方式 引言 日志系统是通过文件来记录项目的 调试信息&#xff0c;运行状态&#xff0c;访问记录&#xff0c;产生的警告和错误的一个系统&#xff0c;是项目中非常重要的一部…...

HarmonyOS 状态管理装饰器 Observed与ObjectLink 处理嵌套对象/对象数组 结构双向绑定

本文 我们还是来说 两个 harmonyos 状态管理的装饰器 Observed与ObjectLink 他们是用于 嵌套对象 或者 以对象类型为数组元素 的数据结构 做双向同步的 之前 我们说过的 state和link 都无法捕捉到 这两种数据内部结构的变化 这里 我们模拟一个类数据结构 class Person{name:…...

windows中的apache改成手动启动的操作步骤

使用cmd解决安装之后开机自启的问题 services.msc 0. 这个命令是打开本地服务找到apache的服务名称 2 .通过服务名称去查看服务的状态 sc query apacheapache3.附加上关掉和启动的命令&#xff08;换成是你的服务名称&#xff09; 关掉命令 sc stop apacheapache启动命令 …...

Intellij Idea的数据库工具 DataGrip

DataGrip DataGrip&#xff1a; IDEA自带&#xff0c;非常好用。智能提示很强大&#xff0c;快捷键跟IDEA自身一致。 如果下载不了 DataGrip&#xff0c;也可以直接用 IDEA 自带的。 常用的快捷键 alt8&#xff1a; 打开数据库Service ctrlshiftF10&#xff1a;打开常用的数…...

精品springboot疫苗发布和接种预约系统

《[含文档PPT源码等]精品基于springboot疫苗发布和接种预约系统[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#xff1a;…...

Linux快速入门

一. Linux的结构目录 1.1 Linux的目录结构 Linux为免费开源的系统&#xff0c;拥有众多发行版&#xff0c;为规范诸多的使用者对Linux系统目录的使用&#xff0c;Linux基金会发布了FHS标准&#xff08;文件系统层次化标准&#xff09;。多数的Linux发行版都遵循这一规范。 注&…...

【图形图像的C++ 实现 01/20】 2D 和 3D 贝塞尔曲线

目录 一、说明二、贝塞尔曲线特征三、模拟四、全部代码如下​五、资源和下载 一、说明 以下文章介绍了用 C 计算和绘制的贝塞尔曲线&#xff08;2D 和 3D&#xff09;。    贝塞尔曲线具有出色的数学能力来计算路径&#xff08;从起点到目的地点的曲线&#xff09;。曲线的形…...

python+flask+django医院预约挂号病历分时段管理系统snsj0

技术栈 后端&#xff1a;python 前端&#xff1a;vue.jselementui 框架&#xff1a;django/flask Python版本&#xff1a;python3.7 数据库&#xff1a;mysql5.7 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm . 第一&#xff0c;研究分析python技术&#xff0c…...

《CSS 简易速速上手小册》第9章:CSS 最佳实践(2024 最新版)

文章目录 9.1 维护大型项目的 CSS9.1.1 基础知识9.1.2 重点案例&#xff1a;构建一个可复用的 UI 组件库9.1.3 拓展案例 1&#xff1a;优化现有项目的 CSS 结构9.1.4 拓展案例 2&#xff1a;实现主题切换功能 9.2 BEM、OOCSS 和 SMACSS 方法论9.2.1 基础知识9.2.2 重点案例&…...

Qt QVariant类应用

QVariant类 QVariant类本质为C联合(Union)数据类型&#xff0c;它可以保存很多Qt类型的值&#xff0c;包括 QBrush&#xff0c;QColor&#xff0c;QString等等&#xff0c;也能存放Qt的容器类型的值。 QVariant::StringList 是 Qt 定义的一个 QVariant::type 枚举类型的变量&…...

不到1s生成mesh! 高效文生3D框架AToM

论文题目&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 论文链接&#xff1a; https://arxiv.org/abs/2402.00867 项目主页&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 随着AIGC的爆火&#xff0c;生成式人工智能在3D领域也实现了非常显著…...

Mac中管理多版本Jdk

1. 首先下载JDK&#xff0c;以jdk8和17为例 2. 打开.zprofile中添加如下内容 #java config export JAVA_8_HOME/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home export JAVA_17_HOME/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home#default java …...

用C语言列出Linux或Unix上的网络适配器

上代码&#xff1a; 1. #include <sys/socket.h> 2. #include <stdio.h> 3. 4. #include <netdb.h> 5. #include <ifaddrs.h> 6. 7. int main() { 8. struct ifaddrs *addresses; 9. if(getifaddrs(&addresses) -1) { 10. printf("…...

单片机学习笔记---LED点阵屏显示图形动画

目录 LED点阵屏显示图形 LED点阵屏显示动画 最后补充 上一节我们讲了点阵屏的工作原理&#xff0c;这节开始代码演示&#xff01; 前面我们已经说了74HC595模块也提供了8个LED&#xff0c;当我们不使用点阵屏的时候也可以单独使用74HC595&#xff0c;这8个LED可以用来测试7…...

Git分支常用指令

目录 1 git branch 2 git branch xx 3 git checkout xx 4 git checkout -b xx 5 git branch -d xx 6 git branch -D xx 7 git merge xx(含快进模式和冲突解决的讲解) 注意git-log: 1 git branch 作用&#xff1a;查看分支 示例&#xff1a; 2 git branch xx 作用&a…...

3.3 Binance_interface APP U本位合约行情-实时行情

Binance_interface APP U本位合约行情-实时行情 Github地址PyTed量化交易研究院 量化交易研究群(VX) py_ted目录 Binance_interface APP U本位合约行情-实时行情1. APP U本位合约行情-实时行情函数总览2. 模型实例化3. 获取一个产品的最优挂单 get_bookTicker4. 获取全部产品…...

机器学习——流形学习

流形学习是一种在机器学习领域中用于理解和分析数据的技术。它的核心思想是&#xff0c;尽管我们通常将数据表示为高维空间中的向量&#xff0c;但实际上数据可能具有较低维度的内在结构&#xff0c;这种结构被称为流形。流形学习的目标是发现并利用数据的这种潜在结构&#xf…...

离线数仓(一)【数仓概念、需求架构】

前言 今天开始学习数仓的内容&#xff0c;之前花费一年半的时间已经学完了 Hadoop、Hive、Zookeeper、Spark、HBase、Flume、Sqoop、Kafka、Flink 等基础组件。把学过的内容用到实践这是最重要的&#xff0c;相信会有很大的收获。 1、数据仓库概念 1.1、概念 数据仓库&#x…...

物联网测试:2024 年的最佳实践和挑战

据 Transforma Insights 称&#xff0c;到 2030 年&#xff0c;全球广泛使用的物联网 (IoT) 设备预计将增加近一倍&#xff0c;从 151 亿台增至 290 亿台。这些设备以及智能汽车、智能手机等广泛应用于各种官僚机构。 健康视频监视器、闹钟以及咖啡机和冰箱等最受欢迎的家用电器…...

蓝桥杯Web应用开发-CSS3 新特性

CSS3 新特性 专栏持续更新中 在前面我们已经学习了元素选择器、id 选择器和类选择器&#xff0c;我们可以通过标签名、id 名、类名给指定元素设置样式。 现在我们继续选择器之旅&#xff0c;学习 CSS3 中新增的三类选择器&#xff0c;分别是&#xff1a; • 属性选择器 • 子…...