day11常见的调参方式@浙大疏锦行

超参数调整专题1

知识点回顾

​ 1. 网格搜索

​ 2. 随机搜索----基于采样的思想,大幅减少搜索的点

​ 3. 贝叶斯优化-----基于代理模型的思想,用简单的模型(高斯回归、决策树、神经网络)来替代复杂且计算成本高的模型,实现形式多样(sklearn、贝叶斯优化库、optuna)

​ 4. time库的计时模块,方便后人查看代码运行时长

5. 代理模型的思想

​ 6. 如何给AI提问?----最小mvp法则

补充知识:

​ 1. 贝叶斯优化的思想

引入一个平替的模型来替代计算成本过高的原模型,优先考虑可以可以拟合万能公式的模型(神经网络 高斯回归 决策树) ,这个平替的模型称之为代理模型

这里平替模型的思想可以理解为训练成本更低的模型,类比做实验的话,有的仪器运行一次成本很贵,可以找到一个更加简单的仪器或者干脆直接找到一个数学模型,在这个成本更低的模型上进行实验即可;而神经网络、高斯回归、决策树等方法就是这个成本更低的模型,当然了,这次学习用到的机器学习的模型本身就很简单

超参数搜索的过程可以理解为 g(超参数)=结果,让代理模型来学习到这个关系(课上我说的是学习原模型,口误说错了),这个模型g(超参数)其实是已知的,但是计算成本太高。

贝叶斯的关键步骤

​ 1. 初始化n个点,得到n组(超参数,结果)

​ 2. 代入这n组结果到代理模型中,开始连线

​ 3. 利用采集函数(类似于蒙特卡洛算法)的思想来找到线型的概率分布

​ 4. 对决定最不确定的线型的超参数进行带入原函数求解新的m组点

​ 5. 迭代这个过程,不断让代理函数接近g(x),直到达到设置的最大迭代值

这些所谓的模型,我的理解就是一个映射,比如如今的chatgpt训练一次时间非常长,但理论上来说,就算参数再多也不存在遍历不完的情况,所以只要给定所有参数的输入,那么它的输出就是确定的;而模型训练就是利用现有的数据(并非包括了所有可能性)去学习这个输入->输出的规则,也就是一个映射规则。那么现存的优化方法,就可以再一次缩短模型训练的时间,例如可以利用一些成熟的数学模型来简化这个过程,上面提到的神经网络等我目前不太了解,但貌似也是干这个的。

基线模型

KNN

# --- 2. 特征缩放 (仅用于 KNN) ---
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

print("--- 数据集规模 ---")
print(f"训练集 (80%): {len(X_train)} 样本")
print(f"测试集 (20%): {len(X_test)} 样本")
print("--------------------")

image-20251111203205937

print("\n--- KNN 基线模型 ---")

# 1. 创建 KNN 模型 (使用默认参数: n_neighbors=5, weights='uniform', p=2/欧氏距离)
knn_baseline = KNeighborsClassifier() 

# 2. 训练模型 (使用缩放后的训练集)
knn_baseline.fit(X_train_scaled, y_train)

# 3. 在测试集上进行预测 (使用缩放后的测试集)
y_pred_knn = knn_baseline.predict(X_test_scaled)

# 4. 评估模型
accuracy_knn = accuracy_score(y_test, y_pred_knn)
print(f"KNN 默认参数 (K=5) 模型在测试集上的准确率: {accuracy_knn:.4f}")

image-20251111203234096

LightGBM

# =================================================================
# --- 3. LightGBM 基线模型 (默认参数) ---
# =================================================================
print("\n--- LightGBM 基线模型 ---")
RANDOM_STATE = 42

# 1. 创建 LightGBM 模型 (使用默认参数)
# 注意: LightGBMClassifier 默认参数通常很合理,例如 n_estimators=100, learning_rate=0.1
lgbm_baseline = lgb.LGBMClassifier(random_state=RANDOM_STATE) 

# 2. 训练模型 (使用未缩放的训练集)
lgbm_baseline.fit(X_train, y_train)

# 3. 在测试集上进行预测
y_pred_lgbm = lgbm_baseline.predict(X_test)

# 4. 评估模型
accuracy_lgbm = accuracy_score(y_test, y_pred_lgbm)
print(f"LightGBM 默认参数模型在测试集上的准确率: {accuracy_lgbm:.4f}")

image-20251111203255914


网格搜索

KNN

import time
import lightgbm as lgb
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.preprocessing import StandardScaler
# =================================================================
# --- 4. KNN 网格搜索 (GridSearchCV) ---
# =================================================================
print("\n--- 4. KNN 网格搜索 ---")

# 定义 KNN 的参数网格
param_grid_knn = {
    'n_neighbors': [1, 3, 5, 7, 9, 11], # 搜索 K 值
    'weights': ['uniform', 'distance'], # 权重模式
    'p': [1, 2] # 距离度量 (1: 曼哈顿距离, 2: 欧氏距离)
}

# 创建 GridSearchCV 对象
# 注意:KNN 模型不需要设置 random_state
grid_search_knn = GridSearchCV(
    estimator=KNeighborsClassifier(),
    param_grid=param_grid_knn,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

start_time = time.time()
# 在缩放后的训练集上进行网格搜索
grid_search_knn.fit(X_train_scaled, y_train)
end_time = time.time()

print(f"KNN 网格搜索耗时: {end_time - start_time:.4f} 秒")
print("KNN 最佳参数: ", grid_search_knn.best_params_)
print("KNN 最佳交叉验证准确率: ", grid_search_knn.best_score_ if grid_search_knn.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行最终预测和评估
best_model_knn = grid_search_knn.best_estimator_
best_pred_knn = best_model_knn.predict(X_test_scaled)

print("\nKNN 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_knn))
print("KNN 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_knn))

image-20251111203450505

LightGBM网格搜索

# =================================================================
# --- 3. LightGBM 网格搜索 (GridSearchCV) ---
# =================================================================
print("\n--- 3. LightGBM 网格搜索 ---")

# 定义 LightGBM 的参数网格 (相对较小的范围以节省时间)
param_grid_lgbm = {
    'n_estimators': [100, 200, 300],
    'learning_rate': [0.05, 0.1, 0.2],
    'num_leaves': [15, 31, 45]
}

# 创建 GridSearchCV 对象
grid_search_lgbm = GridSearchCV(
    estimator=lgb.LGBMClassifier(random_state=RANDOM_STATE, verbose=-1, n_jobs=-1),
    param_grid=param_grid_lgbm,
    cv=5,               # 5折交叉验证
    scoring='accuracy',
    n_jobs=-1           # 使用所有核心进行并行计算
)

start_time = time.time()
# 在训练集上进行网格搜索
grid_search_lgbm.fit(X_train, y_train)
end_time = time.time()

print(f"LightGBM 网格搜索耗时: {end_time - start_time:.4f} 秒")
print("LightGBM 最佳参数: ", grid_search_lgbm.best_params_)
print("LightGBM 最佳交叉验证准确率: ", grid_search_lgbm.best_score_ if grid_search_lgbm.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行最终预测和评估
best_model_lgbm = grid_search_lgbm.best_estimator_
best_pred_lgbm = best_model_lgbm.predict(X_test)

print("\nLightGBM 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_lgbm))
print("LightGBM 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_lgbm))

image-20251111203517465


随机搜索

KNN

import time
import lightgbm as lgb
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.preprocessing import StandardScaler
from scipy.stats import randint, uniform, loguniform
import numpy as np
# =================================================================
# --- 4. KNN 随机搜索 (RandomizedSearchCV) ---
# =================================================================
print("\n--- 4. KNN 随机搜索 ---")

# 定义 KNN 的参数分布空间
param_dist_knn = {
    'n_neighbors': randint(low=1, high=20), # 1到20之间随机整数
    'weights': ['uniform', 'distance'],     # 离散值
    'p': [1, 2]                             # 离散值 (1: 曼哈顿距离, 2: 欧氏距离)
}

# 创建 RandomizedSearchCV 对象
random_search_knn = RandomizedSearchCV(
    estimator=KNeighborsClassifier(),
    param_distributions=param_dist_knn,
    n_iter=15, # KNN参数较少,减少迭代次数
    cv=5,
    scoring='accuracy',
    random_state=RANDOM_STATE,
    n_jobs=-1
)

start_time = time.time()
# 在缩放后的训练集上进行随机搜索
random_search_knn.fit(X_train_scaled, y_train)
end_time = time.time()

print(f"KNN 随机搜索耗时: {end_time - start_time:.4f} 秒")
print("KNN 最佳参数: ", random_search_knn.best_params_)
print("KNN 最佳交叉验证准确率: ", random_search_knn.best_score_ if random_search_knn.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行最终预测和评估
best_model_knn = random_search_knn.best_estimator_
best_pred_knn = best_model_knn.predict(X_test_scaled)

print("\nKNN 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_knn))
print("KNN 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_knn))

image-20251111203616867

LightGBM随机搜索

# =================================================================
# --- 3. LightGBM 随机搜索 (RandomizedSearchCV) ---
# =================================================================
print("\n--- 3. LightGBM 随机搜索 ---")

# 定义 LightGBM 的参数分布空间
param_dist_lgbm = {
    'n_estimators': randint(low=100, high=500), # 100到500之间随机整数
    'learning_rate': loguniform(0.01, 0.3),    # 0.01到0.3之间的对数均匀分布
    'num_leaves': randint(low=10, high=50),    # 10到50之间的随机整数
    'max_depth': [-1, 5, 10, 20],              # 离散值,-1代表无限制
    'min_child_samples': randint(low=10, high=50),
    'subsample': uniform(0.6, 0.4),            # 0.6到1.0之间的均匀分布 (0.6 + 0.4)
    'colsample_bytree': uniform(0.6, 0.4)      # 0.6到1.0之间的均匀分布
}

# 创建 RandomizedSearchCV 对象
random_search_lgbm = RandomizedSearchCV(
    estimator=lgb.LGBMClassifier(random_state=RANDOM_STATE, verbose=-1, n_jobs=-1),
    param_distributions=param_dist_lgbm,
    n_iter=50,          # 随机采样的组合数量,可以根据时间和资源调整
    cv=5,               # 5折交叉验证 (内部验证)
    scoring='accuracy',
    random_state=RANDOM_STATE,
    n_jobs=-1           # 使用所有核心进行并行计算
)

start_time = time.time()
# 在训练集上进行随机搜索
random_search_lgbm.fit(X_train, y_train)
end_time = time.time()

print(f"LightGBM 随机搜索耗时: {end_time - start_time:.4f} 秒")
print("LightGBM 最佳参数: ", random_search_lgbm.best_params_)
print("LightGBM 最佳交叉验证准确率: ", random_search_lgbm.best_score_ if random_search_lgbm.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行最终预测和评估
best_model_lgbm = random_search_lgbm.best_estimator_
best_pred_lgbm = best_model_lgbm.predict(X_test)

print("\nLightGBM 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_lgbm))
print("LightGBM 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_lgbm))

image-20251111203646206


贝叶斯优化

KNN

import numpy as np
import time
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.preprocessing import StandardScaler

# --- 导入贝叶斯优化和模型库 ---
from skopt import BayesSearchCV
# Real 用于连续参数, Integer 用于离散范围
from skopt.space import Real, Integer
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
import lightgbm as lgb
# =================================================================
# --- 4. 贝叶斯优化 KNN (KNeighborsClassifier) ---
# =================================================================
print("\n--- 4. 贝叶斯优化 KNN ---")

# 定义 KNN 的参数空间
search_space_knn = {
    'n_neighbors': Integer(1, 15),              # 搜索 K 值
    'weights': ['uniform', 'distance'],         # 权重模式 (均匀或距离加权)
    'p': Integer(1, 2)                          # 距离度量 (p=1: 曼哈顿距离, p=2: 欧氏距离)
}

# 创建贝叶斯优化搜索对象
# 注意:KNN 必须使用缩放后的数据 X_train_scaled, X_test_scaled
bayes_search_knn = BayesSearchCV(
    estimator=KNeighborsClassifier(),
    search_spaces=search_space_knn,
    n_iter=16, # KNN参数较少,减少迭代次数
    cv=5,
    n_jobs=-1,
    scoring='accuracy',
    random_state=RANDOM_STATE
)

start_time = time.time()
# 在缩放后的训练集上进行贝叶斯优化搜索
bayes_search_knn.fit(X_train_scaled, y_train)
end_time = time.time()

print(f"KNN 贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("KNN 最佳参数: ", bayes_search_knn.best_params_)
print("KNN 最佳交叉验证准确率: ", bayes_search_knn.best_score_ if bayes_search_knn.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行预测和评估
best_model_knn = bayes_search_knn.best_estimator_
best_pred_knn = best_model_knn.predict(X_test_scaled)

print("\nKNN 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_knn))
print("KNN 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_knn))

image-20251111203739297

LightGBM

# =================================================================
# --- 3. 贝叶斯优化 LightGBM (LGBMClassifier) ---
# =================================================================
print("\n--- 3. 贝叶斯优化 LightGBM ---")

# 定义 LightGBM 的参数空间
search_space_lgbm = {
    'n_estimators': Integer(100, 500),                   # 树的数量
    'learning_rate': Real(0.01, 0.3, prior='log-uniform'), # 学习率(对数均匀分布)
    'num_leaves': Integer(20, 40),                       # 每棵树的最大叶子数
    'max_depth': Integer(5, 15),                         # 树的最大深度
    'min_child_samples': Integer(10, 30),                # 叶子节点最小数据量
    'colsample_bytree': Real(0.7, 1.0, prior='uniform')  # 特征采样率 (0.7到1.0均匀分布)
}

# 创建贝叶斯优化搜索对象
bayes_search_lgbm = BayesSearchCV(
    estimator=lgb.LGBMClassifier(objective='multiclass', 
                                 num_class=3, 
                                 random_state=RANDOM_STATE, 
                                 n_jobs=-1, 
                                 verbose=-1 # 关闭冗余输出
                                ),
    search_spaces=search_space_lgbm,
    n_iter=32,
    cv=5,
    n_jobs=-1,
    scoring='accuracy',
    random_state=RANDOM_STATE
)

start_time = time.time()
# 在训练集上进行贝叶斯优化搜索
bayes_search_lgbm.fit(X_train, y_train)
end_time = time.time()

print(f"LightGBM 贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("LightGBM 最佳参数: ", bayes_search_lgbm.best_params_)
print("LightGBM 最佳交叉验证准确率: ", bayes_search_lgbm.best_score_ if bayes_search_lgbm.best_score_ is not None else "N/A")

# 使用最佳参数的模型进行预测和评估
best_model_lgbm = bayes_search_lgbm.best_estimator_
best_pred_lgbm = best_model_lgbm.predict(X_test)

print("\nLightGBM 在测试集上的分类报告:")
print(classification_report(y_test, best_pred_lgbm))
print("LightGBM 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred_lgbm))

image-20251111203805291
@浙大疏锦行

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐