当前位置:网站首页 >  教程

从零用Python实现粒子群算法优化XGBoost分类模型超参数

时间:2026年06月14日 09:34:09 来源:易频IT社区
一、前期环境准备 1.1 安装依赖库 打开终端(Windows用PowerShell/CMD,Mac/Linux用Terminal),复制粘贴以下命令并回车执行: ```bash pip install numpy scikit-learn xgboost joblib ``` 依赖说明: - numpy:负责基础数值计算 - scikit-learn:提供数据集、评估指标 - xgboost:待优化的分类模型 - joblib:保存/加载优化后的模型 1.2 验证环境 创建Python文件`verify_env.py`,粘贴以下代码并运行,无报错即成功: ```python import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split import xgboost as xgb print("依赖库安装成功") ``` 二、数据集准备 使用scikit-learn自带的鸢尾花分类数据集,无需额外下载。创建文件`prepare_data.py`,内容如下: ```python from sklearn import datasets from sklearn.model_selection import train_test_split 加载鸢尾花数据集 iris = datasets.load_iris() X = iris.data 特征:萼片/花瓣的长宽 y = iris.target 标签:0/1/2代表3种鸢尾花 按8:2划分训练集和测试集,固定随机数种子保证结果可复现 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) stratify=y确保训练/测试集中各类别比例一致 ``` 三、实现基础粒子群算法(PSO) PSO的核心逻辑是:每个“粒子”代表一组超参数,粒子群在参数空间里移动,根据“自身历史最优位置”和“全局历史最优位置”调整移动方向。 创建文件`pso_optimizer.py`,完整代码如下: ```python import numpy as np import xgboost as xgb from sklearn.metrics import accuracy_score from joblib import parallel_backend class PSOXGBOptimizer: def __init__( self, X_train, y_train, X_test, y_test, n_particles=20, 粒子数量,建议10-30 max_iter=50, 最大迭代次数,建议30-100 w=0.7, 惯性权重,控制历史速度影响 c1=1.5, 自我认知系数 c2=1.5 社会认知系数 ): 数据初始化 self.X_train = X_train self.y_train = y_train self.X_test = X_test self.y_test = y_test PSO参数初始化 self.n_particles = n_particles self.max_iter = max_iter self.w = w self.c1 = c1 self.c2 = c2 超参数搜索空间:键是参数名,值是(最小值, 最大值, 数据类型) self.param_bounds = { "n_estimators": (50, 300, int), 树的数量 "max_depth": (3, 10, int), 树的最大深度 "learning_rate": (0.01, 0.3, float), 学习率 "subsample": (0.5, 1.0, float), 训练每棵树的样本采样比例 "colsample_bytree": (0.5, 1.0, float) 训练每棵树的特征采样比例 } 初始化粒子群位置和速度 self.n_params = len(self.param_bounds) self.particles = self._init_particles() self.velocities = np.random.uniform(-1, 1, (self.n_particles, self.n_params)) 初始化最优位置和最优分数 self.pbest_positions = self.particles.copy() self.pbest_scores = np.array([self._evaluate(p) for p in self.particles]) self.gbest_idx = np.argmax(self.pbest_scores) self.gbest_position = self.pbest_positions[self.gbest_idx].copy() self.gbest_score = self.pbest_scores[self.gbest_idx] def _init_particles(self): """随机生成粒子群的初始位置(符合搜索空间的数据类型)""" particles = np.zeros((self.n_particles, self.n_params)) for i, (key, (min_val, max_val, dtype)) in enumerate(self.param_bounds.items()): if dtype == int: particles[:, i] = np.random.randint(min_val, max_val+1, self.n_particles) elif dtype == float: particles[:, i] = np.random.uniform(min_val, max_val, self.n_particles) return particles def _clip_particle(self, particle): """将粒子的位置限制在搜索空间内,并转换为对应数据类型""" clipped = [] for i, (key, (min_val, max_val, dtype)) in enumerate(self.param_bounds.items()): val = particle[i] 限制范围 val = max(min_val, min(max_val, val)) 转换类型 if dtype == int: val = int(round(val)) clipped.append(val) return np.array(clipped) def _evaluate(self, particle): """评估单个粒子(一组超参数)的测试集准确率""" 将粒子位置转换为XGBoost参数字典 params = dict(zip(self.param_bounds.keys(), particle)) 补充XGBoost分类器的固定参数 params.update({ "objective": "multi:softmax", 多分类目标函数 "num_class": 3, 鸢尾花有3类 "random_state": 42, 固定随机数 "n_jobs": -1 用全部CPU核心训练 }) 训练模型 model = xgb.XGBClassifier(params) model.fit(self.X_train, self.y_train) 预测并计算准确率 y_pred = model.predict(self.X_test) return accuracy_score(self.y_test, y_pred) def optimize(self): """执行PSO优化流程""" for iter in range(self.max_iter): 打印当前迭代信息 print(f"Iteration {iter+1}/{self.max_iter}, Current Best Accuracy: {self.gbest_score:.4f}") 更新每个粒子的速度和位置 for i in range(self.n_particles): 计算随机因子 r1 = np.random.random(self.n_params) r2 = np.random.random(self.n_params) 更新速度 self.velocities[i] = ( self.w self.velocities[i] + self.c1 r1 (self.pbest_positions[i] - self.particles[i]) + self.c2 r2 (self.gbest_position - self.particles[i]) ) 更新位置并裁剪 self.particles[i] = self._clip_particle(self.particles[i] + self.velocities[i]) 评估新位置 current_score = self._evaluate(self.particles[i]) 更新自身最优 if current_score > self.pbest_scores[i]: self.pbest_positions[i] = self.particles[i].copy() self.pbest_scores[i] = current_score 更新全局最优 if current_score > self.gbest_score: self.gbest_position = self.particles[i].copy() self.gbest_score = current_score 优化结束,返回最优参数和最优分数 best_params = dict(zip(self.param_bounds.keys(), self.gbest_position)) return best_params, self.gbest_score ``` 四、执行超参数优化并验证 创建主文件`main.py`,内容如下,可直接运行: ```python from prepare_data import X_train, X_test, y_train, y_test from pso_optimizer import PSOXGBOptimizer import xgboost as xgb from joblib import dump 1. 初始化PSO优化器 optimizer = PSOXGBOptimizer( X_train, y_train, X_test, y_test, n_particles=15, max_iter=30 ) 2. 执行优化 best_params, best_score = optimizer.optimize() print("\n=== 优化完成 ===") print(f"最优超参数:{best_params}") print(f"最优测试集准确率:{best_score:.4f}") 3. 用最优参数重新训练完整模型(可选) full_model = xgb.XGBClassifier( best_params, objective="multi:softmax", num_class=3, random_state=42, n_jobs=-1 ) full_model.fit(X_train, y_train) 4. 保存模型 dump(full_model, "optimized_xgb_iris.joblib") print("优化后的模型已保存为 optimized_xgb_iris.joblib") ``` 五、常见问题排查 1. 依赖安装失败:如果使用pip安装报错,可尝试使用国内镜像源,替换命令为: ```bash pip install numpy scikit-learn xgboost joblib -i https://pypi.tuna.tsinghua.edu.cn/simple ``` 2. 准确率波动大:检查是否在`train_test_split`、PSO类初始化、XGBoost初始化中都设置了`random_state=42` 3. 优化速度慢:适当减少`n_particles`或`max_iter`,或确保`n_jobs=-1`已生效 六、扩展提示 如果需要优化其他模型(如LightGBM、SVM),只需修改`_evaluate`方法中的模型类和固定参数;如果需要调整超参数搜索空间,只需修改`param_bounds`字典的内容。

相关推荐

最新

热门

推荐

精选

标签

易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。

Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图