机器学习实战:决策树训练、回归树、随机森林与垃圾邮件识别
今天的课程主要围绕决策树训练、回归树、随机森林和垃圾邮件识别展开。前面我们已经学习了交叉验证、下采样、过采样以及 ID3、C4.5 和 CART 等决策树算法。今天的内容更加偏向代码实践如何训练一棵决策树、如何筛选参数、如何用回归树预测连续值以及如何使用随机森林完成垃圾邮件识别。一、决策树分类模型决策树是一种结构直观、可解释性较强的机器学习模型。它会根据数据特征不断提出问题把样本逐步划分到不同分支中最后在叶节点给出预测结果。例如在电信客户流失预测中模型可能依次提出以下问题客户的月消费是否大于100元 ├── 是客户使用时间是否小于12个月 │ ├── 是可能流失 │ └── 否继续判断其他特征 └── 否可能不流失实际训练时问题和划分条件并不是程序员手动规定的而是决策树根据训练数据自动寻找的。可以使用DecisionTreeClassifier创建分类决策树from sklearn.tree import DecisionTreeClassifier model DecisionTreeClassifier( criteriongini, max_depth6, min_samples_split10, min_samples_leaf3, random_state0 )主要参数的作用如下criterion选择节点划分标准max_depth决策树允许达到的最大深度min_samples_split一个节点继续划分所需的最少样本数min_samples_leaf每个叶节点至少保留的样本数random_state固定随机过程使结果能够复现。其中criteriongini表示使用基尼系数选择特征和划分位置。基尼系数可以简单理解为一个节点中样本的混乱程度。假设一个节点中的样本全部属于同一个类别那么这个节点非常纯基尼系数为 0。如果不同类别的样本数量比较接近节点就比较混乱基尼系数也会增大。计算公式为Gini 1 - Σ(pᵢ²)其中pᵢ表示第i个类别在当前节点中的样本比例。决策树会尝试不同的特征和划分位置然后选择能够让子节点更加纯净的方案。二、决策树为什么容易过拟合如果不给决策树设置限制它可能不断向下划分直到每个叶节点只剩下很少的样本。这样做会产生一个现象训练集准确率非常高甚至达到 100%但测试集准确率明显降低。例如模型可能记住某些训练样本的偶然特点而不是真正可以推广到新数据上的规律这就是过拟合。我们可以通过几个参数限制树的复杂程度model DecisionTreeClassifier( max_depth6, min_samples_split10, min_samples_leaf3, random_state0 )max_depth越小决策树越简单min_samples_split和min_samples_leaf越大节点划分条件越严格。不过限制也不能过强。如果树太浅模型可能连基本规律都没有学会导致训练集和测试集表现都比较差这种情况叫作欠拟合。因此训练决策树的关键不是让树越复杂越好而是在欠拟合和过拟合之间寻找合适的平衡。三、处理客户流失数据的类别不平衡在电信客户流失数据中“未流失”客户通常比“流失”客户多。如果两个类别的数量差异很大模型就可能更加偏向多数类。例如未流失客户9000人 流失客户1000人模型即使把大量客户都预测为“未流失”也可能得到比较高的准确率。但对于企业来说真正重要的可能是提前找出会流失的客户。这时可以使用下采样或者过采样平衡数据具体内容可以参考上一篇“机器学习交叉验证、下采样、过采样和决策树”。下采样的基本代码如下train_data X_train.copy() train_data[station] y_train not_churn train_data[ train_data[station] 0 ] churn train_data[ train_data[station] 1 ] not_churn_sample not_churn.sample( nlen(churn), replaceFalse, random_state0 ) balanced_data pd.concat( [not_churn_sample, churn] ) X_train_balanced balanced_data.drop( station, axis1 ) y_train_balanced balanced_data[station]下采样只能处理训练集不能处理测试集。测试集需要保留真实的数据分布否则评价结果无法反映模型在实际数据中的表现。四、使用交叉验证寻找合适参数我们无法只凭感觉决定决策树应该有多少层也很难直接判断叶节点应该保留多少样本。因此可以准备多组候选参数然后使用交叉验证比较效果。首先设置候选值split_values [5, 10, 15, 20, 25] depth_values [4, 6, 8, 10, 12, 14] leaf_values [1, 2, 3, 5, 8, 10]然后把参数逐个组合import numpy as np from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeClassifier scores [] params_list [] for split in split_values: for depth in depth_values: for leaf in leaf_values: model DecisionTreeClassifier( criteriongini, max_depthdepth, min_samples_splitsplit, min_samples_leafleaf, random_state0 ) score cross_val_score( model, X_train_balanced, y_train_balanced, cv5, scoringrecall ) mean_score score.mean() scores.append(mean_score) params_list.append( (split, depth, leaf) )这里使用了三层for循环分别遍历min_samples_split max_depth min_samples_leaf假设分别有 5、6、6 个候选值总共需要测试5 × 6 × 6 180组参数每组参数又需要进行 5 折交叉验证所以模型会被训练很多次。找到最高召回率对应的位置best_idx np.argmax(scores) best_split, best_depth, best_leaf params_list[ best_idx ] print( 最优参数, best_split, best_depth, best_leaf ) print( f最优交叉验证召回率 f{scores[best_idx]:.4f} )这里必须使用np.argmax()因为召回率越大越好。如果评价指标是准确率、召回率、精确率、F1-score 或 R²一般寻找较大的值如果评价指标是 MSE、RMSE 或 MAE则通常寻找较小的值可以使用np.argmin()。五、为什么选择召回率在客户流失预测中召回率表示所有实际会流失的客户中有多少被模型成功找了出来。公式为Recall TP / (TP FN)其中TP实际流失并且预测为流失FN实际流失但预测为不流失。假设实际有 100 名客户会流失模型成功发现其中 80 名那么召回率就是80 / 100 0.8不同业务需要关注的评价指标也不同希望尽可能发现流失客户关注召回率希望减少正常客户被误判关注精确率希望兼顾精确率和召回率关注 F1-score数据类别比较均衡可以参考准确率希望全面查看分类结果使用分类报告和混淆矩阵。这些概念也可以参考“从线性回归到逻辑回归一个初学者的机器学习入门笔记”。六、使用最佳参数重新训练找到最优参数后需要重新创建决策树并使用完整的训练数据进行训练model DecisionTreeClassifier( criteriongini, max_depthbest_depth, min_samples_splitbest_split, min_samples_leafbest_leaf, random_state0, class_weightbalanced ) model.fit( X_train_balanced, y_train_balanced )然后分别在训练集和测试集上预测train_predicted model.predict( X_train_balanced ) test_predicted model.predict( X_test )输出分类报告from sklearn.metrics import classification_report print(训练集结果) print( classification_report( y_train_balanced, train_predicted ) ) print(测试集结果) print( classification_report( y_test, test_predicted ) )如果训练集表现非常好但测试集表现明显下降说明模型可能过拟合。如果训练集和测试集表现都比较差说明模型可能欠拟合或者当前特征无法提供足够的信息。需要注意class_weightbalanced会根据类别数量自动调整权重。如果训练数据已经通过下采样完全平衡这个参数带来的影响可能比较小。可以分别比较只使用下采样、只使用类别权重以及两者同时使用的结果。七、决策树可视化决策树的一大优点是可解释性强。我们可以把训练后的树画出来import matplotlib.pyplot as plt from sklearn.tree import plot_tree fig, ax plt.subplots( figsize(32, 32) ) plot_tree( model, filledTrue, feature_namesX_train_balanced.columns, class_names[未流失, 流失], roundedTrue, axax ) plt.show()图中的常见信息包括当前节点使用的划分特征特征的判断条件当前节点的基尼系数当前节点包含的样本数量不同类别的样本分布节点最终预测的类别。例如月消费 85.5 gini 0.42 samples 320 value [210, 110] class 未流失表示当前节点有 320 个训练样本其中 210 个属于未流失110 个属于流失。如果树太深生成的图片会非常复杂甚至无法正常阅读。从侧面也说明模型可能划分得过细存在过拟合风险。八、回归树决策树不仅能解决分类问题也可以用于预测连续数值。分类树输出离散类别例如流失或未流失 垃圾邮件或正常邮件 患病或未患病回归树输出连续数值例如房屋价格 商品销量 血压数值 温度假设我们根据体重和年龄预测血压收缩值import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeRegressor from sklearn.metrics import mean_squared_error from sklearn.metrics import mean_absolute_error from sklearn.metrics import r2_score data pd.read_csv( 多元回归.csv, encodinggbk ) X data[[体重, 年龄]] y data[血压收缩] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state0 ) model DecisionTreeRegressor( max_depth4, min_samples_leaf3, random_state0 ) model.fit(X_train, y_train) predicted model.predict(X_test)回归树仍然会不断划分数据但判断划分好坏的方式与分类树不同。分类树希望划分后的类别更加纯净而回归树希望同一个叶节点中的目标值更加接近。叶节点的预测结果通常是该节点中训练样本目标值的平均数。九、回归树的评价指标常见的回归评价指标包括 MSE、RMSE、MAE 和 R²。1. 均方误差 MSEmse mean_squared_error( y_test, predicted )MSE 会计算真实值与预测值之间误差的平方平均值。它会对较大的误差给予更严重的惩罚数值越小越好。2. 均方根误差 RMSEimport numpy as np rmse np.sqrt(mse)RMSE 是 MSE 开平方后的结果。它与目标变量的单位一致因此更加直观。3. 平均绝对误差 MAEmae mean_absolute_error( y_test, predicted )MAE 是预测误差绝对值的平均数对极端误差没有 MSE 那么敏感数值越小越好。4. 决定系数 R²r2 r2_score( y_test, predicted )R² 通常越接近 1 越好接近 1模型解释能力较好接近 0模型与直接预测平均值差不多小于 0模型可能还不如直接预测平均值。不应该只在训练数据上评价回归树。决策树很容易记住训练样本如果训练和测试使用相同数据得到的结果可能非常高却不能代表模型预测新数据的能力。十、随机森林单棵决策树容易受到训练数据变化的影响。如果数据稍有改变生成的树结构也可能发生明显变化。随机森林通过训练多棵不同的决策树再综合它们的预测结果提高模型稳定性。分类问题通常采用投票方式第1棵树垃圾邮件 第2棵树正常邮件 第3棵树垃圾邮件 第4棵树垃圾邮件 第5棵树正常邮件 最终结果垃圾邮件创建随机森林from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier( n_estimators100, max_depth10, min_samples_split4, min_samples_leaf2, random_state0, n_jobs-1 )主要参数如下n_estimators森林中决策树的数量max_depth每棵树的最大深度min_samples_split节点继续划分所需的最少样本数min_samples_leaf每个叶节点至少保留的样本数max_features每次划分时查看的特征数量bootstrap是否通过有放回抽样构造训练数据class_weight是否调整不同类别的权重n_jobs-1使用全部可用 CPU 核心训练random_state固定随机过程。十一、随机森林为什么更加稳定随机森林主要通过两种随机性增加不同树之间的差异。第一种是样本随机。每棵树不会直接使用完全相同的训练数据而是通过有放回抽样获得自己的训练样本。第二种是特征随机。在节点划分时每棵树只从部分随机特征中选择划分条件而不是每次查看所有特征。如果所有树使用相同样本和相同特征最后可能生成大量相似的决策树综合结果就没有太大意义。正是由于样本和特征具有随机性每棵树会从不同角度学习数据。某一棵树可能判断错误但多棵树投票后个别错误的影响就会被削弱。不过随机森林也不是完全不会过拟合。如果每棵树都非常深、训练数据存在泄漏或者特征中包含答案信息随机森林仍然可能得到不真实的高分。十二、随机森林识别垃圾邮件spambase.csv中保存了邮件的统计特征和分类标签。可以使用随机森林判断一封邮件是否属于垃圾邮件。首先读取数据import pandas as pd data pd.read_csv(spambase.csv) X data.iloc[:, :-1] y data.iloc[:, -1]划分训练集和测试集from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state0, stratifyy )stratifyy可以让训练集和测试集中的垃圾邮件比例尽量保持一致避免某个集合中的某类样本过少。创建并训练模型from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier( n_estimators100, max_depth10, min_samples_split4, min_samples_leaf2, random_state0, n_jobs-1 ) model.fit(X_train, y_train)进行预测train_predicted model.predict( X_train ) test_predicted model.predict( X_test )输出评价结果from sklearn.metrics import classification_report print(训练集结果) print( classification_report( y_train, train_predicted ) ) print(测试集结果) print( classification_report( y_test, test_predicted ) )如果训练集得分非常高而测试集得分明显偏低通常说明模型可能过拟合。可以尝试减小max_depth增大min_samples_split增大min_samples_leaf增加有效训练数据删除无意义或者存在泄漏的特征使用交叉验证选择参数。十三、垃圾邮件识别中的评价重点垃圾邮件识别中不能只看准确率。如果把垃圾邮件设置为正类那么召回率低很多垃圾邮件没有被拦截精确率低很多正常邮件被错误拦截F1-score综合反映精确率和召回率。两种错误产生的影响不同正常邮件被判断为垃圾邮件 → 用户可能错过重要信息 垃圾邮件被判断为正常邮件 → 用户会收到广告、诈骗或骚扰内容因此需要根据系统实际需求决定更重视精确率还是召回率。还可以查看混淆矩阵from sklearn.metrics import confusion_matrix matrix confusion_matrix( y_test, test_predicted ) print(matrix)混淆矩阵可以直接显示真正例、假正例 假负例、真正例它比单独的准确率更容易看出模型具体错在什么地方。十四、查看随机森林特征重要性训练完成后可以通过feature_importances_查看各个特征的重要程度importance model.feature_importances_ feature_names X.columns importance_data pd.DataFrame({ feature: feature_names, importance: importance }) importance_data importance_data.sort_values( importance, ascendingFalse ) print(importance_data.head(15))绘制特征重要性图import matplotlib.pyplot as plt top15 importance_data.head(15) plt.figure(figsize(10, 6)) plt.barh( top15[feature], top15[importance] ) plt.gca().invert_yaxis() plt.xlabel(特征重要性) plt.title(随机森林特征重要性 Top 15) plt.tight_layout() plt.show()特征重要性可以帮助我们理解模型主要使用了哪些信息也可以作为特征筛选的参考。但需要注意特征重要性描述的是特征在当前模型中的贡献并不能直接证明某个特征与垃圾邮件之间存在因果关系。十五、可以使用 GridSearchCV 简化参数搜索三层for循环可以帮助初学者理解参数组合过程但参数较多时代码会比较长。Scikit-learn 提供了GridSearchCV自动完成网格搜索from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestClassifier param_grid { max_depth: [None, 5, 10, 15], min_samples_split: [2, 4, 8], min_samples_leaf: [1, 2, 4] } model RandomForestClassifier( n_estimators100, random_state0, n_jobs-1 ) grid_search GridSearchCV( estimatormodel, param_gridparam_grid, scoringrecall, cv5, n_jobs-1 ) grid_search.fit( X_train, y_train ) print(最优参数) print(grid_search.best_params_) print(最优交叉验证分数) print(grid_search.best_score_)得到最佳模型best_model grid_search.best_estimator_ test_predicted best_model.predict( X_test )网格搜索本质上仍然是在尝试不同参数组合只是把循环、交叉验证和最佳参数选择封装了起来。十六、总结今天的课程从单棵决策树逐步学习到了随机森林并完成了客户流失预测、血压数值预测和垃圾邮件识别等练习。决策树通过特征不断划分数据结构直观且容易解释但容易出现过拟合。通过限制树的深度、节点划分样本数和叶节点样本数可以控制模型复杂度。回归树与分类树的结构相似但分类树输出类别回归树输出连续数值。评价回归模型时可以使用 MSE、RMSE、MAE 和 R²。随机森林会训练多棵具有差异的决策树再通过投票得到分类结果。它利用随机样本和随机特征降低单棵决策树的不稳定性通常拥有更好的泛化能力。在垃圾邮件识别中除了准确率还需要关注精确率、召回率、F1-score 和混淆矩阵。模型评价不能只看一个分数而应该结合实际业务分析不同错误带来的影响。完整的模型训练过程应该是读取数据 → 划分训练集和测试集 → 只对训练集进行采样 → 使用交叉验证选择参数 → 使用最佳参数重新训练 → 在测试集上进行最终评价 → 分析过拟合和错误类型

相关新闻

统信UOS磁盘无损扩容实战:LVM与分区扩容详解

统信UOS磁盘无损扩容实战:LVM与分区扩容详解

1. 项目概述:为什么统信UOS的磁盘扩容是个技术活? 最近在折腾统信UOS,发现一个挺普遍但又让不少人头疼的问题:系统盘空间告急。无论是当初安装时分区规划得过于保守,还是随着使用,开发环境、Docker镜像、日…

2026/10/9 0:36:40 阅读更多 →
C# WinForms TCP Socket 服务端

C# WinForms TCP Socket 服务端

一、Socket 基础概念1. 什么是 Socket(套接字)Socket 是网络通信的通信端点,可以理解为程序进行网络数据收发的 “接口 / 电话机”。 两台程序想要通过网络通信,两端都必须创建 Socket。IP 地址:定位网络中的电脑&…

2026/9/26 4:46:07 阅读更多 →
勒让德多项式:从物理方程到正交基的推导与应用

勒让德多项式:从物理方程到正交基的推导与应用

1. 项目概述:从物理问题到数学工具 勒让德多项式,这个名字听起来有点学术,但如果你处理过球坐标系下的拉普拉斯方程、搞过电磁学里的多极展开,或者计算过量子力学中的角动量,那你一定绕不开它。它不是什么遥不可及的纯…

2026/10/9 1:22:43 阅读更多 →

最新新闻

码匠教育:为什么同样需求,不同人写出的 Python 代码差距悬殊

码匠教育:为什么同样需求,不同人写出的 Python 代码差距悬殊

在Python学习和职场落地中,有一个极其普遍的现象:面对完全相同的业务需求、完全一致的功能目标,不同开发者写出的代码,呈现出天差地别的效果。新手写出的代码冗长杂乱、冗余严重、运行卡顿、bug频发、无法迭代,而高阶开…

2026/10/11 22:58:43 阅读更多 →
冷热电联供系统多目标优化:NSGA-II代码实战与Pareto前沿分析

冷热电联供系统多目标优化:NSGA-II代码实战与Pareto前沿分析

简介:基于多目标算法的冷热电联供型综合能源系统MATLAB代码与操作视频,面向能源、电气及自动化等相关专业的本硕博学生与教研人员,可作为综合能源系统多目标优化课题的入门模板与实践参考。包内共4个文件,包括两个MATLAB脚本&…

2026/10/11 22:58:43 阅读更多 →
6 行代码把截图变成 Markdown/HTML/LaTeX:TeleOCR 极简调用实测

6 行代码把截图变成 Markdown/HTML/LaTeX:TeleOCR 极简调用实测

6 行代码把截图变成 Markdown/HTML/LaTeX:TeleOCR 极简调用实测 【免费下载链接】TeleOCR 项目地址: https://ai.gitcode.com/XingChen-AGI/TeleOCR 做技术分享和论文笔记时,最烦的就是截图里的内容无法直接复用:公式要手抄成 LaTeX&…

2026/10/11 22:58:43 阅读更多 →
YOLOv8网球检测实战:数据集制作、模型训练到TensorRT部署全流程

YOLOv8网球检测实战:数据集制作、模型训练到TensorRT部署全流程

简介:这是一份面向打网球检测场景的YOLO系列目标检测数据集,适合使用YOLOv5、YOLOv8、YOLOv9等主流版本的算法工程师和研究者,可直接用于模型训练、验证与测试,解决打网球场景下训练数据匮乏、标注格式不统一等问题。数据集已经按…

2026/10/11 22:58:43 阅读更多 →
如何让NullHub开机自启:systemd与launchd系统服务注册完整教程

如何让NullHub开机自启:systemd与launchd系统服务注册完整教程

【免费下载链接】nullhub Management console for the Null ecosystem — install, configure, and monitor AI agents, orchestration workflows, task pipelines, and system health 项目地址: https://gitcode.com/gh_mirrors/nu/nullhub 点击查看 免费下载 想让…

2026/10/11 22:58:42 阅读更多 →
大模型编程提效四法则:结构化提示与渐进验证

大模型编程提效四法则:结构化提示与渐进验证

1. 先泼一盆冷水:GPT-6 与 Codex 并不存在,但这个标题背后藏着真问题你点开这篇文章,大概率是因为被“GPT-6”“Codex”“极致发挥”这几个词击中了——它们像一组精准投放的信号弹,在技术圈信息流里高频闪烁。但作为从业十年、亲…

2026/10/11 22:57:42 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式: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/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →