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

集成学习智慧:为什么Bagging(随机森林)和Boosting(XGBoost)效果那么好?

点击AladdinEdu,同学们用得起的【H卡】算力平台”,注册即送-H卡级别算力沉浸式云原生的集成开发环境80G大显存多卡并行按量弹性计费教育用户更享超低价


引言:三个臭皮匠,顶个诸葛亮

在机器学习的世界里,有一个令人着迷的现象:通过组合多个相对简单的模型,往往能够获得比单个复杂模型更好的性能。这就是集成学习(Ensemble Learning)的核心思想——“三个臭皮匠,顶个诸葛亮”。

集成学习如今已成为机器学习中最强大和最广泛使用的技术之一。从Kaggle竞赛的冠军方案到工业界的实际应用,集成学习方法特别是随机森林(Random Forest)和XGBoost等算法,几乎无处不在。但为什么这些方法如此有效?它们背后的数学原理是什么?如何正确使用和调优这些算法?

本文将深入探讨集成学习的理论基础,重点解析Bagging(如随机森林)和Boosting(如XGBoost)的工作原理,并通过详细的代码示例展示如何调优这些算法的核心参数。无论您是机器学习初学者还是经验丰富的数据科学家,相信本文都能为您提供有价值的见解。

一、集成学习基础与偏差-方差分解

1.1 集成学习概述

集成学习是一种通过构建并结合多个学习器来完成学习任务的方法。其基本思想是:即使每个基学习器只有略优于随机猜测的性能,通过适当的组合,集成学习器可以获得显著优于任何单个基学习器的性能。

集成学习主要分为两大类:

  1. Bagging(Bootstrap Aggregating):并行生成多个基学习器,通过投票或平均进行组合
  2. Boosting:顺序生成多个基学习器,每个后续学习器专注于修正前一个学习器的错误

1.2 偏差-方差分解

要理解集成学习为什么有效,我们首先需要了解偏差-方差分解(Bias-Variance Decomposition),这是解释模型泛化误差的重要框架。

对于回归问题,期望泛化误差可以分解为:
[
E[(y - \hat{f}(x))^2] = \text{Bias}^2[\hat{f}(x)] + \text{Var}[\hat{f}(x)] + \sigma^2
]

其中:

  • 偏差(Bias):模型预测值的期望与真实值的差异,衡量模型的拟合能力
  • 方差(Variance):模型预测值的变化范围,衡量模型的稳定性
  • 噪声(σ²):数据本身的随机噪声,不可减少

偏差-方差权衡:简单模型通常有高偏差低方差(欠拟合),复杂模型通常有低偏差高方差(过拟合)。集成学习通过组合多个模型,能够在保持低偏差的同时降低方差。

1.3 集成学习如何影响偏差和方差

不同的集成方法对偏差和方差的影响不同:

  • Bagging:主要降低方差,对偏差影响较小
  • Boosting:主要降低偏差,同时也能一定程度上降低方差

二、Bagging与随机森林

2.1 Bagging原理

Bagging(Bootstrap Aggregating)的基本思想是通过自助采样法(Bootstrap Sampling)生成多个训练子集,然后在每个子集上训练一个基学习器,最后通过投票(分类)或平均(回归)进行组合。

算法步骤

  1. 从训练集中随机抽取n个样本(有放回抽样),重复k次,得到k个自助采样集
  2. 在每个采样集上训练一个基学习器
  3. 对于分类问题,使用投票法组合预测结果;对于回归问题,使用平均法组合预测结果

数学表达
对于回归问题,Bagging的预测为:
[
\hat{f}{\text{bag}}(x) = \frac{1}{B} \sum{b=1}^{B} \hat{f}^{*b}(x)
]
其中B是基学习器数量,(\hat{f}^{*b})是在第b个自助样本上训练的模型。

2.2 随机森林机理分析

随机森林(Random Forest)是Bagging的扩展,它在Bagging的基础上引入了随机特征选择,进一步增加了基学习器的多样性。

随机森林的两个随机性

  1. 数据随机性:通过自助采样随机选择训练样本
  2. 特征随机性:在每个节点分裂时,随机选择部分特征进行考察

这种双重随机性使得随机森林具有很好的抗过拟合能力,并且能够估计特征重要性。

2.3 随机森林的数学机理

随机森林中每棵树的构建过程可以表示为:
对于每棵树t:

  1. 从原始数据中自助采样得到数据集D_t
  2. 从根节点开始,递归地执行以下操作直到满足停止条件:
    • 随机选择m个特征(m ≤ M,M为总特征数)
    • 找到最佳分裂特征和分裂点
    • 将节点分裂为两个子节点

最终预测为所有树的预测的平均值(回归)或众数(分类)。

2.4 随机森林核心参数调优

下面我们通过代码示例展示随机森林的核心参数调优:

import numpy as np
import pandas as pd
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt
import seaborn as sns# 创建示例数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, n_classes=2, random_state=42)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 基础随机森林模型
base_rf = RandomForestClassifier(random_state=42)
base_rf.fit(X_train, y_train)
y_pred_base = base_rf.predict(X_test)
base_accuracy = accuracy_score(y_test, y_pred_base)print(f"基础随机森林准确率: {base_accuracy:.4f}")# 参数网格
param_grid = {'n_estimators': [50, 100, 200],'max_depth': [None, 10, 20, 30],'min_samples_split': [2, 5, 10],'min_samples_leaf': [1, 2, 4],'max_features': ['auto', 'sqrt', 'log2']
}# 网格搜索
grid_search = GridSearchCV(RandomForestClassifier(random_state=42),param_grid,cv=5,scoring='accuracy',n_jobs=-1,verbose=1
)grid_search.fit(X_train, y_train)# 最佳参数和模型
best_params = grid_search.best_params_
best_rf = grid_search.best_estimator_
y_pred_best = best_rf.predict(X_test)
best_accuracy = accuracy_score(y_test, y_pred_best)print(f"最佳参数: {best_params}")
print(f"调优后准确率: {best_accuracy:.4f}")
print(f"提升: {best_accuracy - base_accuracy:.4f}")# 特征重要性可视化
feature_importance = best_rf.feature_importances_
feature_names = [f'Feature_{i}' for i in range(X.shape[1])]importance_df = pd.DataFrame({'feature': feature_names,'importance': feature_importance
}).sort_values('importance', ascending=False)plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=importance_df.head(10))
plt.title('Top 10 Feature Importance')
plt.tight_layout()
plt.show()# 学习曲线:n_estimators的影响
n_estimators_range = [10, 50, 100, 200, 300, 400, 500]
train_scores = []
test_scores = []for n in n_estimators_range:rf = RandomForestClassifier(n_estimators=n, random_state=42)rf.fit(X_train, y_train)train_score = rf.score(X_train, y_train)test_score = rf.score(X_test, y_test)train_scores.append(train_score)test_scores.append(test_score)plt.figure(figsize=(10, 6))
plt.plot(n_estimators_range, train_scores, label='Training score', marker='o')
plt.plot(n_estimators_range, test_scores, label='Testing score', marker='o')
plt.xlabel('Number of Trees')
plt.ylabel('Accuracy')
plt.title('Random Forest Learning Curve: n_estimators')
plt.legend()
plt.grid(True)
plt.show()

2.5 随机森林参数解读

  1. n_estimators:树的数量。增加树的数量会提高性能但增加计算成本,通常100-500之间
  2. max_depth:树的最大深度。控制模型复杂度,防止过拟合
  3. min_samples_split:内部节点再划分所需最小样本数。值越大越保守,防止过拟合
  4. min_samples_leaf:叶节点最少样本数。类似min_samples_split,控制叶节点粒度
  5. max_features:寻找最佳分割时考虑的特征数。通常设为’sqrt’或’log2’

三、Boosting与梯度提升树

3.1 Boosting原理

Boosting与Bagging有着根本不同的哲学。Boosting是顺序学习的,每个后续模型都试图修正前一个模型的错误。其核心思想是将多个弱学习器组合成一个强学习器。

Boosting的基本流程

  1. 从初始训练集训练一个基学习器
  2. 根据基学习器的表现调整样本权重(增加错误分类样本的权重)
  3. 基于调整后的样本权重训练下一个基学习器
  4. 重复步骤2-3多次
  5. 将多个基学习器加权组合

3.2 梯度提升树(GBDT)机理分析

梯度提升树(Gradient Boosting Decision Tree)是Boosting家族中最著名的算法之一。它通过梯度下降的方式逐步改进模型。

GBDT的数学推导

GBDT使用加法模型:
[
F_m(x) = F_{m-1}(x) + \gamma_m h_m(x)
]
其中(F_{m-1}(x))是当前模型,(h_m(x))是新加的弱学习器,(\gamma_m)是步长。

在每一步,我们选择(h_m)来最小化损失函数L:
[
h_m = \arg\min_{h} \sum_{i=1}^{n} L(y_i, F_{m-1}(x_i) + h(x_i))
]

对于平方损失函数,这等价于拟合残差(y_i - F_{m-1}(x_i))。

3.3 XGBoost算法深度解析

XGBoost(eXtreme Gradient Boosting)是GBDT的高效实现,添加了许多优化:

  1. 正则化:在目标函数中添加L1和L2正则化项
  2. 二阶泰勒展开:使用损失函数的二阶导数信息
  3. 并行处理:特征排序和分桶的并行化
  4. 缺失值处理:自动学习缺失值的分裂方向
  5. 剪枝策略:基于最大深度优先而不是GBDT的深度优先

XGBoost目标函数
[
\text{Obj}^{(t)} = \sum_{i=1}^{n} L(y_i, \hat{y}i^{(t-1)} + f_t(x_i)) + \Omega(f_t) + \text{constant}
]
其中(\Omega(f_t) = \gamma T + \frac{1}{2}\lambda \sum
{j=1}^{T} w_j^2)是正则化项。

3.4 XGBoost核心参数调优

下面我们通过代码示例展示XGBoost的核心参数调优:

import xgboost as xgb
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
import time# 创建DMatrix格式数据(XGBoost高效数据格式)
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)# 基础XGBoost模型
params_base = {'objective': 'binary:logistic','eval_metric': 'logloss','random_state': 42
}base_xgb = xgb.train(params_base, dtrain, num_boost_round=100)
y_pred_proba = base_xgb.predict(dtest)
y_pred_xgb_base = (y_pred_proba > 0.5).astype(int)
base_accuracy_xgb = accuracy_score(y_test, y_pred_xgb_base)print(f"基础XGBoost准确率: {base_accuracy_xgb:.4f}")# 使用sklearn API进行参数调优
xgb_clf = xgb.XGBClassifier(objective='binary:logistic',random_state=42,n_jobs=-1
)# 参数网格
param_grid_xgb = {'n_estimators': [100, 200, 300],'max_depth': [3, 6, 9],'learning_rate': [0.01, 0.1, 0.2],'subsample': [0.8, 0.9, 1.0],'colsample_bytree': [0.8, 0.9, 1.0],'gamma': [0, 0.1, 0.2]
}# 网格搜索
grid_search_xgb = GridSearchCV(estimator=xgb_clf,param_grid=param_grid_xgb,scoring='accuracy',cv=5,n_jobs=-1,verbose=1
)start_time = time.time()
grid_search_xgb.fit(X_train, y_train)
end_time = time.time()print(f"网格搜索耗时: {end_time - start_time:.2f}秒")# 最佳参数和模型
best_params_xgb = grid_search_xgb.best_params_
best_xgb = grid_search_xgb.best_estimator_
y_pred_best_xgb = best_xgb.predict(X_test)
best_accuracy_xgb = accuracy_score(y_test, y_pred_best_xgb)print(f"最佳参数: {best_params_xgb}")
print(f"调优后XGBoost准确率: {best_accuracy_xgb:.4f}")
print(f"提升: {best_accuracy_xgb - base_accuracy_xgb:.4f}")# 学习曲线:learning_rate的影响
learning_rates = [0.001, 0.01, 0.05, 0.1, 0.2, 0.3]
train_scores_xgb = []
test_scores_xgb = []for lr in learning_rates:model = xgb.XGBClassifier(learning_rate=lr,n_estimators=100,random_state=42)model.fit(X_train, y_train)train_score = model.score(X_train, y_train)test_score = model.score(X_test, y_test)train_scores_xgb.append(train_score)test_scores_xgb.append(test_score)plt.figure(figsize=(10, 6))
plt.plot(learning_rates, train_scores_xgb, label='Training score', marker='o')
plt.plot(learning_rates, test_scores_xgb, label='Testing score', marker='o')
plt.xscale('log')
plt.xlabel('Learning Rate')
plt.ylabel('Accuracy')
plt.title('XGBoost Learning Curve: Learning Rate')
plt.legend()
plt.grid(True)
plt.show()# 特征重要性可视化
plt.figure(figsize=(10, 6))
xgb.plot_importance(best_xgb, max_num_features=10)
plt.title('XGBoost Feature Importance')
plt.tight_layout()
plt.show()# 绘制决策树(第一棵树)
plt.figure(figsize=(20, 10))
xgb.plot_tree(best_xgb, num_trees=0)
plt.title('XGBoost Decision Tree (First Tree)')
plt.show()

3.5 XGBoost参数解读

  1. learning_rate:学习率/步长。控制每个弱学习器的贡献程度,通常0.01-0.3
  2. n_estimators:树的数量。与learning_rate共同决定模型复杂度
  3. max_depth:树的最大深度。控制模型复杂度,防止过拟合
  4. subsample:样本采样比例。小于1时实现随机梯度提升
  5. colsample_bytree:特征采样比例。类似随机森林的特征随机性
  6. gamma:分裂所需最小损失减少量。值越大越保守
  7. reg_lambda:L2正则化项。控制模型复杂度
  8. reg_alpha:L1正则化项。产生稀疏模型

四、Bagging vs Boosting:全面对比

4.1 算法特性对比

特性Bagging(随机森林)Boosting(XGBoost)
学习方式并行顺序
基学习器关系相互独立相互依赖
目标降低方差降低偏差
过拟合倾向较不容易过拟合容易过拟合(需正则化)
数据权重等权重错误样本权重增加
并行化容易较难(但XGBoost优化了)
训练速度较快(可并行)较慢(顺序)
噪声敏感度不敏感敏感

4.2 适用场景对比

随机森林更适合

  • 需要快速原型开发
  • 数据噪声较多
  • 需要特征重要性评估
  • 希望减少过拟合风险

XGBoost更适合

  • 追求最高预测精度
  • 有足够计算资源
  • 需要处理复杂非线性关系
  • 参加数据科学竞赛

4.3 性能对比实验

让我们在同一数据集上对比两种算法的性能:

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
from sklearn.model_selection import cross_val_score
import numpy as np# 加载真实数据集
data = load_breast_cancer()
X, y = data.data, data.target# 随机森林性能
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf_scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')# XGBoost性能
xgb_clf = XGBClassifier(n_estimators=100, random_state=42)
xgb_scores = cross_val_score(xgb_clf, X, y, cv=5, scoring='accuracy')print("随机森林交叉验证准确率:")
print(f"各折分数: {rf_scores}")
print(f"平均分数: {rf_scores.mean():.4f}{rf_scores.std():.4f})")print("\nXGBoost交叉验证准确率:")
print(f"各折分数: {xgb_scores}")
print(f"平均分数: {xgb_scores.mean():.4f}{xgb_scores.std():.4f})")# 绘制对比图
models = ['Random Forest', 'XGBoost']
means = [rf_scores.mean(), xgb_scores.mean()]
stds = [rf_scores.std(), xgb_scores.std()]plt.figure(figsize=(8, 6))
plt.bar(models, means, yerr=stds, capsize=10, alpha=0.7)
plt.ylabel('Accuracy')
plt.title('Random Forest vs XGBoost Performance Comparison')
plt.grid(True, axis='y')
plt.show()# 训练时间对比
import timerf_time = []
xgb_time = []for _ in range(5):# 随机森林训练时间start = time.time()rf.fit(X, y)end = time.time()rf_time.append(end - start)# XGBoost训练时间start = time.time()xgb_clf.fit(X, y)end = time.time()xgb_time.append(end - start)print(f"\n训练时间对比:")
print(f"随机森林平均训练时间: {np.mean(rf_time):.4f}秒")
print(f"XGBoost平均训练时间: {np.mean(xgb_time):.4f}秒")

五、高级技巧与最佳实践

5.1 集成学习的集成:Stacking和Blending

除了Bagging和Boosting,还有更高级的集成方法:

Stacking

  1. 首先用多个基学习器对训练集进行预测
  2. 将预测结果作为新特征,训练一个元学习器进行最终预测

Blending
与Stacking类似,但使用保留的验证集生成元特征

from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC# 创建Stacking集成
estimators = [('rf', RandomForestClassifier(n_estimators=100, random_state=42)),('xgb', XGBClassifier(n_estimators=100, random_state=42)),('svm', SVC(probability=True, random_state=42))
]stacking_clf = StackingClassifier(estimators=estimators,final_estimator=LogisticRegression(),cv=5
)stacking_scores = cross_val_score(stacking_clf, X, y, cv=5, scoring='accuracy')
print(f"Stacking集成准确率: {stacking_scores.mean():.4f}{stacking_scores.std():.4f})")

5.2 类别不平衡处理

集成学习在处理类别不平衡数据时需要注意:

from sklearn.utils import class_weight# 计算类别权重
classes_weights = class_weight.compute_sample_weight(class_weight='balanced',y=y_train
)# 使用类别权重的随机森林
rf_balanced = RandomForestClassifier(n_estimators=100,class_weight='balanced',random_state=42
)# 使用scale_pos_weight的XGBoost
xgb_balanced = XGBClassifier(n_estimators=100,scale_pos_weight=np.sum(y == 0) / np.sum(y == 1),  # 负样本数/正样本数random_state=42
)

5.3 提前停止(Early Stopping)

对于Boosting算法,使用提前停止防止过拟合:

# XGBoost提前停止
xgb_early = XGBClassifier(n_estimators=1000,  # 设置较大的n_estimatorsearly_stopping_rounds=50,learning_rate=0.1,random_state=42
)# 需要划分验证集
X_train_part, X_val, y_train_part, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42
)xgb_early.fit(X_train_part, y_train_part,eval_set=[(X_val, y_val)],verbose=False
)print(f"实际使用的树的数量: {len(xgb_early.get_booster().get_dump())}")

5.4 模型解释性

集成学习模型虽然强大,但往往被认为是黑盒。以下方法可以提高模型可解释性:

  1. 特征重要性:随机森林和XGBoost都提供特征重要性评估
  2. SHAP值:统一解释模型预测的方法
  3. 部分依赖图:显示特征对预测的边际效应
import shap# 使用SHAP解释XGBoost模型
explainer = shap.TreeExplainer(best_xgb)
shap_values = explainer.shap_values(X_test)# 摘要图
shap.summary_plot(shap_values, X_test, feature_names=data.feature_names)# 单个预测解释
shap.force_plot(explainer.expected_value, shap_values[0,:], X_test[0,:], feature_names=data.feature_names)

六、实际应用案例

6.1 金融风控中的集成学习应用

在金融风控中,随机森林和XGBoost被广泛用于欺诈检测、信用评分等任务:

# 模拟金融风控数据
def create_financial_data():from sklearn.datasets import make_classificationX, y = make_classification(n_samples=10000,n_features=30,n_informative=20,n_redundant=5,n_clusters_per_class=2,weights=[0.95, 0.05],  # 5%的欺诈案例random_state=42)return X, yX_fin, y_fin = create_financial_data()# 由于类别不平衡,使用合适的评估指标
from sklearn.metrics import confusion_matrix, classification_report, roc_auc_score# 随机森林处理不平衡数据
rf_fin = RandomForestClassifier(n_estimators=200,class_weight='balanced',random_state=42
)rf_fin.fit(X_train, y_train)
y_pred_rf_fin = rf_fin.predict(X_test)print("随机森林金融风控性能:")
print(confusion_matrix(y_test, y_pred_rf_fin))
print(classification_report(y_test, y_pred_rf_fin))
print(f"ROC-AUC: {roc_auc_score(y_test, rf_fin.predict_proba(X_test)[:, 1]):.4f}")# XGBoost处理不平衡数据
xgb_fin = XGBClassifier(n_estimators=200,scale_pos_weight=19,  # 负样本数/正样本数 = 95%/5% = 19random_state=42
)xgb_fin.fit(X_train, y_train)
y_pred_xgb_fin = xgb_fin.predict(X_test)print("\nXGBoost金融风控性能:")
print(confusion_matrix(y_test, y_pred_xgb_fin))
print(classification_report(y_test, y_pred_xgb_fin))
print(f"ROC-AUC: {roc_auc_score(y_test, xgb_fin.predict_proba(X_test)[:, 1]):.4f}")

6.2 医疗诊断中的集成学习应用

在医疗领域,集成学习用于疾病诊断、预后预测等:

# 模拟医疗数据
def create_medical_data():from sklearn.datasets import make_classificationX, y = make_classification(n_samples=5000,n_features=25,n_informative=15,n_redundant=5,n_classes=2,random_state=42)return X, yX_med, y_med = create_medical_data()# 在医疗领域,我们通常更关注召回率(减少漏诊)
from sklearn.metrics import recall_score# 使用侧重召回率的参数调优
param_grid_medical = {'n_estimators': [100, 200],'max_depth': [3, 6, 9],'min_samples_split': [2, 5],'min_samples_leaf': [1, 2]
}grid_search_medical = GridSearchCV(RandomForestClassifier(random_state=42),param_grid_medical,scoring='recall',  # 使用召回率作为评估指标cv=5,n_jobs=-1
)grid_search_medical.fit(X_med, y_med)print(f"最佳参数: {grid_search_medical.best_params_}")
print(f"最佳召回率: {grid_search_medical.best_score_:.4f}")

七、总结与展望

7.1 关键要点总结

通过本文的深入探讨,我们可以得出以下关键结论:

  1. 集成学习之所以有效,是因为它通过组合多个模型来平衡偏差-方差权衡
  2. Bagging(如随机森林) 主要降低方差,通过自助采样和特征随机性增加模型多样性
  3. Boosting(如XGBoost) 主要降低偏差,通过顺序学习不断修正前序模型的错误
  4. 参数调优至关重要,不同的参数设置会显著影响模型性能
  5. 没有一种算法适用于所有场景,需要根据具体问题选择合适的算法

7.2 实用建议

对于实践中的集成学习应用,建议:

  1. 从小开始:先从简单的随机森林开始,再尝试更复杂的XGBoost
  2. 理解参数:深入理解每个参数的含义和影响,而不是盲目调参
  3. 关注评估指标:选择与业务目标一致的评估指标
  4. 考虑计算成本:在模型性能和计算资源之间找到平衡
  5. 模型解释:使用特征重要性、SHAP值等工具解释模型预测

7.3 未来发展方向

集成学习领域仍在快速发展,未来方向包括:

  1. 自动化机器学习:自动选择算法、调参和特征工程
  2. 可解释AI:提高集成学习模型的可解释性和透明度
  3. 在线学习:开发能够适应数据变化的在线集成学习算法
  4. 深度学习集成:将集成学习与深度学习相结合
  5. 联邦集成学习:在保护隐私的前提下进行分布式集成学习

集成学习作为机器学习中最强大和实用的技术之一,无论是在学术研究还是工业应用中都发挥着重要作用。通过深入理解其原理和掌握实践技巧,我们能够构建出更加精准和鲁棒的机器学习模型,解决现实世界中的复杂问题。

希望本文为您提供了对集成学习全面而深入的理解,无论是理论基础还是实践技巧,都能在您的机器学习项目中发挥价值。


点击AladdinEdu,同学们用得起的【H卡】算力平台”,注册即送-H卡级别算力沉浸式云原生的集成开发环境80G大显存多卡并行按量弹性计费教育用户更享超低价

http://www.dtcms.com/a/393312.html

相关文章:

  • 计算机英语缩写
  • 国轩高科校招社招网申线上测评笔试题库结构说明书(适用于研发/工程/职能全部岗位)
  • 3.2.10 虚拟内存管理 (答案见原书 P238)
  • 算法 --- BFS 解决最短路问题
  • Photoshop蒙版的操作
  • cocos shader敌人受到攻击改变颜色
  • cd论文精读
  • USBD_malloc 禁止替换成 malloc 函数
  • 功能测试与测试用例设计方法详解
  • AXI DMA
  • 1:1复刻真实场景,机器人训练不再“纸上谈兵”
  • CMake快速上手:编译、构建与变量管理(包含示例)
  • vscode配置C/C++教程(含常见问题)
  • F021 五种推荐算法之美食外卖推荐可视化系统vue+flask
  • C++学习记录(10)模板进阶
  • cesium案例:三维钢铁厂园区开发平台(附源码下载)
  • 电商开放平台API接口对比爬虫的优势有哪些?
  • SpringDoc-OpenApi 现代化 API 文档生成工具介绍+使用
  • 打造现象级H5答题游戏:《终极主题答题冒险》开源项目详解
  • 实验1.2呼吸灯实验指导书
  • 实验1.3通过for循环精确定时呼吸灯
  • 【c++】多态(一)
  • 01、Python从入门到癫狂:基础
  • uniapp 弹窗
  • 17.2 《16小时→2.3小时!多模态AI颠覆PPT制作:跨国企业实战验证》
  • MyBatis 从入门到实战:环境搭建与核心原理详解
  • 深入剖析陌讯AIGC检测算法:Transformer架构在AIGC识别中的技术创新
  • 【Ai智能客服上篇】
  • 《C++程序设计》笔记p3
  • 华为数字化转型战略框架:从“1套方法+4类场景+3个平台”的全景设计