【机器学习】Boosting算法-梯度提升算法(Gradient Boosting)

76dc4a2b0965f7576ff58465dc669cf7.jpeg

一、原理

梯度提升算法是一种集成学习方法,它可以将多个弱分类器或回归器组合成一个强分类器或回归器,提高预测性能。梯度提升算法的核心思想是利用损失函数的负梯度作为残差的近似值,然后用一个基学习器拟合这个残差,再将其加到之前的模型上,从而不断地减小损失函数的值。梯度提升算法有以下几个特点:

  • 梯度提升算法可以用任何可微分的损失函数,如平方误差、绝对误差、交叉熵等,这使得它比其他基于指数损失函数的算法更加灵活和通用。

  • 梯度提升算法可以用任何基学习器,如决策树、神经网络、支持向量机等,这使得它比其他基于单一类型的基学习器的算法更加强大和多样化。

  • 梯度提升算法可以通过调整学习率、迭代次数、树的深度等参数来控制模型的复杂度和过拟合程度,这使得它比其他缺乏正则化手段的算法更加稳定和可控。

1.1 梯度提升算法

3c48d125d7a66b2e673b986025db356f.jpeg

9281ae167f3d1be511928aa8d13f71fe.jpeg

1.2 四种梯度提升算法实现

0256792e2ba33305ba7adef7b90c41b0.jpeg

499abdb1ec9b119b0569dbc0c9e92787.jpeg

1.3 回归问题

784d24bef449928260eecf7a736e88ff.jpeg

c17c450998f8c673936b7debd3fda1b4.jpeg

3acc4b94453ef8579e291b0704271f71.jpeg

1.4 分类问题

对于分类问题损失函数为log-loss 梯度提升算法推导

e8e0436e38310052bd3aef6b2e9b7978.jpeg

对于分类问题梯度提升算法损失函数的具体形式

848ca9740d6178a27e1d9adf08dc0d34.jpeg

1.5 梯度提升算法对于分类问题和回归问题的区别

a9e1da4eb86478bfc7eb7390e3ccca65.png

1.6 XGBoost 算法推导

8f3721e37482e87236efbe9698163dac.jpeg

1.7 AdaBoost与梯度提升对比

62b0d66851bd121f793eb9a954cf6039.jpeg

1.8 梯度提升优缺点

b121eb7b5f0214a623f2b25f93b8110e.jpeg

二、示例代码

2.1 使用四种不同的基于梯度提升树的回归器来预测波士顿房价数据集的房价,并比较它们的均方误差。

9e22674ad865c88b2bad9b7ea99fc319.jpeg

指定版本python安装梯度提升算法框架(python3.12不支持)

  • 首先,导入所需的库和模块,包括 numpy,sklearn,以及四种回归器的库。

  • 然后,使用 sklearn.datasets.load_boston 函数来加载波士顿房价数据集,这是一个经典的回归问题的数据集,包含 506 个样本,13 个特征,和 1 个目标变量,即房价的中位数。

  • 接着,使用 sklearn.model_selection.train_test_split 函数来划分训练集和测试集,设置测试集的比例为 0.2,随机数种子为 42,以保证结果的可复现性。

  • 然后,定义一个字典 regressors,存储四种不同的回归器的实例,分别是 GBDT,CatBoost,LightGBM,和 XGBoost。这四种回归器都是基于梯度提升树的集成学习方法,它们的共同点是都使用加法模型和贪心算法来逐步增加树的数量,每次迭代都要求解一个新的树,使得目标函数最小化。它们的不同点是在损失函数,正则化项,树的结构,分裂点的选择,以及并行化和优化等方面有各自的特点和优势。

  • 最后,使用一个 for 循环来遍历 regressors 字典中的每个回归器,对于每个回归器,执行以下步骤:

    • 使用 fit 方法来训练回归器,传入训练集的特征和目标变量,得到一个训练好的模型。

    • 使用 predict 方法来预测测试集的房价,传入测试集的特征,得到一个预测值的数组。

    • 使用 sklearn.metrics.mean_squared_error 函数来计算预测值和真实值之间的均方误差,这是一个常用的回归问题的评价指标,表示预测误差的平方的均值,越小越好。

    • 使用 print 函数来打印回归器的名称和均方误差的值,保留两位小数。

# 导入所需的库和模块
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import GradientBoostingRegressor # GBDT
from catboost import CatBoostRegressor # CatBoost
from lightgbm import LGBMRegressor # LightGBM
from xgboost import XGBRegressor # XGBoost# 加载波士顿房价数据集
X, y = load_boston(return_X_y=True)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 定义不同的回归器
regressors = {"GBDT": GradientBoostingRegressor(random_state=42),"CatBoost": CatBoostRegressor(random_state=42, verbose=0),"LightGBM": LGBMRegressor(random_state=42),"XGBoost": XGBRegressor(random_state=42)
}# 训练和评估不同的回归器
for name, reg in regressors.items():# 训练回归器reg.fit(X_train, y_train)# 预测测试集y_pred = reg.predict(X_test)# 计算均方误差mse = mean_squared_error(y_test, y_pred)# 打印结果print(f"{name} MSE: {mse:.2f}")

输出结果:

GBDT MSE: 6.21
CatBoost MSE: 7.72
[LightGBM] [Info] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000745 seconds.
You can set `force_row_wise=true` to remove the overhead.
And if memory is not enough, you can set `force_col_wise=true`.
[LightGBM] [Info] Total Bins 1030
[LightGBM] [Info] Number of data points in the train set: 404, number of used features: 13
[LightGBM] [Info] Start training from score 22.796535
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
……
……
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
LightGBM MSE: 8.34
XGBoost MSE: 6.91

2.2 基于GBDT(Gradient Boosting Decision Trees)算法的分类与回归示例

2.2.1 使用梯度提升分类器(GradientBoostingClassifier)对成人收入数据集(adult_GBDT_Data)进行分类,并评估不同的参数组合对模型性能的影响

  • 导入所需的模块和数据,包括sklearn.ensemble中的GradientBoostingClassifier,numpy,prettytable,matplotlib等,以及自定义的adult_GBDT_Data模块。

  • 定义一些辅助函数,如Tom,ConfuseMatrix,fmse,用于计算混淆矩阵和F1度量等评价指标。

  • 定义Train函数,用于训练一个梯度提升分类器,并返回训练集和验证集上的F1度量。

  • 定义Zuhe函数,用于遍历不同的弱模型个数(models)和树的层数(cengs)的组合,使用交叉验证的方法评估每种组合的平均F1度量,并返回最优的参数组合和对应的折数。

  • 定义duibi函数,用于绘制不同参数组合的F1对比曲线,并保存图片。

  • 定义recspre函数,用于根据最优的参数组合,重新训练一个梯度提升分类器,并在预测数据集(predict_data)上进行预测,输出混淆矩阵和F1度量,精确率,召回率等指标。

  • 在主函数中,调用Zuhe函数,得到最优的参数组合和折数,调用duibi函数,绘制对比曲线,调用recspre函数,进行预测和评估。

#  adult_GBDT_Data.py
import pandas as pd # 导入pandas库,用于数据处理
import numpy as np # 导入numpy库,用于数值计算#  训练数据文件路径
train_path = 'Boosting\Adult_Train.csv' # 定义训练数据的文件路径,文件格式为csv#  预测数据文件路径
pre_path = 'Boosting\Adult_Test.csv' # 定义预测数据的文件路径,文件格式为csv# 读取并且处理确缺失数据
def ReadHandle(filepath, miss='fill'):  # 定义处理数据的函数,参数为文件路径和缺失值处理方式data = pd.read_csv(r'%s' % filepath) # 读取csv文件,返回一个pandas的DataFrame对象data = data.replace('?', np.nan) # 将数据中的'?'替换为numpy的nan值,表示缺失值#  处理缺失值if miss == 'del':  # 如果缺失值处理方式为'del',则删除掉缺失值miss_data = data.dropna(how='any') # 使用dropna方法,删除掉任何含有缺失值的行或列else: # 否则,使用'fill'方式,即填充缺失值miss_data = data.fillna(method='ffill') # 使用fillna方法,使用前一个有效值来填充缺失值,method='ffill'表示向前填充return miss_data # 返回处理后的数据#  将字符串字段进行数字编码,
def Digitcode(traindata, predixdata): # 定义数字编码的函数,参数为训练数据和预测数据#  数字编码for ikey in traindata: # 遍历训练数据的每一列if traindata[ikey].dtype == 'object':  # 如果列的数据类型为object,即字符串类型,那么进行数字编码numb = sorted(list(set(list(traindata[ikey].values)))) # 将列的所有值去重并排序,得到一个列表exdict = {ji: numb.index(ji) for ji in numb} # 生成一个字典,将每个值映射为其在列表中的索引,即数字编码if ikey == 'Money':  # 如果列的名称为'Money',因为sklearn支持字符串类别predixdata[ikey] = ['%s' % gfi[:-1] for gfi in predixdata[ikey]]  # 因为测试数据文件中Money的值多个点,所以去掉最后一个点else: # 否则,对训练数据和预测数据的该列进行数字编码predixdata[ikey] = [exdict[fi] for fi in predixdata[ikey]] # 使用字典的映射关系,将预测数据的该列的值替换为数字traindata[ikey] = [exdict[fi] for fi in traindata[ikey]] # 使用字典的映射关系,将训练数据的该列的值替换为数字return traindata, predixdata.values # 返回数字编码后的训练数据和预测数据# 读取的数据
read_train = ReadHandle(train_path) # 调用ReadHandle函数,读取并处理训练数据文件,返回一个DataFrame对象
read_pre = ReadHandle(pre_path) # 调用ReadHandle函数,读取并处理预测数据文件,返回一个DataFrame对象# 经过处理的数据
han_train, predict_data = Digitcode(read_train, read_pre) # 调用Digitcode函数,对训练数据和预测数据进行数字编码,返回两个数组#  将训练数据进行K折交叉验证,根据F1度量确定最佳的
#  然后再进行预测数据的计算,输出混淆矩阵以及精确率、召回率,F1度量def kfold(trdata, k=10): # 定义K折交叉验证的函数,参数为训练数据和折数vadata = trdata.values # 将训练数据转换为数组legth = len(vadata) # 获取训练数据的长度datadict = {} # 定义一个空字典,用于存储每一折的数据signnuber = np.arange(legth) # 生成一个从0到长度的整数序列,用于索引for hh in range(k): # 遍历每一折datadict[hh] = {} # 初始化该折的数据字典np.random.shuffle(vadata) # 对训练数据进行随机打乱yanzhneg = np.random.choice(signnuber, int(legth / k), replace=False) # 从整数序列中随机选择一部分作为验证集的索引,不重复oneflod_yan = vadata[yanzhneg] # 根据索引,获取验证集的数据oneflod_xun = vadata[[hdd for hdd in signnuber if hdd not in yanzhneg]] # 根据索引,获取训练集的数据,即剩余的数据# 训练数据和验证数据datadict[hh]['train'] = oneflod_xun # 将训练集的数据存储到该折的数据字典中datadict[hh]['test'] = oneflod_yan # 将验证集的数据存储到该折的数据字典中return datadict # 返回包含所有折的数据的字典#  存储K折交叉验证的数据字典
dt_data = kfold(han_train) # 调用kfold函数,对训练数据进行K折交叉验证,返回一个数据字典
# GBDT_Classify_adult.py
# 导入adult_GBDT_Data模块,该模块包含了成年人收入数据集
import adult_GBDT_Data as data# 引入GBDT分类模型,该模型是一种基于梯度提升的集成学习方法
from sklearn.ensemble import GradientBoostingClassifier# 导入numpy模块,该模块提供了科学计算的基本功能
import numpy as np# 导入prettytable模块,该模块可以格式化输出混淆矩阵
from prettytable import PrettyTable as PT# 导入pylab和matplotlib模块,这些模块可以绘制不同参数下F1度量的对比曲线
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong']  # 显示中文
mpl.rcParams['axes.unicode_minus'] = False  # 显示负号
import matplotlib.pyplot as plt# 根据K折交叉的结果确定比较好的参数组合,然后给出预测数据集的结果
# 主要的参数就是随机森林中树的个数和特征的个数,其他参数均使用默认值# 弱模型中树的层数
cengs = [5, 7, 9]# 弱模型的个数
models = [120, 140, 280]# 混淆矩阵的函数
def Tom(reallist, prelist):''':param reallist: 真实的类别列表:param prelist:  预测的类别列表:return: 每个类别预测为所有类别的个数字典'''# 创建一个空字典,用于存储每个类别预测为所有类别的个数coundict = {}# 遍历真实类别列表中的所有不重复的类别for jj in list(set(reallist)):# 在字典中创建一个以该类别为键的子字典coundict[jj] = {}# 遍历真实类别列表中的所有不重复的类别for hh in list(set(reallist)):# 在子字典中创建一个以该类别为键的值,该值为真实类别为jj且预测类别为hh的样本个数coundict[jj][hh] = len([i for i, j in zip(reallist, prelist) if i == jj and j == hh])# 返回字典return coundict# 定义输出混淆矩阵的函数
def ConfuseMatrix(reallist, prelist):''':param reallist: 真实的类别列表:param prelist: 预测的类别列表:return: 输出混淆矩阵'''# 调用Tom函数,得到每个类别预测为所有类别的个数字典zidian = Tom(reallist, prelist)# 对字典的键进行排序,得到类别的列表lieming = sorted(zidian.keys())# 创建一个prettytable对象,用于输出混淆矩阵table = PT(['混淆矩阵'] + ['预测%s'% d for d in lieming])# 遍历类别列表for jj in lieming:# 向表格中添加一行,包括真实类别和预测为各个类别的个数table.add_row(['实际%s' % jj] + [zidian[jj][kk] for kk in lieming])# 返回表格对象return table#  计算F1度量的函数
def fmse(realist, prelist):  # 对于多类别每个类都要计算召回率''':param realist: 真实的类别列表:param prelist: 预测的类别列表:return: F1度量'''# 调用Tom函数,得到每个类别预测为所有类别的个数字典condict = Tom(realist, prelist)# 初始化总样本数和正确预测数为0zongshu = 0zhengque = 0# 创建一个空列表,用于存储每个类别的召回率zhao_cu = []  # 遍历字典中的每个类别for cu in condict:# 初始化该类别的真实样本数和正确预测数为0zq = 0zs = 0# 遍历字典中的每个类别for hh in condict[cu]:# 获取该类别预测为hh的样本个数geshu = condict[cu][hh]# 如果cu和hh相同,说明预测正确,累加正确预测数if cu == hh:zhengque += geshuzq = geshu# 累加总样本数zongshu += geshu# 累加该类别的真实样本数zs += geshu# 计算该类别的召回率,并添加到列表中zhao_cu.append(zq / zs)# 计算精确率jingque = zhengque / zongshu# 计算类别召回率的平均值zhaohui = np.mean(np.array(zhao_cu))# f1度量f_degree = 2 * jingque * zhaohui / (jingque + zhaohui)# 返回F1度量,精确率和召回率return f_degree, jingque, zhaohui# 训练函数
def Train(data, modelcount, censhu, yanzhgdata):# 创建一个GBDT分类模型对象,指定损失函数,弱模型的个数,树的层数,学习率和特征的个数model = GradientBoostingClassifier(loss='deviance', n_estimators=modelcount, max_depth=censhu, learning_rate=0.1, max_features='sqrt')# 使用训练数据拟合模型model.fit(data[:, :-1], data[:, -1])# 给出训练数据的预测值train_out = model.predict(data[:, :-1])# 计算训练数据的F1度量train_mse = fmse(data[:, -1], train_out)[0]# 给出验证数据的预测值add_yan = model.predict(yanzhgdata[:, :-1])# 计算验证数据的F1度量add_mse = fmse(yanzhgdata[:, -1], add_yan)[0]# 打印训练数据和验证数据的F1度量print(train_mse, add_mse)# 返回训练数据和验证数据的F1度量return train_mse, add_mse# 定义一个函数,用于确定最优的参数组合
def Zuhe(datadict, tre=models, ce=cengs):# 创建一个空字典,用于存储不同参数组合的F1度量的均值savedict = {}# 创建一个空字典,用于存储不同参数组合的F1度量的列表sacelist = {}# 遍历弱模型的个数for t in tre:# 遍历树的层数for j in ce:# 打印当前的参数组合print(t, j)# 创建一个空列表,用于存储不同折数的验证数据的F1度量sumlist = []# 因为要展示折数,因此要按序开始# 对数据字典的键进行排序,得到折数的列表ordelist = sorted(list(datadict.keys()))# 遍历折数的列表for jj in ordelist:# 调用训练函数,传入训练数据,验证数据,弱模型的个数和树的层数,得到训练数据和验证数据的F1度量xun, ya = Train(datadict[jj]['train'], t, j, datadict[jj]['test'])# 只选择验证数据较大的# 将验证数据的F1度量添加到列表中sumlist.append(ya)# 将参数组合和对应的F1度量的列表存入字典中sacelist['%s-%s' % (t, j)] = sumlist# 计算F1度量的列表的均值,并存入另一个字典中savedict['%s-%s' % (t, j)] = np.mean(np.array(sumlist))# 在结果字典中选择最大的F1度量的均值,得到最优的参数组合zuixao = sorted(savedict.items(), key=lambda fu: fu[1], reverse=True)[0][0]# 然后再选出此方法中和值最大的折数xiao = sacelist[zuixao].index(max(sacelist[zuixao]))# 返回最优的参数组合,最优的折数和F1度量的字典return zuixao, xiao, sacelist# 定义一个函数,用于根据字典绘制不同参数组合的F1度量的对比曲线
def duibi(exdict, you):# 创建一个图形对象,指定大小plt.figure(figsize=(11, 7))# 遍历字典中的每个参数组合for ii in exdict:# 绘制折数和F1度量的折线图,添加标签plt.plot(list(range(len(exdict[ii]))), exdict[ii], \label='%s,%d折F1均值:%.4f' % (ii, len(exdict[ii]), np.mean(np.array(exdict[ii]))), lw=2)# 显示图例plt.legend()# 添加标题,显示最优的参数组合plt.title('不同参数的组合F1对比曲线[最优:%s]' % you)# 保存图像到指定路径plt.savefig(r'C:\Users\cxy\Desktop\GBDT_adult.jpg')# 返回提示信息return '不同方法对比完毕'# 定义一个函数,用于根据获得最优参数组合绘制真实和预测值的对比曲线
def recspre(estrs, predata, datadict, zhe):# 将参数组合分割为弱模型的个数和树的层数mo, ze = estrs.split('-')# 创建一个GBDT分类模型对象,指定损失函数,弱模型的个数,树的层数,学习率和特征的个数model = GradientBoostingClassifier(loss='deviance', n_estimators=int(mo), max_depth=int(ze), learning_rate=0.1)# 使用最优的折数的训练数据拟合模型model.fit(datadict[zhe]['train'][:, :-1], datadict[zhe]['train'][:, -1])# 预测预测数据的类别yucede = model.predict(predata[:, :-1])# 计算混淆矩阵并打印print(ConfuseMatrix(predata[:, -1], yucede))# 返回预测数据的F1度量,精确率和召回率return fmse(predata[:, -1], yucede)# 主函数
if __name__ == "__main__":# 调用Zuhe函数,得到最优的参数组合,最优的折数和F1度量的字典zijian, zhehsu, xulie = Zuhe(data.dt_data)# 调用duibi函数,绘制方法组合的对比曲线duibi(xulie, zijian)# 调用recspre函数,计算预测数据的f1度量,精确率以及召回率f1, jing, zhao = recspre(zijian, data.predict_data, data.dt_data, zhehsu)# 打印结果print('F1度量:{}, 精确率:{}, 召回率:{}'.format(f1, jing, zhao))

901658e32ffc0f3eee9e437c85a6c49f.png

输出结果:

ae9c5237d3c9053de7f7ac4bb22bfd07.jpeg

2f973f38cd58a0e06b5086c48a9f49d9.jpeg

2.2.2 使用GBDT回归模型对PM2.5的数据进行预测和分析

对一个包含空气质量数据的文件进行预处理,生成训练和预测数据集

  • 导入 pandas 和 numpy 库

  • 读取数据文件,使用 pd.read_csv 函数

  • 定义 DeleteTargetNan 函数,用于删除目标变量 pm2.5 为空值的行,并用均值填充其他列的缺失值,最后将目标变量放在最后一列

  • 定义 Shanchu 函数,用于删除不需要的字段,如 No

  • 定义 Digit 函数,用于将字符串类型的属性转换为数字编码

  • 对原始数据调用 DeleteTargetNan, Shanchu, Digit 函数,得到处理后的数据集 third

  • 定义 fenge 函数,用于将数据集按照 8:2 的比例分为训练和预测数据集,其中训练数据集再分为 K 折,用于交叉验证

  • 对 third 数据集调用 fenge 函数,得到 dt_data 和 predict_data,分别是 K 折交叉的训练数据和预测数据

import pandas as pd # 导入 pandas 库,用于数据处理
import numpy as np # 导入 numpy 库,用于数值计算# 读取数据文件
data = pd.read_csv('Boosting\PRSA_data_2010.1.1-2014.12.31.csv')#  因为Pm2.5是目标数据,如有缺失值直接删除这一条记录# 删除目标值为空值的行的函数, 其他列为缺失值则自动填充的函数,并将目标变量放置在数据集最后一列
def DeleteTargetNan(exdata, targetstr):if exdata[targetstr].isnull().any(): # 如果目标列有空值loc = exdata[targetstr][data[targetstr].isnull().values == True].index.tolist() # 找到空值所在的行索引exdata = exdata.drop(loc) # 删除这些行exdata = exdata.fillna(exdata.mean()) # 其他列的空值用平均值填充targetnum = exdata[targetstr].copy() # 复制目标列del exdata[targetstr] # 删除原来的目标列exdata[targetstr] = targetnum # 将目标列添加到数据集的最后一列return exdata # 返回处理后的数据集# 删除原始数据中不需要的字段名
def Shanchu(exdata, aiduan=['No']):for ai in aiduan: # 对于每个不需要的字段名if ai in exdata.keys(): # 如果在数据集中存在del exdata[ai] # 删除该字段return exdata # 返回处理后的数据集# 将数据中的属性值为字符串的进行数字编码,因为独热编码对决策树而言不那么重要
def Digit(eadata):for jj in eadata: # 对于每个属性try:eadata[jj].values[0] + 1 # 尝试将第一个值加一except TypeError: # 如果出现类型错误,说明该属性值为字符串numlist = list(set(list(eadata[jj].values))) # 将该属性的所有不同值转换为列表zhuan = [numlist.index(jj) for jj in eadata[jj].values] # 将每个值替换为其在列表中的索引eadata[jj] = zhuan # 更新该属性的值return eadata # 返回处理后的数据集first = DeleteTargetNan(data, 'pm2.5') # 调用删除目标值为空值的函数
two = Shanchu(first) # 调用删除不需要的字段的函数
third = Digit(two) # 调用数字编码的函数# 将数据集按照8:2的比例分为训练、预测数据集。其中训练数据集再分为K份,进行K折交叉验证
def fenge(exdata, k=10, per=[0.8, 0.2]):lent = len(exdata) # 获取数据集的长度alist = np.arange(lent) # 生成一个从0到长度减一的数组np.random.shuffle(alist) # 随机打乱数组xunlian_sign = int(lent * per[0]) # 计算训练数据集的大小xunlian = np.random.choice(alist, xunlian_sign, replace=False) # 从数组中随机选择训练数据集的索引,不重复yuce = np.array([i for i in alist if i not in xunlian]) # 剩下的索引为预测数据集的索引save_dict = {} # 创建一个空字典,用于存储K折交叉验证的数据for jj in range(k): # 对于每一折save_dict[jj] = {} # 创建一个子字典length = len(xunlian) # 获取训练数据集的长度# 随机选yuzhi = int(length / k) # 计算每一折的大小yan = np.random.choice(xunlian, yuzhi, replace=False) # 从训练数据集中随机选择一折的索引,不重复tt = np.array([i for i in xunlian if i not in yan]) # 剩下的索引为训练数据集的索引save_dict[jj]['train'] = exdata[tt] # 将训练数据集存入子字典save_dict[jj]['test'] = exdata[yan] # 将测试数据集存入子字典return save_dict, exdata[yuce] # 返回字典和预测数据集deeer = fenge(third.values) # 调用分割数据集的函数dt_data = deeer[0] # 获取K折交叉验证的数据
predict_data = deeer[1] # 获取预测数据集
  • 引入数据,使用pm25_GBDT_Data模块提供的数据集,包括训练数据和预测数据。

  • 引入GBDT回归模型,使用sklearn.ensemble中的GradientBoostingRegressor类,以及sklearn.metrics中的mean_squared_error函数计算MSE。

  • 定义训练函数,接受训练数据、模型参数和验证数据作为输入,返回训练数据和验证数据的MSE。

  • 定义最终确定组合的函数,接受数据字典、弱模型的个数和树的层数作为输入,使用K折交叉验证的方法,遍历不同的参数组合,返回最优的参数组合、最小的MSE对应的折数和每种参数组合的MSE序列。

  • 根据字典绘制曲线,使用matplotlib.pyplot模块,绘制不同参数组合的MSE对比曲线,标注最优的参数组合。

  • 根据最优参数组合绘制真实和预测值的对比曲线,使用预测数据和最小MSE对应的训练数据,训练最优的GBDT回归模型,绘制真实值和预测值的对比曲线,以及真实值和预测值的相对误差曲线。

  • 定义主函数,调用上述函数,完成数据的预测和分析。

# 引入数据
import pm25_GBDT_Data as data # 导入pm25_GBDT_Data模块,该模块包含了用于训练和预测的数据# 引入GBDT回归模型
from sklearn.ensemble import GradientBoostingRegressor # 导入sklearn库中的梯度提升回归模型,该模型是一种集成学习方法,可以用多个弱模型组合成一个强模型
from sklearn.metrics import mean_squared_error as mse # 导入sklearn库中的均方误差函数,该函数可以用来评估模型的预测性能
import numpy as np # 导入numpy库,该库提供了多种数学和科学计算的功能# 绘制不同参数下MSE的对比曲线
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong']  # 显示中文
mpl.rcParams['axes.unicode_minus'] = False  # 显示负号
import matplotlib.pyplot as plt # 导入matplotlib库中的pyplot模块,该模块提供了绘图的功能# 根据K折交叉的结果确定比较好的参数组合,然后给出预测数据真实值和预测值的对比
# 更改的参数一是框架的参数,二是弱模型的参数# 弱模型中树的层数
cengs = [16, 17, 18] # 定义一个列表,存储不同的树的层数,用于调整弱模型的复杂度
# 定义弱模型的个数
models = [55, 56, 57] # 定义一个列表,存储不同的弱模型的个数,用于调整集成模型的强度# 训练函数  _SUPPORTED_LOSS = ('ls', 'lad', 'huber', 'quantile')
def Train(data, modelcount, censhu, yanzhgdata): # 定义一个训练函数,接受四个参数:data是训练数据,modelcount是弱模型的个数,censhu是树的层数,yanzhgdata是验证数据model = GradientBoostingRegressor(loss='ls', n_estimators=modelcount, max_depth=censhu, learning_rate=0.12, subsample=0.8) # 创建一个梯度提升回归模型,设置损失函数为最小二乘法,弱模型的个数为modelcount,树的层数为censhu,学习率为0.12,子采样比例为0.8model.fit(data[:, :-1], data[:, -1]) # 使用训练数据的特征和标签拟合模型# 给出训练数据的预测值train_out = model.predict(data[:, :-1]) # 使用训练数据的特征预测训练数据的标签# 计算MSEtrain_mse = mse(data[:, -1], train_out) # 使用均方误差函数计算训练数据的真实标签和预测标签之间的误差# 给出验证数据的预测值add_yan = model.predict(yanzhgdata[:, :-1]) # 使用验证数据的特征预测验证数据的标签# 计算MSEadd_mse = mse(yanzhgdata[:, -1], add_yan) # 使用均方误差函数计算验证数据的真实标签和预测标签之间的误差print(train_mse, add_mse) # 打印训练数据和验证数据的误差return train_mse, add_mse # 返回训练数据和验证数据的误差# 最终确定组合的函数
def Zuhe(datadict, tre=models, tezhen=cengs): # 定义一个确定最优参数组合的函数,接受三个参数:datadict是一个字典,存储了不同折数的训练数据和验证数据,tre是一个列表,存储了不同的弱模型的个数,tezhen是一个列表,存储了不同的树的层数# 存储结果的字典savedict = {} # 定义一个空字典,用于存储不同参数组合的均方误差的均值# 存储序列的字典sacelist = {} # 定义一个空字典,用于存储不同参数组合的均方误差的序列for t in tre: # 遍历弱模型的个数for te in tezhen: # 遍历树的层数print(t, te) # 打印当前的参数组合sumlist = [] # 定义一个空列表,用于存储不同折数的验证数据的误差# 因为要展示折数,因此要按序开始ordelist = sorted(list(datadict.keys())) # 将datadict的键(即折数)排序并转换为列表for jj in ordelist: # 遍历折数xun, ya = Train(datadict[jj]['train'], t, te, datadict[jj]['test']) # 调用训练函数,传入当前折数的训练数据和验证数据,以及当前的参数组合,返回训练数据和验证数据的误差# 根据验证数据的误差确定最佳的组合sumlist.append(ya) # 将验证数据的误差添加到列表中sacelist['%s-%s' % (t, te)] = sumlist # 将当前参数组合和对应的误差列表存储到sacelist字典中savedict['%s-%s' % (t, te)] = np.mean(np.array(sumlist)) # 将当前参数组合和对应的误差列表的均值存储到savedict字典中# 在结果字典中选择最小的zuixao = sorted(savedict.items(), key=lambda fu: fu[1])[0][0] # 对savedict字典按照值(即误差均值)进行排序,取出第一个元素(即最小的误差均值)的键(即最优的参数组合)# 然后再选出此方法中和值最小的折数xiao = sacelist[zuixao].index(min(sacelist[zuixao])) # 在sacelist字典中根据最优的参数组合找到对应的误差列表,然后在列表中找到最小的误差,返回其索引(即最优的折数)return zuixao, xiao, sacelist # 返回最优的参数组合,最优的折数,和误差列表的字典# 定义一个函数 duibi,用于绘制不同参数组合的 MSE 对比曲线
# 参数 exdict 是一个字典,存储了不同参数组合的 MSE 列表
# 参数 you 是一个字符串,表示最优的参数组合
def duibi(exdict, you):# 创建一个 11 x 7 的图形plt.figure(figsize=(11, 7))# 遍历 exdict 中的每个参数组合for ii in exdict:# 绘制 MSE 随数据量变化的曲线,添加标签plt.plot(list(range(len(exdict[ii]))), exdict[ii], \label='%s,%d折MSE均值:%.3f' % (ii, len(exdict[ii]), np.mean(np.array(exdict[ii]))), lw=2)# 显示图例plt.legend()# 添加标题,显示最优的参数组合plt.title('不同参数的组合MSE对比曲线[最优:%s]' % you)# 保存图形到指定路径plt.savefig(r'C:\Users\cxy\Desktop\GBDT_pm25.jpg')# 返回一个字符串,表示对比完成return '不同方法对比完毕'# 定义一个函数 recspre,用于绘制真实值和预测值的对比曲线
# 参数 exstr 是一个字符串,表示最优的参数组合,格式为 "树的数量-树的深度"
# 参数 predata 是一个数组,表示预测数据,最后一列是真实值
# 参数 datadict 是一个字典,存储了不同折数的训练数据和测试数据
# 参数 zhe 是一个整数,表示使用哪一折的数据
# 参数 count 是一个整数,表示要展示的数据条数,默认为 100
def recspre(exstr, predata, datadict, zhe, count=100):# 根据 exstr 分割出树的数量和树的深度tree, te = exstr.split('-')# 创建一个梯度提升回归模型,设置损失函数、树的数量、树的深度、学习率和子采样比例model = GradientBoostingRegressor(loss='ls', n_estimators=int(tree), max_depth=int(te), learning_rate=0.12, subsample=0.8)# 使用指定折数的训练数据拟合模型,最后一列是目标值model.fit(datadict[zhe]['train'][:, :-1], datadict[zhe]['train'][:, -1])# 使用模型对预测数据进行预测,忽略最后一列的真实值yucede = model.predict(predata[:, :-1])# 为了便于展示,从预测结果中随机选择 count 条数据zongleng = np.arange(len(yucede))randomnum = np.random.choice(zongleng, count, replace=False)# 获取选中的预测值和真实值yucede_se = list(np.array(yucede)[randomnum])yuce_re = list(np.array(predata[:, -1])[randomnum])# 绘制对比图plt.figure(figsize=(17, 9))# 创建一个 2 x 1 的子图,第一个子图显示预测值和真实值的曲线plt.subplot(2, 1, 1)# 用红色虚线绘制预测值的曲线,添加标签plt.plot(list(range(len(yucede_se))), yucede_se, 'r--', label='预测', lw=2)# 用蓝色点绘制真实值的散点图,添加标签plt.scatter(list(range(len(yuce_re))), yuce_re, c='b', marker='.', label='真实', lw=2)# 设置 x 轴的范围plt.xlim(-1, count + 1)# 显示图例plt.legend()# 添加标题,显示树的数量plt.title('预测和真实值对比[最大树数%d]' % int(tree))# 第二个子图显示真实值和预测值的相对误差plt.subplot(2, 1, 2)# 用黑色虚线绘制真实值减去预测值的曲线,添加标签plt.plot(list(range(len(yucede_se))), np.array(yuce_re) - np.array(yucede_se), 'k--', marker='s', label='真实-预测', lw=2)# 显示图例plt.legend()# 添加标题plt.title('预测和真实值相对误差')# 保存图形到指定路径plt.savefig(r'C:\Users\cxy\Desktop\duibi.jpg')# 返回一个字符串,表示对比完成return '预测真实对比完毕'# 主函数
if __name__ == "__main__":# 调用 Zuhe 函数,得到最优的参数组合、折数和 MSE 字典zijian, zhehsu, xulie = Zuhe(data.dt_data)# 调用 duibi 函数,绘制不同参数组合的 MSE 对比曲线duibi(xulie, zijian)# 调用 recspre 函数,绘制真实值和预测值的对比曲线recspre(zijian, data.predict_data, data.dt_data, zhehsu)

输出结果:

abe9d2caf21dec66a5b44d6b0ea6a3d0.jpegce595e909e7b7b7bcb321e4d4d9e95c5.jpeg

2.3 四种梯度提升算法:GBDT, CatBoost, LightGBM, XGBoost 参数设置

  • GBDT(Gradient Boosting Decision Tree)是一种基于梯度提升的集成学习算法,它使用决策树作为弱学习器,通过迭代地拟合残差来提高预测性能。GBDT 的主要参数有:

    • n_estimators:弱学习器的数量,即决策树的数量。增加该参数可以提高模型的复杂度和拟合程度,但也可能导致过拟合。

    • learning_rate:学习率,即每个弱学习器的贡献系数。减小该参数可以降低过拟合的风险,但也需要增加 n_estimators 以保持足够的拟合程度。

    • max_depth:决策树的最大深度。增加该参数可以增加模型的非线性和拟合能力,但也可能导致过拟合。

    • min_samples_split:决策树内部节点进行分裂所需的最小样本数。增加该参数可以防止过拟合,但也可能导致欠拟合。

    • min_samples_leaf:决策树叶节点所需的最小样本数。增加该参数可以防止过拟合,但也可能导致欠拟合。

    • subsample:用于训练每个弱学习器的样本比例。减小该参数可以降低方差,但也可能增加偏差。

    • max_features:用于分裂每个决策树节点的特征数量。减小该参数可以降低过拟合的风险,但也可能降低模型的表达能力。

  • XGBoost(Extreme Gradient Boosting)是一种优化的 GBDT 实现,它使用了更高效的数据结构和并行计算,同时引入了正则化项和剪枝策略来防止过拟合。XGBoost 的主要参数有:

    • n_estimators:同 GBDT。

    • learning_rate:同 GBDT。

    • max_depth:同 GBDT。

    • min_child_weight:决策树叶节点的最小权重和,相当于 GBDT 中的 min_samples_leaf 乘以样本权重。增加该参数可以防止过拟合,但也可能导致欠拟合。

    • subsample:同 GBDT。

    • colsample_bytree:相当于 GBDT 中的 max_features,表示用于训练每棵树的特征比例。减小该参数可以降低过拟合的风险,但也可能降低模型的表达能力。

    • reg_alpha:L1 正则化项的系数,用于惩罚模型的复杂度。增加该参数可以使模型更稀疏,但也可能损失一些信息。

    • reg_lambda:L2 正则化项的系数,用于惩罚模型的复杂度。增加该参数可以防止过拟合,但也可能降低模型的灵活性。

  • LightGBM(Light Gradient Boosting Machine)是一种基于梯度提升的高效的分布式机器学习框架,它使用了基于直方图的算法和基于叶子的生长策略,可以大大提高训练速度和减少内存消耗。LightGBM 的主要参数有:

    • n_estimators:同 GBDT。

    • learning_rate:同 GBDT。

    • num_leaves:决策树的最大叶子数,相当于 GBDT 中的 max_depth 的指数倍。增加该参数可以增加模型的复杂度和拟合程度,但也可能导致过拟合。

    • min_child_samples:同 GBDT 中的 min_samples_leaf

    • subsample:同 GBDT。

    • colsample_bytree:同 XGBoost。

    • reg_alpha:同 XGBoost。

    • reg_lambda:同 XGBoost。

  • CatBoost(Categorical Boosting)是一种基于梯度提升的机器学习框架,它专注于处理分类特征,使用了一种称为目标编码的技术来减少类别扩展的影响,同时使用了随机感知梯度提升算法来降低过拟合的风险。CatBoost 的主要参数有:

    • iterations:同 GBDT 中的 n_estimators

    • learning_rate:同 GBDT。

    • depth:同 GBDT 中的 max_depth

    • l2_leaf_reg:同 XGBoost 中的 reg_lambda

    • subsample:同 GBDT。

    • random_strength:用于平衡每个样本的权重,相当于 GBDT 中的 subsample 的倒数。增加该参数可以降低过拟合的风险,但也可能降低模型的表达能力。

    • one_hot_max_size:用于对类别特征进行独热编码的阈值,如果类别数小于该值,则使用独热编码,否则使用目标编码。增加该参数可以增加模型的非线性和拟合能力,但也可能导致维度灾难。

三、梯度提升算法在制造业中的应用

梯度提升算法在制造业中的一些应用场景。梯度提升算法是一种集成学习方法,它可以将多个弱分类器或回归器组合成一个强分类器或回归器,提高预测性能。梯度提升算法的核心思想是利用损失函数的负梯度作为残差的近似值,然后用一个基学习器拟合这个残差,再将其加到之前的模型上,从而不断地减小损失函数的值。梯度提升算法有以下几个特点:

  • 梯度提升算法可以用任何可微分的损失函数,如平方误差、绝对误差、交叉熵等,这使得它比其他基于指数损失函数的算法更加灵活和通用。

  • 梯度提升算法可以用任何基学习器,如决策树、神经网络、支持向量机等,这使得它比其他基于单一类型的基学习器的算法更加强大和多样化。

  • 梯度提升算法可以通过调整学习率、迭代次数、树的深度等参数来控制模型的复杂度和过拟合程度,这使得它比其他缺乏正则化手段的算法更加稳定和可控。

在制造业中,梯度提升算法也有一些有趣和有用的应用,例如:

  • 产品设计:梯度提升算法可以用于辅助工程师进行产品设计,通过设置期望的参数和性能等约束条件,利用人工智能算法,自动生成多种可行性方案,并筛选出最优的设计方案¹。

  • 故障诊断:梯度提升算法可以用于对制造过程中的故障进行诊断,通过分析传感器数据,识别出异常模式,并提供相应的解决方案²。

  • 质量检测:梯度提升算法可以用于对制造产品的质量进行检测,通过图像分析,检测出产品的缺陷或瑕疵,并提供相应的评估和反馈³。

你可以在以下网页中找到更多关于梯度提升算法在制造业中的应用的信息:

  • 智能制造的人工智能8大应用场景

  • [基于AdaBoost的故障诊断方法及其应用]

79c5417c54b4d0062358b15d9854938e.png

参考网址

(1) 【机器学习】梯度提升机GBM详解 - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/460598556.
(2) 机器学习随笔——分类与回归的联系与区别 - 知乎. https://zhuanlan.zhihu.com/p/589535856.
(3) 机器学习教程 之 梯度提升方法:GBDT处理分类问题-CSDN博客. https://blog.csdn.net/liangjun_feng/article/details/80668461.
(4) 机器学习算法之——梯度提升(Gradient Boosting)原理讲解及Python实现 - 知乎. https://zhuanlan.zhihu.com/p/108641227.
(5) 梯度提升与梯度下降_梯度提升和梯度下降的区别-CSDN博客. https://blog.csdn.net/qq_42003997/article/details/103682921.

(6) Gradient Boosting with Scikit-Learn, XGBoost, LightGBM, and CatBoost. https://machinelearningmastery.com/gradient-boosting-with-scikit-learn-xgboost-lightgbm-and-catboost/.
(7) When to Choose CatBoost Over XGBoost or LightGBM [Practical Guide]. https://neptune.ai/blog/when-to-choose-catboost-over-xgboost-or-lightgbm.
(8) GBDT、XGBoost、LightGBM 的使用及参数调优 - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/33700459.
(9) 从结构到性能,一文概述XGBoost、Light GBM和CatBoost的同与不同 - 知乎. https://zhuanlan.zhihu.com/p/34698733.
(10) 大战三回合:XGBoost、LightGBM和Catboost一决高低 - 知乎. https://zhuanlan.zhihu.com/p/72686522.

(11) GBDT: https://scikit-learn.org/stable/modules/ensemble.html#gradient-boosting

(12) CatBoost: https://catboost.ai/

(13) LightGBM: https://lightgbm.readthedocs.io/en/latest/

(14) XGBoost: https://xgboost.readthedocs.io/en/latest/

(15) 梯度提升算法 Gradient Boosting  https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html 

(16) https://scikit-learn.org/stable/auto_examples/ensemble/plot_gradient_boosting_quantile.html#sphx-glr-auto-examples-ensemble-plot-gradient-boosting-quantile-py 

(17)   集成算法 https://scikit-learn.org.cn/view/90.html# 

(18) 机器学习中的梯度提升 https://www.geeksforgeeks.org/ml-gradient-boosting/ 

(19) 梯度提升 https://deepai.org/machine-learning-glossary-and-terms/gradient-boosting 


The End

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

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

相关文章

二维码智慧门牌管理系统:提升社区管理智能化水平

文章目录 前言一、全方位信息录入与查询二、公安权限账户访问的公安大数据后台三、社区工作人员申请权限安装录入软件四、业主通过移动终端扫描标准地址二维码门牌自主申报录入五、系统的价值 前言 在数字化时代,社区管理面临着更新流动人口信息、准确录入六实相关…

docker安装入门及redis,minio,rabbitmq应用安装

部分笔记来自黑马课堂:【黑马程序员Docker快速入门到项目部署,MySQL部署Nginx部署docker自定义镜像DockerCompose项目实战一套搞定-哔哩哔哩】 https://b23.tv/niWEhEF 一、什么是docker: 快速构建、运行、管理应用的工具。--帮助我们快速部…

【中小型企业网络实战案例 二】配置网络互连互通

​【中小型企业网络实战案例 一】规划、需求和基本配置-CSDN博客 热门IT技术视频教程&#xff1a;https://xmws-it.blog.csdn.net/article/details/134398330?spm1001.2014.3001.5502 配置接入层交换机 1.以接入交换机ACC1为例&#xff0c;创建ACC1的业务VLAN 10和20。 <…

nginx反向代理服务器及负载均衡服务配置

一、正向代理与反向代理 正向代理&#xff1a;是一个位于客户端和原始服务器(oricin server)之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户…

南邮最优化期末复习

黄金分割法 单纯形法&#xff08;大M法&#xff09; 求min, σ找最小&#xff0c;终止条件全部大于0 θ找最小&#xff0c;且不能为负数求max, σ找最大&#xff0c;终止条件全部小于0 θ找最小&#xff0c;且不能为负数 例题 二阶段单纯形法想 分支定界法&#xff08;第二章&…

【单调队列】LeetCode1499:满足不等式的最大值

涉及知识点 单调队列 题目 给你一个数组 points 和一个整数 k 。数组中每个元素都表示二维平面上的点的坐标&#xff0c;并按照横坐标 x 的值从小到大排序。也就是说 points[i] [xi, yi] &#xff0c;并且在 1 < i < j < points.length 的前提下&#xff0c; xi &…

iMazing2024免费版iOS移动设备管理软件

以自己的方式管理iPhone&#xff0c;让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用&#xff0c;称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁&#xff1f;设备数…

leetcode——打家劫舍问题汇总

本章汇总一下leetcode中的打家劫舍问题&#xff0c;使用经典动态规划算法求解。 1、梦开始的地方——打家劫舍&#xff08;★&#xff09; 本题关键点就是不能在相邻房屋偷东西。 采用常规动态规划做法&#xff1a; 根据题意设定dp数组&#xff0c;dp[i]的含义为&#xff1a…

Typora Mac激活

首先去官网选择mac版本下载安装 typora下载 然后打开typora包内容找到 /Applications/Typora.app/Contents/Resources/TypeMark/page-dist 找到/static/js/Licen..如下图 编辑器打开上面文件夹 输入 hasActivated"true"e.hasActivated 进行搜索 将它改为 hasA…

人工智能:网络犯罪分子的驱动力

随着 2024 年的临近&#xff0c;是时候展望今年的网络安全状况了。由于网络犯罪日益复杂&#xff0c;预计到 2025 年&#xff0c;全球网络安全成本将增至 10.5 万亿美元。 人工智能的使用不断发展&#xff0c;网络犯罪分子变得越来越有创造力 我们注意到&#xff0c;联邦调查…

Dash中的callback的使用 多input 6

代码说明 import plotly.express as pxmport plotly.express as px用于导入plotly.express模块并给它起一个别名px。这样在后续的代码中&#xff0c;你可以使用px来代替plotly.express&#xff0c;使代码更加简洁。 plotly.express是Plotly的一个子模块&#xff0c;用于快速创…

路由器常见故障分析及处理方法!

对当前的大多数网络来说&#xff0c;无论是实现网络互连还是访问Internet&#xff0c;路由器是不可或缺的。 由于路由器的重要性&#xff0c;对它的管理就成了维护人员的日常工作中重要的一部分&#xff0c;而路由器的故障分析和排除也是令许多维护人员极为困扰的问题之一。 路…

jenkins Job华为云EIP变更带宽

引言: 在数字化时代&#xff0c;云服务资源的弹性管理是企业降低运营成本、提高效率的关键手段。通过弹性公网IP&#xff08;EIP&#xff09;服务&#xff0c;企业可以实现按需计费&#xff0c;优化网络支出。然而&#xff0c;根据业务流量的不同阶段调整计费模式&#xff0c;…

批量归一化

目录 一、BN层介绍 1、深层神经网络存在的问题 2、批量归一化的解决方案 3、BN层作用位置 4、BN层在做什么 5、总结 二、批量归一化从零实现 1、实现批量归一化操作 2、创建BN层 3、对LeNet加入批量归一化 4、开始训练 三、简明实现 1、对LeNet加入批量归一化 2…

【SD】IP-Adapter 进阶 - 垫图 【画风重绘-必看】

目录 关于SD1.5的画风迁移 修改动作-方法一&#xff1a;提示词 修改动作-方法二&#xff1a;openpose 关于SD1.5的画风迁移 1.5测试模型&#xff1a;flat2DAnimerge_v30_2.safetensors [b2c93e7a89] 测试图&#xff1a; 文生图&#xff1a;best quality,masterpiece, co…

20231225在WIN10下使用SSH连接Ubuntu20.04.6

20231225在WIN10下使用SSH连接Ubuntu20.04.6 2023/12/25 23:03 https://jingyan.baidu.com/article/5552ef479e1856108ffbc9e3.html Win10怎么开启SSH功能 Win10怎么开启SSH功能,下面就一起来看看吧! 工具/原料 华硕天选4 Windows10 方法/步骤 点击左下角的开始菜单,打开Wind…

Redis过期删除策略和内存淘汰策略

1、设置Redis键过期时间 Redis提供了四个命令来设置过期时间&#xff08;生存时间&#xff09;。 EXPIRE <key> <ttl> &#xff1a;表示将键 key 的生存时间设置为 ttl 秒。 PEXPIRE <key> <ttl> &#xff1a;表示将键 key 的生存时间设置为 ttl 毫秒。…

SICP : The Elements of Programming

好的计算机编程语言应具备的三个特性 基础单元表达式&#xff0c;计算机编程语言最最最基础单元&#xff0c;理应具备的表达式组合的能力&#xff0c;能够通过基础单元表达式组合成更复杂的元素抽象的能力&#xff0c;能通过复杂的元素抽象成更高层的单元 基础单元表达式 加 …

快速入门学习定时任务框架-xxljob

定时任务框架-xxljob 简介 主要用于分布式任务调度&#xff0c;可以将任务调度和执行分布在多个节点上。它提供了一个集中式的管理平台&#xff0c;支持动态添加、修改、删除任务&#xff0c;以及任务的分片执行&#xff0c;确保任务在分布式环境中的高可用性的一个框架 spr…

C语言中函数调用和嵌套

函数是C语言的基本组成元素 函数调用 根据函数在程序中出现的位置有下列三种函数调用方式&#xff1a; 将函数作为表达式调用 将函数作为表达式调用时&#xff0c;函数的返回值参与表达式的运算&#xff0c;此时要求函数必须有返回值 int retmax(100,150); 将函数作为语句…