资讯动态

Python机器学习分类实战:决策树、朴素贝叶斯与神经网络对比

发布时间:2026/9/28 18:27:22 来源:尧图企业网站定制
简介这份资源面向希望系统入门机器学习分类算法的Python学习者与数据分析初学者围绕决策树、朴素贝叶斯与人工神经网络三种经典分类算法提供可直接运行的代码与配套数据帮助读者在动手实践中理解算法原理并完成从建模到结果分析的完整流程。压缩包共3个文件包含1个ipynb笔记本、1个py脚本和1个csv数据集整体约119KB其中笔记本适合在Jupyter Notebook中分步调试与观察输出脚本便于快速复用csv数据则用于股票价格波动分析的实战案例。资源覆盖决策树与贝叶斯分类的原理及代码实现、人工神经网络分类算法以及股票价格波动分析这一具体场景的实操演练读者可据此掌握数据预处理、模型训练、分类预测与效果评估等关键环节并对照代码理解各算法的参数设置与调优思路。目前已有5901人学习下载适合作为课程实验、自学练手或项目参考的轻量级实践材料。1. 从一份股票波动数据说起三个分类器怎么选、怎么跑手里这份资源包不大分类算法.zip解压后是四个文件分类算法.ipynb、分类算法.py、a601318.csv外加一份说明。a601318.csv是案例数据围绕股票价格波动做分类两个代码文件是同一套逻辑的两种载体.ipynb适合在 Jupyter Notebook 里逐格跑、看中间输出.py适合直接命令行执行或塞进自己的工程。三个算法分别是决策树、朴素贝叶斯、人工神经网络都是分类任务里最常被拿来对比的基线模型。如果你正在学 Python 机器学习或者想找一个能跑通、能改参数、能看结果的分类实战案例这份资源的价值在于它把「数据 → 特征 → 三个模型 → 结果对比」这条链路完整摆出来了不是孤立的算法片段。下面按「先跑通、再拆原理、最后避坑」的顺序走一遍每一步都落到可复现的命令和参数上。2. 环境与数据把 a601318.csv 喂进三个模型之前2.1 依赖安装与 Jupyter 启动资源里给了.ipynb说明作者默认你用 Jupyter Notebook 跑。常见做法是先用 conda 或 venv 建一个干净环境再装核心三件套pandas、scikit-learn、matplotlib。神经网络部分如果代码里用的是sklearn的MLPClassifier那不需要额外装 TensorFlow 或 PyTorch如果用的是 Keras就得单独装。先按sklearn路线准备跑通后再看代码里实际 import 了什么。# 创建虚拟环境conda 或 venv 二选一 conda create -n cls_demo python3.10 -y conda activate cls_demo # 安装核心依赖 pip install pandas scikit-learn matplotlib jupyter # 启动 Jupyter Notebook浏览器会自动打开 jupyter notebook逻辑说明python3.10是当前scikit-learn兼容性最稳的版本区间之一太新的 Python 有时会让某些 wheel 还没跟上。jupyter notebook启动后把分类算法.ipynb拖进浏览器页面即可打开。如果你更习惯 VS Code装好 Python 扩展后直接右键.ipynb选「在交互窗口中运行」也行效果一样。参数说明-n cls_demo是环境名随便取但建议别用中文。pip install后面跟的四个包matplotlib用于画决策树或混淆矩阵jupyter是 Notebook 运行环境。如果公司网络走内网源把pip install换成pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ...会快很多。2.2 数据加载与字段速览a601318.csv这个文件名里的601318是股票代码格式数据大概率是按交易日排列的行情衍生指标。加载时第一件事不是急着fit而是先看列名、看缺失、看标签分布。import pandas as pd # 读取 CSV注意编码中文环境常见 gbk 或 utf-8 df pd.read_csv(a601318.csv, encodingutf-8) # 看前五行和字段类型 print(df.head()) print(df.dtypes) print(df.shape) # 看缺失值和标签分布假设最后一列是分类标签 print(df.isnull().sum()) print(df.iloc[:, -1].value_counts())逻辑说明encodingutf-8如果报UnicodeDecodeError换成gbk再试这是国内 CSV 最常见的两个编码。df.dtypes能一眼看出哪些列是object类型这些列要么是标签要么需要做编码转换。value_counts()看标签是否均衡如果某一类占了 90% 以上后面准确率再高也没意义得换评估指标。参数说明df.iloc[:, -1]取最后一列作为标签这是很多教学代码的默认约定。如果你的数据标签不在最后一列改成对应列名即可。isnull().sum()返回每列缺失数量缺失超过 30% 的列建议直接删少量缺失可以用均值或中位数填充。2.3 特征与标签的切分逻辑分类任务的核心是把数据切成X特征和y标签。股票波动分析里标签通常是「涨/跌」或「高波动/低波动」这种二分类。切分时注意两点一是别把标签列混进特征二是如果数据有时间顺序别用随机切分否则会引入未来信息。from sklearn.model_selection import train_test_split # 假设最后一列是标签其余是特征 X df.iloc[:, :-1] y df.iloc[:, -1] # 如果特征里有 object 类型先做编码 X pd.get_dummies(X, drop_firstTrue) # 按 8:2 切分random_state 固定保证可复现 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) print(X_train.shape, X_test.shape)逻辑说明pd.get_dummies把类别型特征转成 0/1 哑变量drop_firstTrue避免多重共线性。stratifyy保证训练集和测试集的标签比例一致样本不均衡时尤其重要。random_state42是固定随机种子保证你每次跑出来的切分一样方便对比模型。参数说明test_size0.2是经验值数据量小可以调到 0.3数据量大可以降到 0.1。如果数据本身按时间排列把train_test_split换成按时间点切分比如前 80% 交易日做训练后 20% 做测试这样更贴近实盘逻辑。3. 决策树与朴素贝叶斯两个基线模型的代码拆解3.1 决策树分类器的 fit 与 predict决策树在sklearn里的接口非常统一核心就是DecisionTreeClassifier。资源里的.py文件大概率也是这个写法。关键参数有三个criterion、max_depth、min_samples_split。from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report # 初始化决策树限制最大深度防止过拟合 dt DecisionTreeClassifier( criteriongini, # 分裂标准gini 或 entropy max_depth5, # 树的最大深度 min_samples_split10, # 节点再分裂所需最小样本数 random_state42 ) dt.fit(X_train, y_train) y_pred_dt dt.predict(X_test) print(决策树准确率:, accuracy_score(y_test, y_pred_dt)) print(classification_report(y_test, y_pred_dt))逻辑说明criteriongini是默认值计算基尼不纯度比entropy稍快效果通常差不多。max_depth5是手动限制树深不限制的话树会一直长到每个叶子只有一个样本训练集准确率 100%测试集一塌糊涂。min_samples_split10表示一个节点至少要有 10 个样本才允许继续分裂这也是防过拟合的手段。参数说明max_depth从 3 到 10 逐个试看测试集准确率什么时候开始下降。min_samples_split一般设在 2% 到 5% 的样本量之间。classification_report会输出 precision、recall、f1-score比单看准确率更能反映模型在每一类上的表现。3.2 朴素贝叶斯的假设与适用边界朴素贝叶斯的核心假设是「特征之间相互独立」这个假设在现实中几乎不成立但它依然能跑出不错的结果尤其在文本分类比如朴素贝叶斯垃圾邮件过滤里是经典基线。股票数据里特征之间往往有相关性所以朴素贝叶斯在这里更多是作为对比项而不是最优解。from sklearn.naive_bayes import GaussianNB # 高斯朴素贝叶斯假设特征服从正态分布 nb GaussianNB() nb.fit(X_train, y_train) y_pred_nb nb.predict(X_test) print(朴素贝叶斯准确率:, accuracy_score(y_test, y_pred_nb)) print(classification_report(y_test, y_pred_nb))逻辑说明GaussianNB适合连续型特征它会对每个特征在每个类别下估计均值和方差。如果特征是离散的计数型换成MultinomialNB如果是 0/1 二值特征用BernoulliNB。资源里用的是哪种打开.ipynb看 import 那一行就知道。参数说明GaussianNB只有一个主要参数var_smoothing默认1e-9作用是给方差加一个极小值防止除零。如果特征尺度差异很大先做StandardScaler标准化再喂给GaussianNB否则方差大的特征会主导似然计算。3.3 两个模型的对比与选型建议跑完两个模型后别只看准确率数字。把混淆矩阵和特征重要性一起看才能判断模型是不是真的学到了东西。from sklearn.metrics import confusion_matrix import matplotlib.pyplot as plt # 混淆矩阵 print(决策树混淆矩阵:\n, confusion_matrix(y_test, y_pred_dt)) print(朴素贝叶斯混淆矩阵:\n, confusion_matrix(y_test, y_pred_nb)) # 决策树特征重要性 importances pd.Series(dt.feature_importances_, indexX.columns) print(importances.sort_values(ascendingFalse).head(10))逻辑说明混淆矩阵的四个格子分别是 TN、FP、FN、TP。如果 FN 特别高说明模型把「正类」漏掉了在股票场景里可能意味着漏掉了该买的信号。feature_importances_只有树模型有它告诉你哪些特征对分裂贡献最大如果前三个特征占了 90% 的重要性可以考虑做特征筛选。参数说明head(10)只看前 10 个重要特征避免输出太长。如果发现某个特征重要性异常高但业务上说不通检查是不是数据泄漏比如把未来价格不小心当成了特征。4. 人工神经网络MLPClassifier 的参数与训练节奏4.1 网络结构怎么定hidden_layer_sizes 的试错sklearn的MLPClassifier是一个多层感知机适合中小规模数据。资源里如果用的是 Keras逻辑类似但sklearn版本更轻量不用装深度学习框架。核心参数是hidden_layer_sizes它是一个元组每个数字代表一层隐藏层的神经元数量。from sklearn.neural_network import MLPClassifier from sklearn.preprocessing import StandardScaler # 神经网络对尺度敏感先标准化 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 两层隐藏层分别 64 和 32 个神经元 mlp MLPClassifier( hidden_layer_sizes(64, 32), activationrelu, solveradam, max_iter500, random_state42 ) mlp.fit(X_train_scaled, y_train) y_pred_mlp mlp.predict(X_test_scaled) print(神经网络准确率:, accuracy_score(y_test, y_pred_mlp))逻辑说明StandardScaler把每个特征变成均值 0、方差 1这是神经网络训练的标配不做的话梯度下降会非常慢甚至不收敛。hidden_layer_sizes(64, 32)表示两层第一层 64 个神经元第二层 32 个。activationrelu是默认激活函数计算快、效果稳。solveradam是自适应学习率优化器比sgd省心。参数说明max_iter500是最大迭代次数默认 200 有时不够会报ConvergenceWarning。如果数据量小hidden_layer_sizes从(10,)开始试数据量大再往上加。层数不是越多越好两层通常够用三层以上容易过拟合且训练慢。4.2 训练过程监控与早停神经网络训练最怕两件事不收敛和过拟合。MLPClassifier提供了loss_curve_属性可以画出损失下降曲线直观判断训练状态。import matplotlib.pyplot as plt # 画损失曲线 plt.plot(mlp.loss_curve_) plt.xlabel(Iteration) plt.ylabel(Loss) plt.title(MLP Training Loss) plt.show() # 开启早停验证集分数不提升就停 mlp_es MLPClassifier( hidden_layer_sizes(64, 32), early_stoppingTrue, validation_fraction0.1, n_iter_no_change10, max_iter500, random_state42 ) mlp_es.fit(X_train_scaled, y_train) print(早停后准确率:, accuracy_score(y_test, mlp_es.predict(X_test_scaled)))逻辑说明loss_curve_是每次迭代的损失值正常情况应该是一条下降然后趋于平缓的曲线。如果曲线震荡剧烈说明学习率太大如果一直不降说明特征没标准化或网络结构不合适。early_stoppingTrue会从训练集里切出 10% 做验证连续 10 次迭代验证分数不提升就停止这是防止过拟合的后悔药。参数说明validation_fraction0.1表示切 10% 做验证数据量小可以调到 0.2。n_iter_no_change10是耐心值设太小会停得太早设太大就失去早停意义。max_iter在开启早停后可以设大一点反正会自动停。4.3 三个模型的统一评估与对比把三个模型的评估结果放在一张表里比单独看每个模型的数字更有决策价值。from sklearn.metrics import f1_score, precision_score, recall_score results [] for name, pred in [(决策树, y_pred_dt), (朴素贝叶斯, y_pred_nb), (神经网络, y_pred_mlp)]: results.append({ 模型: name, 准确率: accuracy_score(y_test, pred), 精确率: precision_score(y_test, pred, averageweighted), 召回率: recall_score(y_test, pred, averageweighted), F1: f1_score(y_test, pred, averageweighted) }) print(pd.DataFrame(results))逻辑说明averageweighted表示按类别样本量加权样本不均衡时比macro更合理。如果标签是二分类且你更关心正类把average改成binary并指定pos_label。这张表能直接看出哪个模型在哪个指标上占优比如决策树精确率高但召回率低神经网络可能更均衡。参数说明precision_score和recall_score默认针对二分类的正类多分类必须加average参数否则会报错。f1_score是精确率和召回率的调和平均综合两者适合作为最终选型的主要参考。5. 避坑与排查跑这份代码时最容易翻车的五个点5.1 现象UnicodeDecodeError: utf-8 codec cant decode byte原因a601318.csv可能是 GBK 或 GB2312 编码尤其在 Windows 上生成的 CSV 经常这样。解决pd.read_csv时把encoding改成gbk或者用chardet检测编码后再读。5.2 现象神经网络准确率一直在 0.5 附近损失不下降原因特征没有标准化或者标签没有转成数值。解决先StandardScaler处理特征再用LabelEncoder把标签转成 0/1。如果标签是字符串「涨/跌」MLPClassifier会直接报错必须编码。5.3 现象决策树训练集准确率 1.0测试集只有 0.6原因树太深把训练集的噪声也学进去了。解决设max_depth在 3 到 8 之间或者设min_samples_leaf5以上。也可以用ccp_alpha做后剪枝但手动限制深度更直观。5.4 现象ConvergenceWarning: Stochastic Optimizer: Maximum iterations reached原因max_iter不够或者学习率不合适。解决把max_iter从默认 200 提到 500 甚至 1000同时开early_stoppingTrue。如果还不行把solver从adam换成lbfgs后者在小数据上收敛更稳。5.5 现象三个模型准确率都差不多不知道选哪个原因数据本身区分度不高或者特征信息量不足。解决先看特征重要性把重要性接近 0 的特征删掉再跑一遍。如果还是差不多说明这份数据可能不适合做分类或者标签定义本身有噪声。这时候别硬调模型回去检查数据质量。6. 进阶技巧用交叉验证和网格搜索把参数定下来单次train_test_split的结果有随机性换个random_state可能差好几个百分点。更稳的做法是交叉验证加网格搜索。下面以决策树为例把max_depth和min_samples_split一起搜。from sklearn.model_selection import GridSearchCV param_grid { max_depth: [3, 5, 7, 10], min_samples_split: [2, 5, 10, 20], criterion: [gini, entropy] } grid GridSearchCV( DecisionTreeClassifier(random_state42), param_grid, cv5, scoringf1_weighted, n_jobs-1 ) grid.fit(X_train, y_train) print(最优参数:, grid.best_params_) print(最优交叉验证 F1:, grid.best_score_) print(测试集准确率:, accuracy_score(y_test, grid.predict(X_test)))逻辑说明cv5表示 5 折交叉验证把训练集分成 5 份轮流用 4 份训练、1 份验证最后取平均。scoringf1_weighted指定优化目标比默认的准确率更适合不均衡数据。n_jobs-1表示用所有 CPU 核心并行跑速度取决于机器。参数说明param_grid里的候选值是经验范围max_depth超过 10 基本没必要min_samples_split超过 20 在小数据上会欠拟合。如果跑完发现最优参数在边界上比如max_depth10最好把范围往外扩再搜一轮。同样的套路可以套到MLPClassifier上但神经网络参数多、训练慢网格搜索容易跑很久。我一般先用RandomizedSearchCV随机采样几十组缩小范围后再用GridSearchCV精搜。朴素贝叶斯参数少var_smoothing用对数刻度搜几个值就够了。从那以后我每次拿到一份分类数据都强制先跑一遍train_test_split加交叉验证的基线再决定要不要上复杂模型。这份资源里的三个算法正好覆盖了从简单到复杂的梯度拿它当模板改自己的数据比从头写省事得多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑