news 2026/8/23 7:31:38

Python打卡第11天

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python打卡第11天

@浙大疏锦行

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

importwarnings

importlightgbm as lgb

importmatplotlib.pyplot as plt

importnumpy as np

importpandas as pd

fromsklearn.metricsimportaccuracy_score

fromsklearn.model_selectionimportGridSearchCV, RandomizedSearchCV, train_test_split

fromsklearn.neighborsimportKNeighborsClassifier

fromsklearn.preprocessingimportLabelEncoder, StandardScaler

fromskoptimportBayesSearchCV

warnings.filterwarnings("ignore")

plt.rcParams['font.sans-serif']=['SimHei','Microsoft YaHei']# 优先黑体,备选微软雅黑

plt.rcParams['axes.unicode_minus']=False# 解决坐标轴负号显示方框问题

data=pd.read_csv(r'D:\Desktop\Postgraduate\PythonStudy\Python打卡训练营\Python打卡训练营\python60-days-challenge-master\data.csv')# 读取数据

# print(data.info())

col_cn_dict={

"Id":"编号",

"Home Ownership":"房屋产权情况",

"Annual Income":"年收入",

"Years in current job":"现工作任职年限",

"Tax Liens":"税务留置次数",

"Number of Open Accounts":"未结清账户数量",

"Years of Credit History":"信用历史年限",

"Maximum Open Credit":"最大开放授信额度",

"Number of Credit Problems":"信用问题次数",

"Months since last delinquent":"上次逾期距今月数",

"Bankruptcies":"破产记录次数",

"Purpose":"贷款用途",

"Term":"贷款期限",

"Current Loan Amount":"当前贷款金额",

"Current Credit Balance":"当前信贷余额",

"Monthly Debt":"月负债",

"Credit Score":"信用评分",

"Credit Default":"是否违约"

}

data=data.rename(columns=col_cn_dict)

# print(data.info())

# print(data['现工作任职年限'].value_counts())

defpreprocess_credit_data(data, test_size=0.2, random_state=42):

"""

信贷违约数据完整预处理流程

返回: X_train, X_test, y_train, y_test

"""

# ==================== 1. 划分特征与标签 ====================

X=data.drop(columns=["是否违约","编号"])# 编号无预测意义,丢弃

y=data["是否违约"]

# ==================== 2. 划分训练集 / 测试集 ====================

X_train, X_test, y_train, y_test=train_test_split(

X, y, test_size=test_size, random_state=random_state, stratify=y

)

# stratify=y 保证训练/测试集中违约比例一致

# ==================== 3. 区分离散 / 连续特征 ====================

discrete_cols=X_train.select_dtypes(include=["object"]).columns.tolist()

continuous_cols=X_train.select_dtypes(include=[np.number]).columns.tolist()

special_col="现工作任职年限"

ifspecial_colindiscrete_cols:

discrete_cols.remove(special_col)# 任职年限单独字典映射

# ==================== 4. 缺失值填充 ====================

# 连续特征 → 中位数(只用训练集统计量,防泄露)

forcolincontinuous_cols:

median_val=X_train[col].median()

X_train[col]=X_train[col].fillna(median_val)

X_test[col]=X_test[col].fillna(median_val)

# 离散特征(含任职年限) → 众数

forcolindiscrete_cols+[special_col]:

mode_val=X_train[col].mode()[0]

X_train[col]=X_train[col].fillna(mode_val)

X_test[col]=X_test[col].fillna(mode_val)

# ==================== 5. 现工作任职年限:字典映射 ====================

job_years_map={

"< 1 year":0,

"1 year":1,

"2 years":2,

"3 years":3,

"4 years":4,

"5 years":5,

"6 years":6,

"7 years":7,

"8 years":8,

"9 years":9,

"10+ years":11,

}

X_train[special_col]=X_train[special_col].map(job_years_map).astype(int)

X_test[special_col]=X_test[special_col].map(job_years_map).astype(int)

# ==================== 6. 其余离散特征编码 ====================

# 有序特征:贷款期限(短期 < 长期)→ 标签编码

# 无序特征:房屋产权情况、贷款用途 → 独热编码

ordinal_cols=["贷款期限"]

nominal_cols=[cforcindiscrete_colsifcnotinordinal_cols]

# 6.1 有序特征 LabelEncoder

forcolinordinal_cols:

le=LabelEncoder()

X_train[col]=le.fit_transform(X_train[col])

X_test[col]=le.transform(X_test[col])

# 6.2 无序特征 One-Hot(测试集按训练集列对齐,防止列数不一致)

X_train=pd.get_dummies(X_train, columns=nominal_cols, drop_first=True)

X_test=pd.get_dummies(X_test, columns=nominal_cols, drop_first=True)

X_test=X_test.reindex(columns=X_train.columns, fill_value=0)

# ==================== 7. 异常值处理(IQR 截断,不删样本) ====================

# 对连续特征 + 映射后的任职年限做截断;独热列和0/1标签列不动

outlier_cols=continuous_cols+[special_col]

forcolinoutlier_cols:

Q1=X_train[col].quantile(0.25)

Q3=X_train[col].quantile(0.75)

IQR=Q3-Q1

lower, upper=Q1-1.5*IQR, Q3+1.5*IQR

X_train[col]=X_train[col].clip(lower=lower, upper=upper)

X_test[col]=X_test[col].clip(lower=lower, upper=upper)

# ==================== 8. 标准化 ====================

# 选择 StandardScaler:已做 IQR 截断,异常值影响可控;

# 信贷数据右偏明显,StandardScaler 比 MinMax 更稳健,且适配逻辑回归/SVM/NN

# 独热列保持 0/1 不缩放,仅缩放连续/有序数值列

onehot_cols=[cforcinX_train.columns

ifany(c.startswith(nc+"_")forncinnominal_cols)]

scale_cols=[cforcinX_train.columnsifcnotinonehot_cols]

scaler=StandardScaler()

X_train[scale_cols]=scaler.fit_transform(X_train[scale_cols])

X_test[scale_cols]=scaler.transform(X_test[scale_cols])

returnX_train, X_test, y_train, y_test

# ========== 调用方式 ==========

X_train, X_test, y_train, y_test=preprocess_credit_data(data)

# ===================== 1. 定义保存结果列表 =====================

results=[]

# ===================== 2. 通用工具函数:保存结果 =====================

defrecord_result(model_name, search_name, best_params,

X_train, X_test, y_train, y_test, best_estimator):

y_pred_train=best_estimator.predict(X_train)

y_pred_test=best_estimator.predict(X_test)

acc_train=round(accuracy_score(y_train, y_pred_train),4)

acc_test=round(accuracy_score(y_test, y_pred_test),4)

results.append({

"模型": model_name,

"寻优方法": search_name,

"最优参数": best_params,

"训练集准确率": acc_train,

"测试集准确率": acc_test

})

# ===================== 3. KNN 参数空间 =====================

knn=KNeighborsClassifier()

knn_grid={

"n_neighbors": [3,5,7,9,11],

"weights": ["uniform","distance"],

"p": [1,2]

}

knn_random={

"n_neighbors":list(range(3,15)),

"weights": ["uniform","distance"],

"p": [1,2]

}

knn_bayes={

"n_neighbors": (3,15),

"weights": ["uniform","distance"],

"p": (1,2)

}

# -------- KNN - 网格搜索 --------

print("==== KNN 网格搜索 ====")

gs_knn=GridSearchCV(knn, knn_grid, cv=5, scoring="accuracy", n_jobs=-1)

gs_knn.fit(X_train, y_train)

record_result("KNN","网格搜索", gs_knn.best_params_, X_train, X_test, y_train, y_test, gs_knn.best_estimator_)

# -------- KNN - 随机搜索 --------

print("==== KNN 随机搜索 ====")

rs_knn=RandomizedSearchCV(knn, knn_random, cv=5, scoring="accuracy",

n_iter=10, random_state=42, n_jobs=-1)

rs_knn.fit(X_train, y_train)

record_result("KNN","随机搜索", rs_knn.best_params_, X_train, X_test, y_train, y_test, rs_knn.best_estimator_)

# -------- KNN - 贝叶斯优化 --------

print("==== KNN 贝叶斯优化 ====")

bs_knn=BayesSearchCV(knn, knn_bayes, cv=5, scoring="accuracy",

n_iter=10, random_state=42, n_jobs=-1)

bs_knn.fit(X_train, y_train)

record_result("KNN","贝叶斯优化", bs_knn.best_params_, X_train, X_test, y_train, y_test, bs_knn.best_estimator_)

# ===================== 4. LightGBM 参数空间 =====================

lgb_clf=lgb.LGBMClassifier(random_state=42, verbosity=-1)

lgb_grid={

"learning_rate": [0.01,0.05,0.1],

"n_estimators": [50,100,200],

"max_depth": [3,5,7]

}

lgb_random={

"learning_rate": np.logspace(-3,-1,10),

"n_estimators":list(range(50,300,20)),

"max_depth":list(range(2,10)),

"subsample": [0.6,0.7,0.8,0.9,1.0]

}

lgb_bayes={

"learning_rate": (1e-3,0.3,"log-uniform"),

"n_estimators": (50,300),

"max_depth": (2,10),

"subsample": (0.6,1.0)

}

# -------- LightGBM - 网格搜索 --------

print("==== LightGBM 网格搜索 ====")

gs_lgb=GridSearchCV(lgb_clf, lgb_grid, cv=5, scoring="accuracy", n_jobs=-1)

gs_lgb.fit(X_train, y_train)

record_result("LightGBM","网格搜索", gs_lgb.best_params_, X_train, X_test, y_train, y_test, gs_lgb.best_estimator_)

# -------- LightGBM - 随机搜索 --------

print("==== LightGBM 随机搜索 ====")

rs_lgb=RandomizedSearchCV(lgb_clf, lgb_random, cv=5, scoring="accuracy",

n_iter=10, random_state=42, n_jobs=-1)

rs_lgb.fit(X_train, y_train)

record_result("LightGBM","随机搜索", rs_lgb.best_params_, X_train, X_test, y_train, y_test, rs_lgb.best_estimator_)

# -------- LightGBM - 贝叶斯优化 --------

print("==== LightGBM 贝叶斯优化 ====")

bs_lgb=BayesSearchCV(lgb_clf, lgb_bayes, cv=5, scoring="accuracy",

n_iter=10, random_state=42, n_jobs=-1)

bs_lgb.fit(X_train, y_train)

record_result("LightGBM","贝叶斯优化", bs_lgb.best_params_, X_train, X_test, y_train, y_test, bs_lgb.best_estimator_)

# ===================== 5. 输出汇总对比表格 =====================

df_result=pd.DataFrame(results)

# 让 Pandas 在终端中正确计算中文字符宽度,避免表头错位

pd.set_option("display.unicode.east_asian_width",True)

pd.set_option("display.unicode.ambiguous_as_wide",True)

# 主表只展示适合横向比较的字段,较长的参数字典放到下方分行显示

summary_columns=["模型","寻优方法","训练集准确率","测试集准确率"]

df_summary=df_result[summary_columns].copy()

accuracy_formatters={

"训练集准确率":lambdavalue: f"{value:.2%}",

"测试集准确率":lambdavalue: f"{value:.2%}",

}

print("\n"+"="*72)

print("【各模型不同超参数寻优方法结果汇总表】")

print("="*72)

print(

df_summary.to_string(

index=False,

justify="center",

col_space={"模型":12,"寻优方法":12},

formatters=accuracy_formatters,

)

)

print("\n【各模型最优参数明细】")

print("-"*72)

forresultinresults:

print(f"{result['模型']} - {result['寻优方法']}")

forparam_name, param_valueinresult["最优参数"].items():

print(f" {param_name}: {param_value}")

print()

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 7:28:21

三维旋转表示法:从旋转矩阵、欧拉角到四元数插值的工程实践

1. 项目概述&#xff1a;三维空间旋转的“语言”与“桥梁”在三维图形、机器人学、惯性导航、无人机飞控乃至游戏开发中&#xff0c;我们无时无刻不在处理一个核心问题&#xff1a;如何精确地描述和计算一个物体在三维空间中的朝向变化&#xff1f;这听起来像是一个纯粹的数学问…

作者头像 李华
网站建设 2026/8/23 7:28:03

秉承在实践中学习,在项目中提高编程语言的综合能力的原则,准备在复刻deepseek harness项目的过程中,找到光明的不足,补足短板,让光明语言真正能够实战!请你修正一下,然后制定改进计划!

秉承在实践中学习&#xff0c;在写项目中提高编程语言的综合能力的原则&#xff0c;准备在复刻deepseek harness项目的过程中&#xff0c;找到light的不足&#xff0c;补足短板&#xff0c;让light语言真正能够实战&#xff01; 已经让hy3 模型先摸了摸底&#xff0c;写了两篇文…

作者头像 李华
网站建设 2026/8/23 7:25:12

储能 BMS 的绝缘检测,到底是怎么同时测出正、负两路绝缘电阻的

在储能系统里&#xff0c;绝缘检测是少数几个「平时没人注意&#xff0c;出事就是大事故」的功能。电池堆的正负极母线动辄几百伏&#xff0c;一旦对机壳的绝缘性能下降&#xff0c;轻则漏电报警&#xff0c;重则电弧、短路、起火。所以几乎每一套正经的储能 BMS 都会把绝缘检测…

作者头像 李华
网站建设 2026/8/23 7:24:16

工业边缘AI实战:基于NXP i.MX 8M Plus的嵌入式硬件选型与开发指南

1. 项目概述&#xff1a;当工业边缘遇到AI&#xff0c;我们需要什么样的“硬核”&#xff1f;最近几年&#xff0c;工业圈子里聊得最火的话题&#xff0c;除了数字化转型&#xff0c;就是边缘计算和AI了。大家不再满足于把海量的设备数据一股脑儿往云端传&#xff0c;延迟、带宽…

作者头像 李华
网站建设 2026/8/23 7:23:48

C++函数模板:从类型参数化到泛型编程实战指南

1. 从“重复造轮子”到“一次编写&#xff0c;处处适配”的思维转变如果你写过一段时间的C&#xff0c;尤其是在处理一些需要支持多种数据类型的算法或功能时&#xff0c;大概率会遇到一个让人头疼的问题&#xff1a;代码重复。比如&#xff0c;你想写一个函数来比较两个值的大…

作者头像 李华