简介面向数据建模与机器学习初学者的Python代码资源包系统覆盖广义可加模型GAM、梯度提升决策树GBDT、分类回归树CART、BP神经网络和深度神经网络DNN等常用算法每个模型都附带独立数据集并配有从数据读取、训练到验证的完整代码记录。压缩包共184个文件以117个ipynb可执行脚本为主体另有35个csv数据文件、xlsx表格、txt说明、png可视化图和少量zip/json辅助文件整体大小约304.19MB结构清晰便于对照学习。代码刻意保留训练过程中的关键调参环节帮助理解不同模型在不同数据上的表现差异无论是回归、分类还是非线性拟合问题都能从中找到对应模板并快速改造使用。适合想系统掌握模型选择与参数优化、并动手复现经典算法的学习者。目前已有110人学习下载是一份可直接运行、覆盖面广的数据建模实操合集。1. 一套能跑的Python机器学习全套代码解决的是“建模流程”而不只是“单个算法”做数据建模与分析听起来难在算法实际做起来全耗在一条看不见的流程上数据怎么清洗、特征怎么处理、训练测试集怎么切、模型怎么评估怎么调参。网上单段算法示例到处都是真拿自己的数据集一跑总在流程的某个缝里翻车。“Python机器学习全套代码”的价值不是某个算法脚本而是把数据建模与分析拆成带边界、带参数、带验证方法的标准流程让你照着骨架处理任何业务表。这份代码适合三类人做数据分析要建模型的工程师、做课程设计的学生、准备转算法岗的入门者。你要的不是背一个模型而是拿到一份能改、能复现、能排错的代码体系。下面按实际使用顺序讲读数据、预处理、建模、评估再单独排一遍坑最后讲怎么沉淀成自己的工具箱。2. 数据预处理与可视化代码建模前八成的坑都埋在这里很多现成代码包里预处理脚本是最容易被跳过的部分。因为单看一段随机森林代码好像数据直接喂进去也能出结果。真到了数据建模与分析的项目里脏数据会让模型指标忽高忽低你今天调通的参数明天换个表就失效。所以我会把完整代码拆成“先看数据、再处理缺失、再做特征”三步每一步都有对应的代码骨架。2.1 数据加载与缺失值处理三步把一张脏表理成干净表import pandas as pd import numpy as np # 读 CSV 时先显式指定编码UTF-8 的文件常见报错是 GBK 编码 df pd.read_csv(raw_data.csv, encodingutf-8) print(行列数:, df.shape) print(字段类型:\n, df.dtypes) print(缺失值统计:\n, df.isnull().sum())读进来之后第一件事永远不是建模而是确认这张表到底长什么样。df.shape看行列数能第一时间发现是不是读错了文件dtypes看字段类型很多“看起来是数字”的列其实是字符串这类问题在后面建模时会以报错形式冒出来isnull().sum()看缺失分布这里会直接决定下一步用哪种填充策略。# 按列类型分开处理数值列和类别列的填充策略完全不同 num_cols df.select_dtypes(include[float64, int64]).columns cat_cols df.select_dtypes(include[object]).columns for col in num_cols: # 中位数填充对离群点不敏感比均值更稳 df[col] df[col].fillna(df[col].median()) for col in cat_cols: # 众数填充避免训练时没见过的类别在验证阶段出现 df[col] df[col].fillna(df[col].mode()[0])数值列我基本优先用中位数而不是均值。均值会被极端值拉偏比如收入列有个别千万级异常值均值会显著上移导致缺失值填充后整列分布变形。中位数对这种场景更稳。类别列用众数出现最多的值是常见做法实际业务里缺失往往只是“没填”用众数补对模型的影响最小。这段代码放在任何建模任务前面都能跑直接照抄改列名就行。如果刚装完 Python 还没配依赖在终端里执行一行pip install numpy pandas matplotlib seaborn就能把这一整套数据处理的库补齐。Windows 上装完 Python 记得勾选 “Add Python to PATH”否则执行pip会提示找不到命令这一步卡住不少刚入门的人。2.2 特征分布检查画图是最快的错误探测器预处理做完不急着建模先画图看分布。这一步在一线做项目时价值极高很多数据问题用统计量发现不了画图一眼就能看出来。看分布能发现偏态、离群点和脏值。import matplotlib.pyplot as plt # 所有数值列画直方图bins30 对大多数场景够用 df[num_cols].hist(bins30, figsize(12, 8)) plt.tight_layout() plt.show()直方图里最典型的翻车现场是某个特征呈现极端右偏长尾巴拖到右边说明这列数据有大量小值和少数极大值或者干脆混入了脏数据。比如交易金额列有负数和 0 混在里面直方图上会出现一个孤立长条这时需要单独处理而不是让模型去硬学这个分布。# 右偏严重的数值列用 log1p 压缩量级 # log1p 对 0 值也能计算出结果比 log 更稳 skewed_cols [amount, income] for col in skewed_cols: df[col _log] np.log1p(df[col])log1p计算的是ln(1 x)好处是 x 为 0 时结果也是 0不会出现log(0)的负无穷。做完变换后再画一次直方图分布会变得像钟形这类特征喂给线性模型和距离类模型时效果会明显变好。树模型对单调变换不敏感但做特征工程时统一处理没坏处。2.3 相关性矩阵选特征前先看这张热力图import seaborn as sns # 只对数值列算相关性pandas 会自动跳过非数值列 corr df.select_dtypes(include[np.number]).corr() plt.figure(figsize(12, 10)) sns.heatmap(corr, cmapRdBu_r, annotFalse, vmin-1, vmax1) plt.show() # 把与目标列相关性最高的前十名打印出来 target_col y corr_with_target corr[target_col].abs().sort_values(ascendingFalse) print(与目标列相关性最高的特征:\n, corr_with_target.head(11))相关性热力图回答两个问题第一哪些特征和目标列强相关这决定了建模的第一轮特征候选第二哪些特征彼此强相关也就是多重共线性。如果两列特征的相关系数超过 0.95树模型能容忍线性回归会直接摊上系数不稳定逻辑回归的特征权重也会变得不可解释。遇到高相关的特征组我的做法是保留业务上最合理的那个其余的先剔除。注意corr()只能捕捉线性关系。特征与目标之间的关系如果是 U 形、台阶形的相关性数字会很低但不代表特征没用。所以相关性矩阵只做第一轮粗筛别用它做最终判定。3. 算法建模代码把分类、回归、聚类统一成一套能改参数的骨架任何机器学习项目的数据建模与分析最终都会落到算法选择上。但算法选择在工程上不是“哪个最高级用哪个”而是“先用便宜的模型建立基准再看复杂模型能不能赢过基准”。这个思路贯穿这章的代码组织方式。3.1 数据划分train_test_split 里的两个隐藏参数在跑任何模型之前先把训练集和测试集分好。这一步看似简单却是整个建模流程里最容易写错的地方。from sklearn.model_selection import train_test_split X df.drop(y, axis1) y df[y] # test_size0.2 即留 20% 做测试random_state 固定切分结果 # stratifyy 是在分类任务里按类别比例分层抽样必须加 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy )三个值得解释的参数test_size决定留多少数据做验证小数据集几千行可以留 30%大数据集 10% 就够random_state决定切分的随机种子不固定的话每次运行切出的训练测试集都不同指标也就跟着跳stratify分层抽样只用于分类问题它保证训练集和测试集里的正负样本比例与原始数据一致否则当正样本只有 5% 时随手一切有可能把测试集切得一个正样本都没有。回归任务里没有类别比例的概念所以stratify不能传但random_state一样要固定。时间序列数据要注意不能随机打乱切分得按时间先后切否则等于用未来数据训练、预测过去指标会虚高得离谱。3.2 分类建模代码逻辑回归先跑通再换树模型分类任务是机器学习检测类需求里最常见的形式垃圾检测、异常检测、风险检测本质都是二分类。我的习惯是先跑一个最朴素的逻辑回归当基准再跑随机森林和 XGBoost 对比。from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from xgboost import XGBClassifier models { lr: LogisticRegression(max_iter1000, random_state42), rf: RandomForestClassifier(n_estimators200, random_state42), xgb: XGBClassifier(n_estimators200, max_depth6, random_state42, eval_metriclogloss) } # 所有 sklearn 模型接口统一fit 训练、score 返回准确率 for name, model in models.items(): model.fit(X_train, y_train) acc model.score(X_test, y_test) print(f{name}: acc{acc:.4f})scikit-learn 统一了fit/predict/score接口这段代码可以塞进任何模型。max_iter1000是逻辑回归的迭代上限默认 100 在小数据集上偶尔不收敛会报警告n_estimators是树的数量200 到 300 之间对大多数表格数据效果稳定再往上收益递减且训练时间翻倍random_state在树模型里同样重要不固定的话随机森林每次使用的特征子集和样本子集都不一样。XGBClassifier里的eval_metriclogloss是 XGBoost 2.0 之后要求显式指定的旧代码里没有这个参数会在训练时被警告或直接报错这一点在升级库版本后容易踩到。3.3 回归与聚类评估方式和预处理习惯完全不一样回归任务看重的是预测值和真实值之间的误差量级代码可以复用上面的建模骨架但评估指标要换。很多新人把分类的score准确率直接用在回归上得到的是 R²理解上容易出错下面这段是把回归建模和评估一起写完。from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score model RandomForestRegressor(n_estimators200, random_state42) model.fit(X_train, y_train) y_pred model.predict(X_test) print(R2:, r2_score(y_test, y_pred)) print(RMSE:, mean_squared_error(y_test, y_pred, squaredFalse))R² 的含义是模型解释了目标变量多少比例的方差0.9 意思是目标值的波动有 90% 被特征解释RMSE 带有原始目标的单位比如预测房价就是“误差平均几万元”。实际落到业务里RMSE 比 R² 更好沟通因为它能直接换算成钱或周转量。回归模型在训练前对特征做标准化StandardScaler不是必须的树模型对量纲不敏感但如果后面要加线性回归就需要统一缩放。聚类没有真实标签建模流程和数据划分都要调整。from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score # 聚类前必须做标准化否则量纲大的特征主导距离计算 scaler StandardScaler() X_scaled scaler.fit_transform(X) # n_init10 表示用 10 次不同初始点跑 KMeans取最优结果 kmeans KMeans(n_clusters5, random_state42, n_init10) labels kmeans.fit_predict(X_scaled) print(轮廓系数:, silhouette_score(X_scaled, labels))n_clusters的选取本身是个开放问题不是拍脑袋定。常见做法是让 k 从 2 到 10 循环跑一遍画出轮廓系数随 k 变化的曲线取拐点位置的 k 值。n_init10是 sklearn 新版本的默认行为但旧版本默认值不同显式写出来更保险。标准化这一步在聚类里是必须的因为 KMeans 用的是欧氏距离收入几万和年龄几十直接放在一起年龄对距离的贡献会被收入完全淹没。4. 模型评估与参数调优代码让结果可信、可复现、能解释模型跑出一个分数不代表结束数据建模与分析的下半场是评估和调参。很多时候模型在测试集上分数高换一批数据就垮了或者同一条代码跑两遍结果对不上。这章讲怎么用交叉验证稳住评估结果怎么选对评估指标以及怎么让调参不再靠感觉。4.1 交叉验证单次切分的分数是抽样运气单次 train_test_split 的评估结果受随机切分的影响很大。尤其当数据集只有几千行时换一个random_stateAUC 可能波动 5 个百分点以上。交叉验证的思路是把数据切成 k 份轮流拿其中一份做验证、其余 k-1 份做训练最后取 k 次分数的平均值。from sklearn.model_selection import StratifiedKFold, cross_val_score from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier(n_estimators200, random_state42) # StratifiedKFold分类任务里的分层 k 折保证每折类别比例一致 cv StratifiedKFold(n_splits5, shuffleTrue, random_state42) scores cross_val_score(model, X, y, cvcv, scoringf1) print(每折分数:, scores) print(平均分:, scores.mean(), ±, scores.std())n_splits5是最常见的默认选择5 折既能让每次训练集足够大又能把方差控制住shuffleTrue必须在交叉验证前打乱数据否则原始数据里如果按时间排序每一折的分布会系统性偏移做出来的结果时好时坏。打印scores.std()是个好习惯如果标准差超过 0.05说明模型对数据划分非常敏感这时优先怀疑的是数据里有离群点或类别不平衡而不是继续加参数。注意交叉验证的对象是“整个建模流程”不是“某个模型”。如果流程里包含特征选择特征选择也必须在每一折内部单独做否则特征选择过程“看过”了验证集的分布这种数据泄漏会让交叉验证分数虚高。下一章我会专门讲这个问题。时间序列数据的交叉验证不能用StratifiedKFold得用TimeSeriesSplit它的切分方式是训练集永远在测试集前面模拟真实回测的环境。这一点在量化交易策略、销量预测里非常重要用普通KFold会让模型看到未来的数据看起来分数很好实盘一跑就翻车。4.2 评估指标分类别只看准确率回归别只报 R²评估指标的选择直接决定“这个模型是不是真的能用”。下面是不同任务常用指标和它们各自适合的场景。任务类型常用指标适合场景新手的常见误区分类accuracy类别均衡、误分类代价一致类别不平衡时直接用失真分类precision / recall / F1正样本稀有或误分类代价不对称只报 F1 不报混淆矩阵分析不了错在哪分类AUC-ROC需要排序能力、样本不平衡把 AUC 当普适指标实际业务更关注阈值附近的精确率回归R²衡量拟合优度时单看 R² 不看残差掩盖异方差回归RMSE / MAE需要带业务单位的误差RMSE 受大误差项主导跟业务方沟通时被大离群点带偏聚类轮廓系数评估聚类紧密度和分离度直接在原始特征上算量纲没缩放导致结果失真表格里最值得展开的是分类任务。实际分类项目里正负样本配比几乎从来不均衡比如风险检测中正常的样本可能占 98%。这时 accuracy 会给出一种“模型很厉害”的假象模型把所有样本都预测为负类准确率照样 98%但业务要的是把少数异常找出来。from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score y_pred model.predict(X_test) y_prob model.predict_proba(X_test)[:, 1] print(classification_report(y_test, y_pred)) print(混淆矩阵:\n, confusion_matrix(y_test, y_pred)) print(AUC:, roc_auc_score(y_test, y_prob))classification_report会同时打印 precision、recall、F1 和支持样本数三类数字一起看才能判断模型偏在哪边confusion_matrix是 2x2 矩阵左上右上分别是真正例和假负例右下左下是假正例和真负例具体业务关注哪一格就把哪一格的权重提到前面predict_proba输出的概率分数比硬分类更细AUC 用概率计算能绕过阈值选择的影响。predict_proba的结果是多列二分类里取[:, 1]表示正类的概率。注意predict_proba只有带概率输出接口的模型才有部分 SVM 默认没有这个接口需要先设置probabilityTrue。4.3 网格搜索调参别全凭手感先粗调再精调调参是数据建模与分析里最像“玄学”的部分。有经验的工程师不会直接对十几个参数做笛卡尔积搜索而是分两轮先用随机搜索RandomizedSearchCV粗扫出值得关注的参数区间再在小区间上用网格搜索做细调。网格搜索和随机搜索的代码骨架几乎一样只差一个参数。from sklearn.model_selection import GridSearchCV # 参数网格只放你最关心的 2~3 个参数 # 笛卡尔积数量3*3*327 次组合每次都跑 5 折交叉验证 param_grid { n_estimators: [100, 200, 300], max_depth: [5, 8, 12], min_samples_leaf: [1, 2, 4] } gs GridSearchCV( RandomForestClassifier(random_state42), param_grid, cvStratifiedKFold(5, shuffleTrue, random_state42), scoringf1, n_jobs-1 ) gs.fit(X, y) print(最优参数:, gs.best_params_) print(交叉验证最优分数:, gs.best_score_)n_jobs-1表示用满所有 CPU 核心表格数据规模下能显著加快搜索scoringf1让搜索过程的评估口径与业务目标一致不能用默认 accuracybest_score_是交叉验证的平均分best_params_是最优参数组合。网格搜索的问题在于参数组合数呈指数增长如果你加 5 个参数、每个 5 个候选值就是 3125 次训练普通笔记本跑上一夜很正常。先跑 RandomizedSearchCV参数用分布而不是列表比如n_estimators: randint(50, 500)扫 50 组可以花同样的时间覆盖更大的参数空间。搜索结束后拿最优参数在之前切好的测试集上跑一遍确认测试集的分数和交叉验证的分数差距不大。如果交叉验证 0.85、测试集 0.82是正常波动如果测试集 0.72说明搜索过程过拟合了交叉验证的划分这时优先怀疑数据量太小或正样本太少。5. 避坑数据建模与分析里最常见的 6 个翻车点这章每一节都是我在实际项目里遇到过的状况按“现象 → 原因 → 解决”整理。遇到类似问题先对照现象定位原因再套用解决方案能少走很多弯路。5.1 训练分数高得离谱先查数据泄漏现象模型在测试集上的准确率接近 99%但业务评估完全达不到这个水平。原因八成是数据泄漏。最常见的一个错误是在做 train_test_split 之前先对整个数据集做了缺失值填充或标准化。这一步让median()、StandardScaler的均值和方差在整个数据集上计算其中包含了测试集的信息等于把“答案”的一部分泄露给了训练过程。特征选择也一样在划分前跑了一遍相关性筛选再交叉验证筛选过程已经把测试集的结构看完了。解决方法是把“预处理 特征选择 建模”放进每一折内部先划分后处理。# 错误顺序先标准化再划分数据泄漏 # scaler StandardScaler() # X_scaled scaler.fit_transform(X) # X_train, X_test train_test_split(X_scaled, ...) # 正确顺序先划分scaler 只在训练集上 fit X_train, X_test, y_train, y_test train_test_split(X, y, random_state42) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 只 transform不 fit注意scaler.transform(X_test)这行不能多写一个fit_transform。一旦对测试集调用了fit_transform均值方差就被测试集重新计算一次标准化的含义就变了。这类问题最隐蔽的是“看着每行代码都没问题但合在一起就把测试集用了一遍”。5.2 样本不均衡准确率 95% 的模型可能一个正样本都没抓到现象分类报告里 precision 很高recall 很低比如 0.98 和 0.03再看混淆矩阵模型几乎把所有样本都判成了负类。原因类别不均衡。比如异常检测任务正样本只占 2%默认用 accuracy 做优化目标时模型发现“全判负类”就有 98% 的准确率这个行为在数学上是最优的但在业务上毫无价值。解决这个问题有几个层次换评估指标F1、AUC、recalltopK给少数类加权重class_weightbalanced或者做上采样/下采样。我一般先用class_weight再看指标这行代码能省很多事。model RandomForestClassifier( n_estimators200, class_weightbalanced, random_state42 )class_weightbalanced会让 sklearn 按类别的反比自动调整权重少数类的样本在损失函数里占更大的比重。这个参数只影响训练过程不影响预测接口指标立刻就能看到变化。如果加了权重后 recall 还是没有业务可接受的水平再考虑 SMOTE 这类合成少数类样本的方法但注意 SMOTE 也可能放大噪声且只能用于表格数据。5.3 特征缩放树模型不需要逻辑回归和 KNN 必须要现象随机森林跑出来的 AUC 还行换成逻辑回归或 KNN 后效果明显变差分数惨不忍睹。原因量纲问题。逻辑回归的梯度下降和 KNN 的距离计算都对特征的尺度敏感。收入列的值域是几千到几十万年龄列是 0 到 100两者放在一起距离计算几乎被收入完全主导年龄的特征贡献被吃掉。随机森林这类树模型做的是阈值切分对单调变换不敏感所以不需要缩放很多新人因此误以为“所有模型都不需要缩放”。解决方法是凡是基于距离、梯度、正则化的算法统一先做StandardScaler。StandardScaler把每列变成均值为 0、标准差为 1对存在离群点的数据相对稳定。如果数据是稀疏的大量 0 值改用MinMaxScaler更合适因为标准化会把稀疏结构破坏掉。聚类、PCA、KNN、SVM 这些算法一律先缩放再训练。5.4 随机种子不固定同一条代码两次跑结果不一样现象代码没动同一份数据上午跑出 AUC 0.85下午跑出 0.83还以为模型有 bug。原因机器学习流程里到处都是随机性。train_test_split的打乱是随机的、随机森林的样本抽样是随机的、KMeans 的初始点是随机的、神经网络的权重初始化也是随机的任何一步不固定最终结果就跳。交叉验证里还有一个隐藏坑StratifiedKFold如果不传random_state每次划分的折也不一样。解决方法是项目一开始就统一定义种子并且所有用到随机性的地方都显式传入。SEED 42 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_stateSEED, stratifyy ) model RandomForestClassifier(n_estimators200, random_stateSEED) cv StratifiedKFold(n_splits5, shuffleTrue, random_stateSEED)我的习惯是把这个SEED定义放在脚本最顶部后面所有地方都引用它。一旦需要复现某次实验只要把SEED的值记下来整个结果就能重现。别不同模块用不同的种子那样会跳过“能复现”这道保险。5.5 数据量一大内存就爆float64 是隐形杀手现象几百万行的 CSV 读进来内存直接飙升到十几个 G机器卡死甚至进程被杀。原因pandas 默认把所有数值列都读成 float64/int64每列 8 字节。一个 500 万行、200 列的表光数值部分就是 8GB加上中间过程的副本很容易超过内存上限。解决方法是读入时直接指定 dtype把精度需求不高的列降成 float32把整数列降成 int32。多数建模场景下 float32 的精度完全够用模型指标差异可以忽略。dtype_dict { price: float32, quantity: int32, user_id: int32 } df pd.read_csv(large_data.csv, dtypedtype_dict) print(df.memory_usage(deepTrue).sum() / 1024 / 1024, MB)如果文件列太多先只读需要的列pd.read_csv(..., usecols[col1, col2])。对已经读进来的 DataFrame可以用df.astype(float32)事后转换。内存优化这件事看起来和模型效果无关但数据量大到跑不动时它决定了你能不能继续做下去。5.6 画图中文乱码和负号变方块一行配置解决现象Matplotlib 画的图中文标签变成一个个方框负号变成小短线截图发给业务方差点闹笑话。原因Matplotlib 默认字体里没有中文字形同时默认关闭了 Unicode 负号渲染导致中文和负数全部显示异常。解决方法是画图前统一设置 rcParams。Windows 上直接指定 SimHei 字体即可Mac 或 Linux 上可以指定系统中已有的中文字体路径。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False这段配置放在脚本最前面所有后续画图都生效。如果在公司服务器上跑代码服务器可能没装 SimHei这时用fc-list :langzh命令看系统装了哪些中文字体然后把可用字体名字填进列表首位。这个坑对数据建模与分析的前期探索影响不大但到给业务方出报表时是必踩的早配置早省心。6. 把这套代码沉淀成你自己的建模工具箱三个成本最低的进阶操作前面五章是一套能跑的流程这一章讲怎么把它变成你以后每个项目都能直接调用的东西。纯复制粘贴没有沉淀价值等下一个项目真的来了你还要重新翻旧代码。我一般会做三个操作每个都只需要半小时。第一个操作把流程函数化。建模流程不是一个线性脚本而是数据清洗、划分、训练、评估这几个独立步骤每个步骤写成函数输入输出都是明确的 DataFrame 和模型对象。以后遇到新项目直接import或复制函数来组装新流程而不是从头到尾重写一遍。实操时我习惯把基础函数放进一个modeling_utils.py跑新项目时from modeling_utils import train_classifier, evaluate_binary。from sklearn.pipeline import Pipeline # 把预处理和模型装进一条流水线fit 和 predict 统一调用 # 这一条对防止数据泄漏尤其有用 pipe Pipeline([ (scaler, StandardScaler()), (clf, RandomForestClassifier(random_state42)) ]) pipe.fit(X_train, y_train)Pipeline 的好处是预处理和模型绑定在一起交叉验证时每一折都会自动在折内重新执行 scaler 和模型训练从代码结构上杜绝了 5.1 节那种数据泄漏。第二个操作先用 DummyClassifier 建立基线。任何数据建模项目第一个跑的模型应该是最普通的“无脑策略”模型而不是随机森林或 XGBoost。from sklearn.dummy import DummyClassifier base DummyClassifier(strategymost_frequent) base.fit(X_train, y_train) print(基线准确率:, base.score(X_test, y_test))如果最厉害的模型连“全猜多数类”都没赢过多少先别调参回头查预处理和数据泄漏。我之前有次把一个不均衡数据集调了一整晚后来发现连基线模型都能到 95% 准确率才意识到是数据泄漏再回去查果然是在划分前就做了标准化。一个 DummyClassifier 能在第一天就替我拦下这类问题。第三个操作让输出结果自动化。每跑完一轮模型把关键指标连同数据特征名、模型参数、时间戳写进一个结果文件CSV 或 JSON。这样每一次实验都有迹可循调参不是调完就忘下次项目可以直接复用之前的搜索结果。做量化交易策略因子筛选时我也是用这套骨架——把因子表换成业务表评估指标换成夏普比率流程完全一样。说到底这套 Python 机器学习全套代码真正能沉淀下来的是那种拿到任何表格数据都能按固定顺序排错的能力先跑通流程再追求效果先保证结果可信再去调参。我吃过的亏基本都出在流程没走通就急着上模型后来每个项目都先建基线、再交叉验证效率反而高了。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?