Python训练营打卡DAY11

DAY11

超参数调整专题

知识点回顾

  1. 网格搜索
  2. 随机搜索(简单介绍,非重点 实战中很少用到,可以不了解)
  3. 贝叶斯优化(2种实现逻辑,以及如何避开必须用交叉验证的问题)
  4. time库的计时模块,方便后人查看代码运行时长

今日作业:

对于信贷数据的其他模型,如LightGBM和KNN 尝试用下贝叶斯优化和网格搜索

#回顾一下
import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
dt = pd.read_csv('heart.csv')
dt.info()
dt.head()

dt.isnull().sum()

def manual_normalize(dt):
    min_val = dt.min()
    max_val = dt.max()
    normalized_dt = (dt - min_val) / (max_val - min_val)
    return normalized_dt
dt['age'] = manual_normalize(dt['age'])
dt['trestbps'] = manual_normalize(dt['trestbps'])
dt['chol'] = manual_normalize(dt['chol'])
dt['thalach'] = manual_normalize(dt['thalach'])
dt['oldpeak'] = manual_normalize(dt['oldpeak'])
dt.head()

from sklearn.model_selection import train_test_split
x = dt.drop(['target'],axis=1)
y = dt['target']
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=42)
print(f"训练集形状: {x_train.shape}, 测试集形状: {x_test.shape}")

from sklearn.svm import SVC #支持向量机分类器
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore")
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
smodel = SVC(random_state=42)
smodel.fit(x_train,y_train)
smodel_pred = smodel.predict(x_test)
print("\nSVM 分类报告:")
print(classification_report(y_test, smodel_pred))
print("SVM 混淆矩阵:")
print(confusion_matrix(y_test, smodel_pred))
print("SVM 准确率:", accuracy_score(y_test, smodel_pred))
print("SVM 精确率:", precision_score(y_test, smodel_pred))
print("SVM 召回率:", recall_score(y_test, smodel_pred))
print("SVM F1 分数:", f1_score(y_test, smodel_pred))

# new数据预处理
import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
dt = pd.read_csv('data.csv')
dt.info()
dt.head()

discrete_features = dt.select_dtypes(include=['object']).columns.tolist()
print("离散型特征列:", discrete_features)

continuous_features = dt.select_dtypes(include=['int64', 'float64']).columns.tolist()
print("连续型特征列:", continuous_features)

for features in discrete_features:
    mode_value = dt[features].mode()[0]
    dt[features].fillna(mode_value,inplace=True)
    print(f'列:{features}用众数{mode_value}填充缺失值')
for features in continuous_features:
    median_value = dt[features].median()
    dt[features].fillna(median_value,inplace=True)
    print(f'列:{features}用中位数{median_value}填充缺失值')
dt.info()
dt.head()

# Home Ownership 标签编码
home_ownership_mapping = {
    'Own Home': 1,
    'Rent': 2,
    'Have Mortgage': 3,
    'Home Mortgage': 4
}
dt['Home Ownership'] = dt['Home Ownership'].map(home_ownership_mapping)

# Years in current job 标签编码
years_in_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
}
dt['Years in current job'] = dt['Years in current job'].map(years_in_job_mapping)

dt['Purpose'].value_counts()
# Purpose 独热编码,记得需要将bool类型转换为数值
dt = pd.get_dummies(dt, columns=['Purpose'])
dt2 = pd.read_csv("data.csv") # 重新读取数据,用来做列名对比
purpose_final = [] # 新建一个空列表,用于存放独热编码后新增的特征名
for i in dt.columns:
    if i not in dt2.columns:
        purpose_final.append(i) # 这里打印出来的就是独热编码后的特征名
for i in purpose_final:
    dt[i] = dt[i].astype(int) # 这里的i就是独热编码后的特征名

# Term 0 - 1 映射
term_mapping = {
    'Short Term': 0,
    'Long Term': 1
}
dt['Term'] = dt['Term'].map(term_mapping)
dt.rename(columns={'Term': 'Long Term'}, inplace=True) # 重命名列

def manual_normalize(dt):
    min_val = dt.min()
    max_val = dt.max()
    normalized_dt = (dt - min_val) / (max_val - min_val)
    return normalized_dt
for features in continuous_features:
    dt[features] = manual_normalize(dt[features])

dt.head()
dt.info()
#删除id列
dt = dt.drop(['Id'],axis=1)
dt.head()
dt.info()

#划分训练集和测试集
from sklearn.model_selection import train_test_split
x = dt.drop(['Credit Default'],axis=1)
y = dt['Credit Default']
x_train,x_temp,y_train,y_temp = train_test_split(x,y,test_size=0.2,random_state=42)
x_test,x_val,y_test,y_val = train_test_split(x_temp,y_temp,test_size=0.5,random_state=42)
print("dt shapes:")
print("x_train:", x_train.shape)
print("y_train:", y_train.shape)
print("x_val:", x_val.shape)
print("y_val:", y_val.shape)
print("x_test:", x_test.shape)
print("y_test:", y_test.shape)

from sklearn.model_selection import train_test_split
x = dt.drop(['Credit Default'], axis=1)  # 特征,axis=1表示按列删除
y = dt['Credit Default'] # 标签
# 按照8:2划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集
print("dt shapes:")
print("x_train:", x_train.shape)
print("y_train:", y_train.shape)
print("x_test:", x_test.shape)
print("y_test:", y_test.shape)

from sklearn.svm import SVC #支持向量机分类器
from sklearn.neighbors import KNeighborsClassifier #K近邻分类器
from sklearn.linear_model import LogisticRegression #逻辑回归分类器
import xgboost as xgb #XGBoost分类器
import lightgbm as lgb #LightGBM分类器
from sklearn.ensemble import RandomForestClassifier #LGB分类器
from catboost import CatBoostClassifier #CatBoost分类器
from sklearn.tree import DecisionTreeClassifier #决策树分类器
from sklearn.naive_bayes import GaussianNB #高斯朴素贝叶斯分类器
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") # 忽略所有警告信息
import time

print("--- 1. 默认参数LGB (训练集 -> 测试集) ---")
start_time = time.time()
lgb_model = lgb.LGBMClassifier(random_state=42) # 初始化LGB分类器
lgb_model.fit(x_train, y_train) # 训练模型
lgb_pred = lgb_model.predict(x_test) # 预测测试集
end_time = time.time()
print(f"训练时间:{ end_time - start_time:.4f}秒")
print("\nLGB 分类报告:")
print(classification_report(y_test, lgb_pred))
print("LGB 混淆矩阵:")
print(confusion_matrix(y_test, lgb_pred))
print("LGB F1 分数:", f1_score(y_test, lgb_pred))

print("\n--- 2. 网格搜索优化LGB (训练集 -> 测试集) ---")
from sklearn.model_selection import GridSearchCV
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]
}
grid_search = GridSearchCV(estimator=lgb.LGBMClassifier(random_state=42), # LGB分类器
                        param_grid=param_grid, # 参数网格
                        cv=5, # 5折交叉验证
                        n_jobs=-1, # 使用所有可用的CPU核心进行并行计算
                        scoring='accuracy')
start_time = time.time()
# 在训练集上进行网格搜索
grid_search.fit(x_train, y_train) # 在训练集上训练,模型实例化和训练的方法都被封装在这个网格搜索对象里了
end_time = time.time()

print(f"网格搜索耗时: {end_time - start_time:.4f} 秒")
print("最佳参数: ", grid_search.best_params_) #best_params_属性返回最佳参数组合

# 使用最佳参数的模型进行预测
best_model = grid_search.best_estimator_ # 获取最佳模型
best_pred = best_model.predict(x_test) # 在测试集上进行预测

print("\n网格搜索优化后的LGB 在测试集上的分类报告:")
print(classification_report(y_test, best_pred))
print("网格搜索优化后的LGB 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred))
print("网格搜索优化后的LGB 在测试集上的 F1 分数:", f1_score(y_test, best_pred))

print("\n--- 3. 贝叶斯优化LGB (训练集 -> 测试集) ---")
from bayes_opt import BayesianOptimization
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np

# 定义目标函数,这里使用交叉验证来评估模型性能
def lgb_eval(n_estimators, max_depth, min_samples_split, min_samples_leaf):
    n_estimators = int(n_estimators)
    max_depth = int(max_depth)
    min_samples_split = int(min_samples_split)
    min_samples_leaf = int(min_samples_leaf)
    model = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        min_samples_split=min_samples_split,
        min_samples_leaf=min_samples_leaf,
        random_state=42
    )
    scores = cross_val_score(model, x_train, y_train, cv=5, scoring='accuracy')
    return np.mean(scores)

# 定义要搜索的参数空间
pbounds_lgb = {
    'n_estimators': (50, 200),
    'max_depth': (10, 30),
    'min_samples_split': (2, 10),
    'min_samples_leaf': (1, 4)
}

# 创建贝叶斯优化对象,设置 verbose=2 显示详细迭代信息
optimizer_lgb = BayesianOptimization(
    f=lgb_eval, # 目标函数
    pbounds=pbounds_lgb, # 参数空间
    random_state=42, # 随机种子
    verbose=2  # 显示详细迭代信息
)

start_time = time.time()
# 开始贝叶斯优化
optimizer_lgb.maximize(
    init_points=5,  # 初始随机采样点数
    n_iter=32  # 迭代次数
)
end_time = time.time()

print(f"贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("最佳参数: ", optimizer_lgb.max['params'])

# 使用最佳参数的模型进行预测
best_params = optimizer_lgb.max['params']
best_model = lgb.LGBMClassifier(
    n_estimators=int(best_params['n_estimators']),
    max_depth=int(best_params['max_depth']),
    min_samples_split=int(best_params['min_samples_split']),
    min_samples_leaf=int(best_params['min_samples_leaf']),
    random_state=42
)
best_model.fit(x_train, y_train)
best_pred = best_model.predict(x_test)

print("\n贝叶斯优化后的LGB 在测试集上的分类报告:")
print(classification_report(y_test, best_pred))
print("贝叶斯优化后的LGB 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred))
print("贝叶斯优化后的LGB 在测试集上的 F1 分数:", f1_score(y_test, best_pred))
print(f"贝叶斯优化耗时: {end_time - start_time:.4f} 秒")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值