文章目录一、项目背景介绍1.1 业务场景信用卡欺诈检测1.2 数据集说明二、业务场景分析2.1 业务指标与模型指标2.2 部署约束三、数据集获取与预处理3.1 数据下载与加载3.2 数据初步探索3.3 数据清洗与预处理四、数据探索 EDA4.1 类别分布可视化4.2 特征分布对比欺诈 vs 正常4.3 相关性矩阵五、特征工程全流程5.1 原始特征已足够PCA 特征5.2 特征选择六、模型选型对比多种算法横向测评七、模型训练/调参/交叉验证7.1 划分训练集和测试集最终评估用7.2 使用随机搜索调优 GBDT7.3 使用最佳参数重新训练并评估测试集八、模型评估指标详解8.1 混淆矩阵8.2 PR 曲线与 AUC8.3 业务解释九、模型保存与加载十、推理预测实战10.1 单条预测实时 API 风格10.2 批量预测十一、项目部署简易流程11.1 使用 Flask 构建 REST API示例11.2 使用 Docker 容器化简化十二、常见问题复盘12.1 极度不平衡导致的过拟合12.2 实时预测性能12.3 模型更新与监控十三、全套源码完整附录十四、课程整体结业总结⏬项目源码下载《30节课 scikit-learn 从入门到精通》系列课程导航一、项目背景介绍1.1 业务场景信用卡欺诈检测信用卡欺诈每年给金融机构和消费者造成巨额损失。根据 Nilson Report 数据全球信用卡欺诈损失在 2020 年超过 280 亿美元。银行和支付公司迫切需要能够实时检测可疑交易的自动化系统。业务目标在大量交易记录中快速、准确地识别出欺诈交易同时尽量减少对正常交易的误判避免打扰客户。关键挑战极度不平衡欺诈交易通常占全部交易的 0.1% 甚至更低本项目中模拟为 0.17%。实时性要求交易审批需要在毫秒级完成模型推理必须高效。可解释性银行监管要求模型输出应能被解释特征重要性、决策路径。1.2 数据集说明本项目使用 Kaggle 上的Credit Card Fraud Detection数据集已脱敏可公开使用。该数据集包含 2013 年 9 月欧洲持卡人的 284807 笔交易其中欺诈交易 492 笔0.172%。特征经过 PCA 变换得到 V1-V28 共 28 个匿名特征外加Time交易距第一笔交易的秒数和Amount交易金额。目标变量Class1 表示欺诈0 表示正常。由于数据集较大约 140MB我们将演示用pandas读取并可选择下采样或使用全部数据但本课程为教学演示使用全量但通过代码控制。二、业务场景分析2.1 业务指标与模型指标在欺诈检测中不同的错误类型成本不同漏报FN将欺诈判为正常银行赔付全部损失成本极高。误报FP将正常判为欺诈客户体验受损银行需人工审核成本较低。因此业务上更关注召回率Recall即真正欺诈有多少被抓住。但同时要控制误报率避免过多打扰客户。常用评估指标包括精确率Precision预测为欺诈中实际欺诈的比例。召回率Recall真实欺诈中被正确识别的比例。F1 分数精确率和召回率的调和平均。混淆矩阵直观展示 TP、FP、FN、TN。PR 曲线下面积AUPRC对不平衡数据优于 ROC-AUC。本项目将使用召回率为主要优化目标同时兼顾 F1 分数。2.2 部署约束模型需支持批量预测和单条实时预测推理延迟 50ms模型大小 100MB。三、数据集获取与预处理3.1 数据下载与加载数据集可从 Kaggle 下载为方便本课程我们提供模拟代码实际运行请下载真实数据。以下代码演示从本地 CSV 加载。# -*- coding: utf-8 -*- 信用卡欺诈检测 - 完整项目代码 要求下载 creditcard.csv 到 ./data/ 目录 可从 https://www.kaggle.com/datasets/mlg-ulb/creditcardfraud 下载 importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsfromsklearn.model_selectionimporttrain_test_split,cross_val_score,GridSearchCV,StratifiedKFoldfromsklearn.preprocessingimportStandardScalerfromsklearn.linear_modelimportLogisticRegressionfromsklearn.ensembleimportRandomForestClassifier,GradientBoostingClassifierfromsklearn.metricsimport(confusion_matrix,classification_report,precision_recall_curve,average_precision_score,roc_auc_score,f1_score,recall_score)importjoblibimportwarnings warnings.filterwarnings(ignore)# 设置显示plt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]Falsesns.set_style(whitegrid)# 加载数据请确保路径正确# df pd.read_csv(./data/creditcard.csv)# 由于数据较大本演示使用模拟数据同样不平衡性但你应替换为真实数据# 为便于复现这里生成模拟数据特征数 30符合实际形状fromsklearn.datasetsimportmake_classification np.random.seed(42)X_sim,y_simmake_classification(n_samples284807,n_features30,n_informative20,n_redundant10,weights[0.99828],flip_y0.005,random_state42)# 构造 DataFramefeature_names[fV{i}foriinrange(1,29)][Amount,Time]dfpd.DataFrame(X_sim,columnsfeature_names)df[Class]y_simprint(数据集形状:,df.shape)print(类别分布:\n,df[Class].value_counts())print(欺诈比例: {:.4%}.format(df[Class].mean()))3.2 数据初步探索# 查看前5行print(df.head())# 统计信息print(df.describe())# 检查缺失值真实数据无缺失这里验证print(缺失值数量:\n,df.isnull().sum())# 查看 Amount 和 Time 的分布fig,axesplt.subplots(1,2,figsize(12,4))axes[0].hist(df[Amount],bins50)axes[0].set_title(交易金额分布右偏)axes[1].hist(df[Time],bins50)axes[1].set_title(交易时间分布)plt.show()3.3 数据清洗与预处理真实数据中无缺失值但金额和时间尺度差异大需要标准化。# 分离特征和标签Xdf.drop(Class,axis1)ydf[Class]# 标准化 Amount 和 TimeV1-V28 已经是 PCA 后的近似标准正态可不标但统一标scalerStandardScaler()X_scaledscaler.fit_transform(X)# 保存 scaler 供后续使用joblib.dump(scaler,models/scaler.pkl)四、数据探索 EDA4.1 类别分布可视化plt.figure(figsize(6,4))sns.countplot(xClass,datadf)plt.title(类别分布极度不平衡)plt.show()4.2 特征分布对比欺诈 vs 正常# 选取部分特征展示features_to_plot[V1,V2,V3,Amount]fig,axesplt.subplots(2,2,figsize(12,8))fori,featinenumerate(features_to_plot):axaxes[i//2,i%2]sns.kdeplot(df[df[Class]0][feat],label正常,axax)sns.kdeplot(df[df[Class]1][feat],label欺诈,axax)ax.set_title(f{feat}分布对比)plt.tight_layout()plt.show()4.3 相关性矩阵由于 V1-V28 是 PCA 结果相互正交相关性接近0但金额与时间可能与其他特征有弱相关。plt.figure(figsize(12,10))corrdf.corr()sns.heatmap(corr,cmapcoolwarm,center0,annotFalse)plt.title(特征相关性热力图)plt.show()五、特征工程全流程5.1 原始特征已足够PCA 特征由于数据集已经提供了 PCA 转换后的特征我们不再需要额外的特征构造。但可以尝试创建金额与时间交互特征或者对金额取对数。# 添加金额的对数特征缓解右偏X_scaled_with_lognp.column_stack([X_scaled,np.log1p(df[Amount].values)])# 更新特征名列表feature_names_newlist(feature_names)[log_Amount]5.2 特征选择可使用随机森林的特征重要性或方差阈值筛选但为保持完整性我们先用全部特征。六、模型选型对比多种算法横向测评我们将比较以下算法并采用分层 K 折交叉验证5 折以召回率为主要指标同时记录 F1 和 AUC。fromsklearn.model_selectionimportcross_validatefromsklearn.metricsimportmake_scorer,recall_score,f1_score,roc_auc_score# 定义评分字典scoring{recall:make_scorer(recall_score),f1:make_scorer(f1_score),roc_auc:make_scorer(roc_auc_score)}# 模型列表models{Logistic Regression:LogisticRegression(class_weightbalanced,max_iter1000,random_state42),Random Forest:RandomForestClassifier(n_estimators100,class_weightbalanced,random_state42,n_jobs-1),Gradient Boosting:GradientBoostingClassifier(n_estimators100,learning_rate0.1,random_state42)}# 使用原始特征 X_scaled不含 log_AmountX_finalX_scaled y_finaly# 分层 K 折cvStratifiedKFold(n_splits5,shuffleTrue,random_state42)results{}forname,modelinmodels.items():scorescross_validate(model,X_final,y_final,cvcv,scoringscoring,n_jobs-1)results[name]{recall_mean:np.mean(scores[test_recall]),recall_std:np.std(scores[test_recall]),f1_mean:np.mean(scores[test_f1]),auc_mean:np.mean(scores[test_roc_auc])}print(f{name}: Recall {results[name][recall_mean]:.4f}(/-{results[name][recall_std]:.4f}), F1 {results[name][f1_mean]:.4f}, AUC {results[name][auc_mean]:.4f})根据结果梯度提升树和随机森林通常召回率较高我们选择梯度提升树作为最终模型。七、模型训练/调参/交叉验证7.1 划分训练集和测试集最终评估用X_train,X_test,y_train,y_testtrain_test_split(X_final,y_final,test_size0.2,random_state42,stratifyy_final)7.2 使用随机搜索调优 GBDTfromsklearn.model_selectionimportRandomizedSearchCVfromscipy.statsimportrandint,loguniform param_dist{n_estimators:randint(50,300),learning_rate:loguniform(1e-3,0.5),max_depth:randint(3,8),subsample:[0.7,0.8,0.9,1.0],min_samples_split:randint(2,20)}gbGradientBoostingClassifier(random_state42,class_weightbalanced)rand_searchRandomizedSearchCV(gb,param_dist,n_iter30,cv3,scoringrecall,random_state42,n_jobs-1,verbose1)rand_search.fit(X_train,y_train)print(最佳参数:,rand_search.best_params_)print(最佳召回率 (CV): {:.4f}.format(rand_search.best_score_))7.3 使用最佳参数重新训练并评估测试集best_gbrand_search.best_estimator_ y_predbest_gb.predict(X_test)y_probabest_gb.predict_proba(X_test)[:,1]print(测试集召回率:,recall_score(y_test,y_pred))print(测试集 F1:,f1_score(y_test,y_pred))print(测试集 AUC:,roc_auc_score(y_test,y_proba))print(\n分类报告:\n,classification_report(y_test,y_pred))八、模型评估指标详解8.1 混淆矩阵cmconfusion_matrix(y_test,y_pred)plt.figure(figsize(5,4))sns.heatmap(cm,annotTrue,fmtd,cmapBlues,xticklabels[正常,欺诈],yticklabels[正常,欺诈])plt.xlabel(预测)plt.ylabel(真实)plt.title(混淆矩阵)plt.show()8.2 PR 曲线与 AUCprecision,recall,_precision_recall_curve(y_test,y_proba)apaverage_precision_score(y_test,y_proba)plt.figure(figsize(8,6))plt.plot(recall,precision,labelfPR曲线 (AP{ap:.4f}))plt.xlabel(召回率)plt.ylabel(精确率)plt.title(精确率-召回率曲线)plt.legend()plt.show()8.3 业务解释在混淆矩阵中我们可以计算出误报率FP / (FPTN)和漏报率FN / (FNTP)。根据业务成本可以调整分类阈值。# 寻找最佳阈值最大化 F1fromsklearn.metricsimportf1_score thresholdsnp.linspace(0.1,0.9,50)f1_scores[]forthinthresholds:y_pred_th(y_probath).astype(int)f1_scores.append(f1_score(y_test,y_pred_th))best_ththresholds[np.argmax(f1_scores)]print(f最佳阈值:{best_th:.2f}, F1{max(f1_scores):.4f})九、模型保存与加载# 保存模型joblib.dump(best_gb,models/credit_fraud_gbdt.pkl)# 保存阈值可选np.save(models/best_threshold.npy,best_th)# 加载模型loaded_modeljoblib.load(models/credit_fraud_gbdt.pkl)十、推理预测实战10.1 单条预测实时 API 风格defpredict_fraud(transaction_features,model,scaler,threshold0.5): transaction_features: 长度为 30 的列表或 numpy 数组顺序同原始特征 X_scaledscaler.transform([transaction_features])probamodel.predict_proba(X_scaled)[0,1]predint(probathreshold)returnpred,proba# 示例取测试集第一条sampleX_test[0]pred,probapredict_fraud(sample,loaded_model,scaler,best_th)print(f预测结果:{欺诈ifpredelse正常}, 概率:{proba:.4f})10.2 批量预测batch_predloaded_model.predict(X_test[:100])batch_probaloaded_model.predict_proba(X_test[:100])[:,1]十一、项目部署简易流程11.1 使用 Flask 构建 REST API示例# 需安装 flask: pip install flaskfromflaskimportFlask,request,jsonifyimportjoblibimportnumpyasnp appFlask(__name__)modeljoblib.load(models/credit_fraud_gbdt.pkl)scalerjoblib.load(models/scaler.pkl)thresholdnp.load(models/best_threshold.npy)app.route(/predict,methods[POST])defpredict():datarequest.get_json()featuresnp.array(data[features]).reshape(1,-1)X_scaledscaler.transform(features)probamodel.predict_proba(X_scaled)[0,1]predint(probathreshold)returnjsonify({fraud:pred,probability:proba})if__name____main__:app.run(host0.0.0.0,port5000)11.2 使用 Docker 容器化简化编写 Dockerfile 并将模型文件打包使用 gunicorn 作为生产服务器。具体步骤略。十二、常见问题复盘12.1 极度不平衡导致的过拟合在调参过程中我们使用了class_weightbalanced或通过调整阈值改善召回率。若使用下采样将正常样本减少到与欺诈样本相同数量会丢失大量信息可能导致欠拟合。本项目采用全量数据 类别权重 阈值调整。12.2 实时预测性能GBDT 推理速度约每笔 1ms满足实时要求。若需要更高吞吐可考虑使用 XGBoost 或 LightGBM可单独安装。12.3 模型更新与监控部署后应定期重新训练例如每周并监控模型分数分布和特征漂移。十三、全套源码完整附录完整的项目代码已包含在上述各个代码块中可按顺序执行。所有文件结构如下credit_fraud_project/ ├── data/ │ └── creditcard.csv ├── models/ │ ├── scaler.pkl │ ├── credit_fraud_gbdt.pkl │ └── best_threshold.npy ├── train.py # 训练代码含上述所有步骤 ├── predict.py # 预测脚本 └── app.py # Flask API十四、课程整体结业总结通过本专栏 30 课的学习你已经从零基础成长为能够独立完成机器学习项目的开发者。我们回顾一下核心技能环境搭建熟练使用 Anaconda、虚拟环境、sklearn 安装。数据理解掌握 NumPy、Pandas、Matplotlib/Seaborn 进行数据处理与可视化。模型训练从线性回归到逻辑回归、决策树、随机森林、GBDT、SVM、KNN、朴素贝叶斯等。特征工程标准化、归一化、编码、多项式特征、降维PCA。模型评估混淆矩阵、精确率、召回率、F1、ROC、AUC以及不同业务场景下的指标选择。集成学习Bagging、随机森林、BoostingAdaBoost、GBDT。调优方法网格搜索、随机搜索、交叉验证、早停。项目落地从业务分析到模型部署的全流程。现在你已经具备了在真实工业场景中解决分类、回归、聚类问题的能力。未来可以进一步探索深度学习、AutoML、大数据框架Spark MLlib以及生产环境 MLops 实践。祝愿你在数据科学的道路上越走越远项目代码运行提示请先下载真实数据集或使用模拟数据完成练习。建议将本项目作为简历上的一个亮点并在 GitHub 上开源。课程结束感谢你完成了《scikit-learn 从入门到精通》全部课程⏬项目源码下载《30节课 scikit-learn 从入门到精通》系列课程导航去订阅第一部分基础入门 环境准备1-6 课第二部分数据预处理 数据集操作7-12 课第三部分传统机器学习回归算法13-17 课第四部分分类算法精讲18-23 课第五部分聚类 降维 集成学习24-29 课第六部分结业大型项目实战第 30 课 感谢您耐心阅读到这里 如果本文对您有所启发欢迎 点赞 收藏 分享给更多需要的伙伴。️ 期待在评论区看到您的想法, 共同进步。 关注我持续获取更多干货内容 我们下个专栏见
企业数字化 ERP 产品动态
相关推荐
把 Claude Code 接进 SoC 验证流水线:TaoToken 统一 Key 的 Agent 提效实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 9:58:45
OpenClaw 可视化安装全流程演示:用 TaoToken 统一 Key 打通本地智能办公助手 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 9:58:39
中望CAD批量打印插件实战:从手动逐张出图到自动化PDF交付 干我们这行的,天天跟中望CAD打交道,最烦的一件事就是把图纸转成PDF交出去。尤其是成套施工图,三五十张起步,大项目上百张也有,以前我都是开着一级“窗口”、二级“窗口”一个个框选图框,设置打印参数&#… · 2026/9/25 9:58:39
把 UltraEdit 改造成 Java IDE:用 TaoToken 统一 Key 打通编译与 AI 补全 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 10:27:01
开源可审计的LLM代码审查工作流:CLI+Git Hooks实战指南 1. 项目概述:这不是一个“工具”,而是一套可落地的开源代码审查工作流设计open-code-review 这个名字乍看像某个具体软件,但实际它代表的是一类正在快速成型的新型开发实践——用开源、透明、可审计的方式,把大语言模型࿰… · 2026/9/25 10:26:36
Atlas 300V 24G部署YOLO实战:昇腾推理卡环境搭建与调优 1. 项目概述:别被“atlas”这个名字唬住先给结论:Atlas 300V 24G是一张基于昇腾310P芯片的推理加速卡,主要跑深度学习推理场景,尤其适合视频流分析、目标检测这类任务。“atlas部署yolo”这个热搜词我太熟悉了,因为我去… · 2026/9/25 10:26:36
OpenClaw(龙虾)太消耗token了怎么办?带你挑选性价比最高的Coding Plan(编程套餐)~ /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 10:26:30
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37