1. 遗传算法
2. 粒子群优化
3. 模拟退火
运行与处理好的代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 设置中文字体(解决中文显示问题) plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows系统常用黑体字体 plt.rcParams['axes.unicode_minus'] = False # 正常显示负号 data = pd.read_csv('data.csv') #读取数据 #先筛选出字符串变量 discrete_data = data.select_dtypes(include=['object']).columns.tolist() #Home Ownership 标签编码 home_ownership_mapping = { 'Own Home': 1, 'Rent': 2 , 'Home Mortgage': 3, 'Have Mortgage': 4, } data['Home Ownership'] = data['Home Ownership'].map(home_ownership_mapping) #Years in current job 标签编码 years_in_current_job_mapping = { '< 1 year': 1 , '1 year': 2, '2 years': 3, '3 years': 4, '4 years': 5, '5 years': 6, '6 years': 7, '7 years': 8, '8 years': 9, '9 years': 10, '10+ years': 11, } data['Years in current job'] = data['Years in current job'].map(years_in_current_job_mapping) #Purpose 独热编码,记得将bool类型转换为int类型 data = pd.get_dummies(data, columns=['Purpose']) data2 = pd.read_csv('data.csv') #读取数据 list_final = [] for i in data.columns: if i not in data2.columns: list_final.append(i) for i in list_final: data[i] = data[i].astype(int) #Term 0-1编码 # Term 0 - 1 映射 term_mapping = { 'Short Term': 0, 'Long Term': 1 } data['Term'] = data['Term'].map(term_mapping) data.rename(columns={'Term': 'Long Term'}, inplace=True) # 重命名列 continuous_features = data.select_dtypes(include=['int64', 'float64']).columns.tolist() #把筛选出来的列名转换成列表 #连续特征用中位数补全 for feature in continuous_features: mode_value = data[feature].mode()[0] # 计算众数 data[feature].fillna(mode_value, inplace=True) # 使用众数填充缺失值 #训练集测试集划分 from sklearn.model_selection import train_test_split X = data.drop('Credit Default', axis=1) # 特征 y = data['Credit Default'] # 目标变量 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 划分训练集和测试集,测试集占20%
随机森林
start_time = time.time() # 记录开始时间
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train) # 在训练集上训练
rf_pred = rf_model.predict(X_test) # 在测试集上预测
end_time = time.time() # 记录结束时间
end_time - start_time:.4f
classification_report(y_test, rf_pred)
confusion_matrix(y_test, rf_pred)
from sklearn.ensemble import RandomForestClassifier #随机森林分类器 from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标 from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵 import warnings #用于忽略警告信息 warnings.filterwarnings("ignore") # 忽略所有警告信息 # --- 1. 默认参数的随机森林 --- # 评估基准模型,这里确实不需要验证集 print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---") import time # 这里介绍一个新的库,time库,主要用于时间相关的操作,因为调参需要很长时间,记录下会帮助后人知道大概的时长 start_time = time.time() # 记录开始时间 rf_model = RandomForestClassifier(random_state=42) rf_model.fit(X_train, y_train) # 在训练集上训练 rf_pred = rf_model.predict(X_test) # 在测试集上预测 end_time = time.time() # 记录结束时间 print(f"训练与预测耗时: {end_time - start_time:.4f} 秒") print("\n默认随机森林 在测试集上的分类报告:") print(classification_report(y_test, rf_pred)) print("默认随机森林 在测试集上的混淆矩阵:") print(confusion_matrix(y_test, rf_pred))
核心思想:
1. 这些启发式算法都是优化器。你的目标是找到一组超参数,让你的机器学习模型在某个指标(比如验证集准确率)上表现最好。
2. 这个过程就像在一个复杂的地形(参数空间)上寻找最高峰(最佳性能)。
3. 启发式算法就是一群聪明的“探险家”,它们用不同的策略(模仿自然、物理现象等)来寻找这个最高峰,而不需要知道地形每一处的精确梯度(导数)。
遗传算法
遗传算法 (Genetic Algorithm - GA)
- 灵感来源: 生物进化,达尔文的“适者生存”。
- 简单理解: 把不同的超参数组合想象成一群“个体”。表现好的个体(高验证分)更有机会“繁殖”(它们的参数组合会被借鉴和混合),并可能发生“变异”(参数随机小改动),产生下一代。表现差的个体逐渐被淘汰。一代代下去,种群整体就会越来越适应环境(找到更好的超参数)。
- 应用感觉: 像是在大范围“撒网”搜索,通过优胜劣汰和随机变动逐步逼近最优解。适合参数空间很大、很复杂的情况。
AI时代的工具很大的好处,就是找到了一个记忆工具来帮助我们记住这个方法需要的步骤,然后我们只需要调用这个工具,就可以完成这个任务。
1. 关注输入和输出的格式和数据
2. 关注方法的前生今世和各自的优势---优缺点和应用场景
3. 关注模型本身的实现逻辑(如果用的时候很少,可跳过,借助ai实现)
学习重心转移
- ❌ 传统方式:深究算法实现细节(如遗传算法的交叉/变异操作)
- ✅ AI时代方式:
- 输入输出规范 :明确需要什么样的数据格式,得到什么结果
- 方法特性认知 :了解不同优化算法(遗传/粒子群/模拟退火)的适用场景
- 工具化思维 :通过调用现成工具(如scikit-learn的 HalvingGridSearchCV )完成优化# 定义适应度函数和个体类型 creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax) ##……………… # 遗传算法参数 NGEN = 10 CXPB = 0.5 MUTPB = 0.2 # 运行遗传算法 for gen in range(NGEN): offspring = algorithms.varAnd(pop, toolbox, cxpb=CXPB, mutpb=MUTPB) fits = toolbox.map(toolbox.evaluate, offspring) for fit, ind in zip(fits, offspring): ind.fitness.values = fit pop = toolbox.select(offspring, k=len(pop)) # 找到最优个体 best_ind = tools.selBest(pop, k=1)[0] best_n_estimators, best_max_depth, best_min_samples_split, best_min_samples_leaf = best_ind print(f"遗传算法优化耗时: {end_time - start_time:.4f} 秒") print("最佳参数: ", { 'n_estimators': best_n_estimators, 'max_depth': best_max_depth, 'min_samples_split': best_min_samples_split, 'min_samples_leaf': best_min_samples_leaf })
## 粒子群方法
粒子群优化 (Particle Swarm Optimization - PSO)
- 灵感来源: 鸟群或鱼群觅食。
- 简单理解: 把每个超参数组合想象成一个“粒子”(鸟)。每个粒子在参数空间中“飞行”。它会记住自己飞过的最好位置,也会参考整个“鸟群”发现的最好位置,结合这两者来调整自己的飞行方向和速度,同时带点随机性。
- 应用感觉: 像是一群探险家,既有自己的探索记忆,也会互相交流信息(全局最佳位置),集体协作寻找目标。通常收敛比遗传算法快一些。
粒子群方法的思想比较简单,所以甚至可以不调库自己实现。
# 定义适应度函数,本质就是构建了一个函数实现 参数--> 评估指标的映射 ef fitness_function(params): n_estimators, max_depth, min_samples_split, min_samples_leaf = params # 序列解包,允许你将一个可迭代对象(如列表、元组、字符串等)中的元素依次赋值给多个变量。 model = RandomForestClassifier(n_estimators=int(n_estimators), max_depth=int(max_depth), min_samples_split=int(min_samples_split), min_samples_leaf=int(min_samples_leaf), random_state=42) model.fit(X_train, y_train) y_pred = model.predict(X_test) accuracy = accuracy_score(y_test, y_pred) return accuracy # 粒子群优化算法实现 def pso(num_particles, num_iterations, c1, c2, w, bounds): # 粒子群优化算法核心函数 # num_particles:粒子的数量,即算法中用于搜索最优解的个体数量。 # num_iterations:迭代次数,算法运行的最大循环次数。 # c1:认知学习因子,用于控制粒子向自身历史最佳位置移动的程度。 # c2:社会学习因子,用于控制粒子向全局最佳位置移动的程度。 # w:惯性权重,控制粒子的惯性,影响粒子在搜索空间中的移动速度和方向。 # bounds:超参数的取值范围,是一个包含多个元组的列表,每个元组表示一个超参数的最小值和最大值。 ####定义过程 # 超参数范围 bounds = [(50, 200), (10, 30), (2, 10), (1, 4)] # n_estimators, max_depth, min_samples_split, min_samples_leaf # 使用最佳参数的模型进行预测 best_model = RandomForestClassifier(n_estimators=int(best_params[0]), max_depth=int(best_params[1]), min_samples_split=int(best_params[2]), min_samples_leaf=int(best_params[3]), random_state=42) best_model.fit(X_train, y_train) best_pred = best_model.predict(X_test) print("\n粒子群优化算法优化后的随机森林 在测试集上的分类报告:") print(classification_report(y_test, best_pred)) print("粒子群优化算法优化后的随机森林 在测试集上的混淆矩阵:") print(confusion_matrix(y_test, best_pred))
## 退火算法
模拟退火 (Simulated Annealing - SA)
- 灵感来源: 金属冶炼中的退火过程(缓慢冷却使金属达到最低能量稳定态)。
- 简单理解: 从一个随机的超参数组合开始。随机尝试改变一点参数。如果新组合更好,就接受它。如果新组合更差,也有一定概率接受它(尤其是在“高温”/搜索早期)。这个接受坏解的概率会随着时间(“降温”)慢慢变小。
- 应用感觉: 像一个有点“冲动”的探险家,初期愿意尝试一些看起来不太好的路径(为了跳出局部最优的小山谷),后期则越来越“保守”,专注于在当前找到的好区域附近精细搜索。擅长避免陷入局部最优。
# 定义适应度函数 ………… # 模拟退火算法实现 def simulated_annealing(initial_solution, bounds, initial_temp, final_temp, alpha): current_solution = initial_solution current_fitness = fitness_function(current_solution) best_solution = current_solution best_fitness = current_fitness temp = initial_temp #实现