news 2026/10/11 0:10:50

Python机器学习全套代码:从数据预处理到模型评估的完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python机器学习全套代码:从数据预处理到模型评估的完整流程

简介:面向数据建模与机器学习初学者的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', encoding='utf-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 # 所有数值列画直方图,bins=30 对大多数场景够用 df[num_cols].hist(bins=30, 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, cmap='RdBu_r', annot=False, vmin=-1, vmax=1) plt.show() # 把与目标列相关性最高的前十名打印出来 target_col = 'y' corr_with_target = corr[target_col].abs().sort_values(ascending=False) 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', axis=1) y = df['y'] # test_size=0.2 即留 20% 做测试;random_state 固定切分结果 # stratify=y 是在分类任务里按类别比例分层抽样,必须加 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y )

三个值得解释的参数: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_iter=1000, random_state=42), 'rf': RandomForestClassifier(n_estimators=200, random_state=42), 'xgb': XGBClassifier(n_estimators=200, max_depth=6, random_state=42, eval_metric='logloss') } # 所有 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_iter=1000是逻辑回归的迭代上限,默认 100 在小数据集上偶尔不收敛,会报警告;n_estimators是树的数量,200 到 300 之间对大多数表格数据效果稳定,再往上收益递减且训练时间翻倍;random_state在树模型里同样重要,不固定的话随机森林每次使用的特征子集和样本子集都不一样。

XGBClassifier里的eval_metric='logloss'是 XGBoost 2.0 之后要求显式指定的,旧代码里没有这个参数会在训练时被警告或直接报错,这一点在升级库版本后容易踩到。

3.3 回归与聚类:评估方式和预处理习惯完全不一样

回归任务看重的是预测值和真实值之间的误差量级,代码可以复用上面的建模骨架,但评估指标要换。很多新人把分类的score(准确率)直接用在回归上,得到的是 R²,理解上容易出错,下面这段是把回归建模和评估一起写完。

from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error, r2_score model = RandomForestRegressor(n_estimators=200, random_state=42) 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, squared=False))

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_init=10 表示用 10 次不同初始点跑 KMeans,取最优结果 kmeans = KMeans(n_clusters=5, random_state=42, n_init=10) labels = kmeans.fit_predict(X_scaled) print('轮廓系数:', silhouette_score(X_scaled, labels))

n_clusters的选取本身是个开放问题,不是拍脑袋定。常见做法是让 k 从 2 到 10 循环跑一遍,画出轮廓系数随 k 变化的曲线,取拐点位置的 k 值。n_init=10是 sklearn 新版本的默认行为,但旧版本默认值不同,显式写出来更保险。标准化这一步在聚类里是必须的,因为 KMeans 用的是欧氏距离,收入(几万)和年龄(几十)直接放在一起,年龄对距离的贡献会被收入完全淹没。

4. 模型评估与参数调优代码:让结果可信、可复现、能解释

模型跑出一个分数不代表结束,数据建模与分析的下半场是评估和调参。很多时候模型在测试集上分数高,换一批数据就垮了;或者同一条代码跑两遍,结果对不上。这章讲怎么用交叉验证稳住评估结果,怎么选对评估指标,以及怎么让调参不再靠感觉。

4.1 交叉验证:单次切分的分数是抽样运气

单次 train_test_split 的评估结果,受随机切分的影响很大。尤其当数据集只有几千行时,换一个random_state,AUC 可能波动 5 个百分点以上。交叉验证的思路是把数据切成 k 份,轮流拿其中一份做验证、其余 k-1 份做训练,最后取 k 次分数的平均值。

from sklearn.model_selection import StratifiedKFold, cross_val_score from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier(n_estimators=200, random_state=42) # StratifiedKFold:分类任务里的分层 k 折,保证每折类别比例一致 cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) scores = cross_val_score(model, X, y, cv=cv, scoring='f1') print('每折分数:', scores) print('平均分:', scores.mean(), '±', scores.std())

n_splits=5是最常见的默认选择,5 折既能让每次训练集足够大,又能把方差控制住;shuffle=True必须在交叉验证前打乱数据,否则原始数据里如果按时间排序,每一折的分布会系统性偏移,做出来的结果时好时坏。打印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 默认没有这个接口,需要先设置probability=True。

4.3 网格搜索调参:别全凭手感,先粗调再精调

调参是数据建模与分析里最像“玄学”的部分。有经验的工程师不会直接对十几个参数做笛卡尔积搜索,而是分两轮:先用随机搜索(RandomizedSearchCV)粗扫出值得关注的参数区间,再在小区间上用网格搜索做细调。网格搜索和随机搜索的代码骨架几乎一样,只差一个参数。

from sklearn.model_selection import GridSearchCV # 参数网格:只放你最关心的 2~3 个参数 # 笛卡尔积数量=3*3*3=27 次组合,每次都跑 5 折交叉验证 param_grid = { 'n_estimators': [100, 200, 300], 'max_depth': [5, 8, 12], 'min_samples_leaf': [1, 2, 4] } gs = GridSearchCV( RandomForestClassifier(random_state=42), param_grid, cv=StratifiedKFold(5, shuffle=True, random_state=42), scoring='f1', n_jobs=-1 ) gs.fit(X, y) print('最优参数:', gs.best_params_) print('交叉验证最优分数:', gs.best_score_)

n_jobs=-1表示用满所有 CPU 核心,表格数据规模下能显著加快搜索;scoring='f1'让搜索过程的评估口径与业务目标一致,不能用默认 accuracy;best_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_state=42) 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、recall@topK),给少数类加权重(class_weight='balanced'),或者做上采样/下采样。我一般先用class_weight再看指标,这行代码能省很多事。

model = RandomForestClassifier( n_estimators=200, class_weight='balanced', random_state=42 )

class_weight='balanced'会让 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_size=0.2, random_state=SEED, stratify=y ) model = RandomForestClassifier(n_estimators=200, random_state=SEED) cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED)

我的习惯是把这个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', dtype=dtype_dict) print(df.memory_usage(deep=True).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 :lang=zh命令看系统装了哪些中文字体,然后把可用字体名字填进列表首位。这个坑对数据建模与分析的前期探索影响不大,但到给业务方出报表时是必踩的,早配置早省心。

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_state=42)) ]) pipe.fit(X_train, y_train)

Pipeline 的好处是:预处理和模型绑定在一起,交叉验证时每一折都会自动在折内重新执行 scaler 和模型训练,从代码结构上杜绝了 5.1 节那种数据泄漏。

第二个操作:先用 DummyClassifier 建立基线。任何数据建模项目,第一个跑的模型应该是最普通的“无脑策略”模型,而不是随机森林或 XGBoost。

from sklearn.dummy import DummyClassifier base = DummyClassifier(strategy='most_frequent') base.fit(X_train, y_train) print('基线准确率:', base.score(X_test, y_test))

如果最厉害的模型连“全猜多数类”都没赢过多少,先别调参,回头查预处理和数据泄漏。我之前有次把一个不均衡数据集调了一整晚,后来发现连基线模型都能到 95% 准确率,才意识到是数据泄漏,再回去查,果然是在划分前就做了标准化。一个 DummyClassifier 能在第一天就替我拦下这类问题。

第三个操作:让输出结果自动化。每跑完一轮模型,把关键指标连同数据特征名、模型参数、时间戳写进一个结果文件(CSV 或 JSON)。这样每一次实验都有迹可循,调参不是调完就忘,下次项目可以直接复用之前的搜索结果。做量化交易策略因子筛选时,我也是用这套骨架——把因子表换成业务表,评估指标换成夏普比率,流程完全一样。

说到底,这套 Python 机器学习全套代码真正能沉淀下来的,是那种拿到任何表格数据都能按固定顺序排错的能力:先跑通流程,再追求效果;先保证结果可信,再去调参。我吃过的亏基本都出在流程没走通就急着上模型,后来每个项目都先建基线、再交叉验证,效率反而高了。希望帮到你。

本文还有配套的精品资源,点击获取

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

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

作者头像 李华
网站建设 2026/10/10 23:52:11

Java实现冰岛人家族关系判断:五代以内共同祖先算法与PTA满分代码

PTA团体程序设计天梯赛的L2-030《冰岛人》是一道看似简单、实则边界极多的家族关系判断题,尤其在Java提交时,稍不注意就会超时或者被“五代以内”这个说法带偏。这篇文章把我从读题、设计数据结构、到最终Java满分通过的全过程完整拆开,重点说…

作者头像 李华
网站建设 2026/10/10 23:51:56

土豆目标检测数据集:YOLO与VOC双格式实战指南

简介:本资源是面向农业AI与目标检测初学者及实践者的土豆目标检测专用数据集,适用于YOLO系列、Faster R-CNN等主流检测模型的训练与验证,可支撑智能分拣、田间监测、品质分级等实际场景建模。压缩包共310个文件,含152张JPEG图像、…

作者头像 李华
网站建设 2026/10/10 23:42:36

小狗情绪图像识别数据集:工业级小样本视觉训练闭环

简介:本资源是一套专为图像分类任务设计的小狗情绪识别数据集,面向计算机视觉初学者与深度学习实践者,解决细粒度动物情绪分类建模中的数据获取与可视化验证难题。压缩包共2000个文件,含1998张JPG格式情绪图像(按angry…

作者头像 李华
网站建设 2026/10/10 23:29:26

Serverless 冷启动 + Orleans 虚拟 Actor:Agent Substrate 的架构血统考

Serverless 冷启动 Orleans 虚拟 Actor:Agent Substrate 的架构血统考 【免费下载链接】substrate Agent Substrate: the core system 项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate 一个看似矛盾的事实正在改写云原生的资源模型&am…

作者头像 李华