Python二手车价格预测实战:从数据清洗到LightGBM模型调参完整链路
简介这份资源面向Python课程设计、期末大作业及数据挖掘入门学习者围绕二手车价格预测这一典型回归任务提供从数据清洗、特征工程到模型训练与评估的完整实现方案帮助读者快速理解数据挖掘项目的整体流程与落地方式。压缩包共27个文件约34.86MB包含2个Python源码文件、1份CSV数据集、1份docx设计报告、1份md说明文档以及9张png结果图、8个xml配置文件和若干工程配置文件覆盖代码、数据、报告与运行环境说明。目前已有211人学习下载适合作为课程大作业参考或自学练手项目。源码配有详细注释新手也能看懂下载后简单部署即可运行设计报告与结果图可直接用于作业撰写与答辩展示具有较高的实际应用与参考价值。1. 二手车价格预测从课程大作业到能跑通的完整数据挖掘链路二手车价格预测这个题目几乎每年都会出现在数据挖掘或 Python 课程的选题清单里。原因很直接数据获取门槛低、业务含义清晰、建模路径完整从爬虫、清洗、特征工程到回归模型全都能串一遍。但真正动手做过的人都知道这类项目最容易翻车的地方不在模型选型而在数据本身——同一款车不同年份、不同里程、不同城市的价格能差出一倍缺失值和异常值处理不好后面调参调到天亮也白搭。这篇笔记面向两类人一是正在做 Python 课程大作业、需要一份能跑通且注释清楚的完整方案的同学二是想快速搭一套二手车估价原型的开发者。我会按真实落地顺序拆解数据从哪来、怎么洗、特征怎么造、模型怎么选、评估怎么做以及那些只有踩过才知道的坑。全程用 Python 实现代码可直接复现参数会说明为什么这么设。2. 数据获取与初探别急着建模先看清数据长什么样2.1 数据来源的三种常见路径做二手车价格预测数据来源决定了后续所有工作的上限。常见做法有三类第一类是公开数据集比如一些数据竞赛平台发布过的二手车交易记录字段通常包含品牌、车型、注册年份、里程、变速箱类型、燃油类型、售价等。这类数据已经过一定脱敏拿来练手最省事。第二类是自己采集。用 requests 配合解析库抓取公开的二手车信息页面或者用 Selenium 处理动态渲染。这里要注意频率控制别给目标站点造成压力也要遵守其 robots 协议。第三类是模拟生成。课程大作业如果拿不到真实数据可以基于业务规则构造一份带噪声的数据集重点是把完整流程跑通。我一般会建议先用模拟数据把 pipeline 搭好再替换成真实数据。不管哪条路径拿到数据后第一件事不是建模而是做数据初探。下面这段代码是标准的初探模板import pandas as pd import numpy as np # 读取数据注意编码中文数据常见 gbk 或 utf-8 df pd.read_csv(used_car.csv, encodingutf-8) # 基本信息行列数、字段类型、内存占用 print(df.shape) print(df.dtypes) print(df.info()) # 数值字段描述统计重点看均值和中位数差多少 print(df.describe()) # 类别字段看取值分布 for col in df.select_dtypes(includeobject).columns: print(col, df[col].nunique()) print(df[col].value_counts().head(10)) # 缺失值统计 missing df.isnull().sum() missing_rate missing / len(df) print(pd.DataFrame({缺失数: missing, 缺失率: missing_rate}) .sort_values(缺失率, ascendingFalse))这段代码的逻辑是先看整体规模再分字段类型看分布最后定位缺失。参数上没什么可调的但有一个习惯值得养成describe()之后一定对比均值和 50% 分位数如果差距很大说明分布偏斜严重后面可能要做对数变换。类别字段的nunique()能帮你判断哪些字段适合做独热编码哪些应该做目标编码或直接舍弃。2.2 目标变量分布检查与处理决策二手车价格是典型的右偏分布少数豪车会把均值拉得很高。建模前必须看目标变量的分布import matplotlib.pyplot as plt # 原始价格分布 plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) plt.hist(df[price], bins50) plt.title(原始价格分布) # 对数变换后 plt.subplot(1, 2, 2) plt.hist(np.log1p(df[price]), bins50) plt.title(对数变换后价格分布) plt.show() # 偏度和峰度 print(偏度:, df[price].skew()) print(峰度:, df[price].kurt())如果偏度大于 1我一般会对价格做log1p变换再训练预测时用expm1还原。这样做的好处是让模型更关注相对误差而不是绝对误差对高价车的预测不会过度主导损失函数。注意log1p而不是log是为了处理价格可能为 0 的边界情况。提示变换后一定要检查还原后的误差指标别只看对数域的 MSE那个数值没有业务解释力。3. 特征工程决定预测精度的主战场3.1 从原始字段里榨出可用特征原始字段往往不能直接喂给模型。以注册年份为例直接放年份数字模型会认为 2020 比 2010 大但真正影响价格的是车龄。所以第一步是构造衍生特征# 假设当前年份为 2024 CURRENT_YEAR 2024 # 车龄 df[car_age] CURRENT_YEAR - df[register_year] # 里程分箱把连续里程变成有序类别 bins [0, 1, 3, 5, 8, 12, 20, 100] labels [1万内, 1-3万, 3-5万, 5-8万, 8-12万, 12-20万, 20万以上] df[mileage_bin] pd.cut(df[mileage], binsbins, labelslabels) # 品牌保值率用品牌下所有车的中位价格作为该品牌的粗略保值指标 brand_price_median df.groupby(brand)[price].median() df[brand_price_median] df[brand].map(brand_price_median) # 车龄与里程的交互项反映使用强度 df[usage_intensity] df[mileage] / (df[car_age] 1)这里有几个参数需要说明。里程分箱的边界不是拍脑袋定的而是根据业务常识一般家用车年均行驶 1 到 2 万公里所以 3 万、5 万、8 万这些节点对应的是不同车况阶段。brand_price_median这个特征在训练集上计算然后映射到测试集注意避免用测试集信息去算中位数否则就是数据泄露。usage_intensity加 1 是防止车龄为 0 时除零。3.2 类别字段编码独热、目标编码还是频率编码类别字段的处理方式直接影响模型表现。品牌、变速箱、燃油类型这些字段取值数量差别很大字段取值数推荐编码理由变速箱2-3独热编码取值少无顺序燃油类型3-5独热编码取值少无顺序品牌20-50目标编码取值多独热会爆炸车型100频率编码或目标编码取值极多需降维目标编码的实现要配合交叉验证否则容易过拟合from sklearn.model_selection import KFold def target_encode(df, col, target, n_splits5, smoothing10): 带平滑的目标编码用 K 折避免泄露 df[col _target_enc] np.nan kf KFold(n_splitsn_splits, shuffleTrue, random_state42) global_mean df[target].mean() for train_idx, val_idx in kf.split(df): train_fold df.iloc[train_idx] val_fold df.iloc[val_idx] # 计算每类的均值和中位数样本数 agg train_fold.groupby(col)[target].agg([mean, count]) # 平滑样本少时向全局均值靠拢 smooth (agg[mean] * agg[count] global_mean * smoothing) / (agg[count] smoothing) df.loc[val_fold.index, col _target_enc] val_fold[col].map(smooth) # 用全量数据再算一次供测试集使用 agg df.groupby(col)[target].agg([mean, count]) smooth (agg[mean] * agg[count] global_mean * smoothing) / (agg[count] smoothing) return df, smooth df, brand_map target_encode(df, brand, price)平滑参数smoothing控制的是某个品牌样本很少时它的编码值向全局均值靠拢的程度。设 10 意味着至少要有 10 条样本该品牌的均值才有足够话语权。这个值可以根据数据量调整数据量大就调小数据量小就调大。3.3 缺失值处理删除、填充还是模型自己扛缺失值处理没有万能方案要看缺失比例和缺失机制# 缺失率超过 60% 的字段考虑直接删除 high_missing_cols [c for c in df.columns if df[c].isnull().mean() 0.6] df df.drop(columnshigh_missing_cols) # 数值字段用中位数填充比均值抗异常值 num_cols df.select_dtypes(include[np.number]).columns for col in num_cols: if df[col].isnull().sum() 0: df[col] df[col].fillna(df[col].median()) # 类别字段用众数填充 cat_cols df.select_dtypes(includeobject).columns for col in cat_cols: if df[col].isnull().sum() 0: df[col] df[col].fillna(df[col].mode()[0])如果用的是 LightGBM 或 XGBoost其实可以保留缺失值让模型自己处理这类树模型对缺失值有原生支持。但线性模型和神经网络必须填充。我一般会先跑一版保留缺失的树模型作为 baseline再对比填充后的效果。4. 模型训练与调参从线性回归到梯度提升树4.1 基线模型先跑通再优化别一上来就上复杂模型。先用线性回归跑一个基线确认整个流程没有泄露、没有逻辑错误from sklearn.model_selection import train_test_split from sklearn.linear_model import Ridge from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_absolute_error, r2_score import numpy as np # 准备特征矩阵去掉目标列和原始文本列 feature_cols [c for c in df.columns if c not in [price, brand, model, city]] X df[feature_cols] y np.log1p(df[price]) # 对数变换 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 标准化 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 岭回归alpha 控制正则强度 ridge Ridge(alpha1.0) ridge.fit(X_train_scaled, y_train) # 预测并还原 y_pred_log ridge.predict(X_test_scaled) y_pred np.expm1(y_pred_log) y_true np.expm1(y_test) print(MAE:, mean_absolute_error(y_true, y_pred)) print(R2:, r2_score(y_true, y_pred))alpha是正则化强度越大越不容易过拟合但也可能欠拟合。可以先试 0.1、1、10 几个值。注意标准化只在训练集上 fit测试集用同样的 scaler 做 transform这是防止数据泄露的基本操作。4.2 梯度提升树主力模型的选择与参数含义树模型在表格数据上通常表现最好。LightGBM 训练快、内存占用低是我做这类任务的首选import lightgbm as lgb from sklearn.model_selection import KFold params { objective: regression, metric: mae, learning_rate: 0.05, num_leaves: 31, max_depth: -1, min_data_in_leaf: 20, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 5, lambda_l2: 1.0, verbose: -1, seed: 42 } # 5 折交叉验证 kf KFold(n_splits5, shuffleTrue, random_state42) oof_preds np.zeros(len(X_train)) test_preds np.zeros(len(X_test)) for fold, (tr_idx, val_idx) in enumerate(kf.split(X_train)): X_tr, X_val X_train.iloc[tr_idx], X_train.iloc[val_idx] y_tr, y_val y_train.iloc[tr_idx], y_train.iloc[val_idx] dtrain lgb.Dataset(X_tr, labely_tr) dval lgb.Dataset(X_val, labely_val, referencedtrain) model lgb.train( params, dtrain, num_boost_round2000, valid_sets[dval], callbacks[lgb.early_stopping(100), lgb.log_evaluation(200)] ) oof_preds[val_idx] model.predict(X_val, num_iterationmodel.best_iteration) test_preds model.predict(X_test, num_iterationmodel.best_iteration) / kf.n_splits print(OOF MAE:, mean_absolute_error(np.expm1(y_train), np.expm1(oof_preds)))几个关键参数需要解释。learning_rate设 0.05 是速度和精度的折中设太小训练慢设太大容易震荡。num_leaves控制单棵树复杂度31 是常用起点数据量大可以调到 63 或 127。min_data_in_leaf防止叶子节点样本过少导致过拟合20 是保守值。feature_fraction和bagging_fraction都是行采样和列采样增加随机性来提升泛化。early_stopping(100)表示验证集指标 100 轮不提升就停这是防止过拟合最实用的手段。4.3 特征重要性分析与模型解释训练完要看哪些特征真正起了作用# 用最后一折的模型看特征重要性 importance pd.DataFrame({ feature: X_train.columns, gain: model.feature_importance(importance_typegain), split: model.feature_importance(importance_typesplit) }).sort_values(gain, ascendingFalse) print(importance.head(20)) # 如果装了 shap可以看单样本解释 # import shap # explainer shap.TreeExplainer(model) # shap_values explainer.shap_values(X_test.iloc[:100]) # shap.summary_plot(shap_values, X_test.iloc[:100])gain表示该特征带来的总信息增益比split次数更能反映重要性。如果发现brand_price_median这类目标编码特征排第一要警惕是否泄露了目标信息检查编码时是否严格按折计算。5. 避坑与排查那些让模型翻车的细节5.1 数据泄露最常见也最致命现象线下交叉验证 MAE 很低上线或换一批数据后误差翻倍。原因目标编码用了全量数据计算或者标准化时用了包含测试集的统计量或者构造特征时用到了未来信息。解决所有依赖目标值的特征必须在交叉验证的每一折内部单独计算。标准化、填充中位数这些操作只能在训练折上 fit然后应用到验证折。写代码时养成习惯先 split再在训练集上做任何 fit。5.2 异常价格不处理会带偏整个模型现象模型对正常车的预测还行但偶尔给出离谱高价或负值。原因训练数据里混入了标价错误、事故车、限量收藏车等极端样本。解决用分位数截断比如把价格低于 1% 分位和高于 99% 分位的样本剔除或缩尾。也可以对价格做 log 变换来压缩极端值的影响。但别一刀切太狠否则会丢失真实的高价车模式。5.3 类别字段取值不一致现象训练时品牌有 30 个取值预测时来了一个没见过的品牌模型直接报错或给出随机结果。原因训练集和测试集的类别空间不一致或者线上新出现了训练时没有的品牌。解决目标编码时给未知类别留一个全局均值作为兜底。独热编码用handle_unknownignore。更稳妥的做法是维护一个类别映射表新类别统一归入“其他”。5.4 评估指标选错MAE 和 RMSE 讲的是不同故事现象用 RMSE 调参结果模型对大误差很敏感但业务方更关心平均误差。原因RMSE 对大误差惩罚重MAE 对所有误差一视同仁。二手车场景里偶尔一个极端误差可能比整体平均误差更值得关注也可能相反。解决同时看 MAE、RMSE 和 MAPE。如果高价车样本少但重要用 RMSE如果追求整体平均准确度用 MAE。我一般以 MAE 为主RMSE 为辅两个都监控。5.5 过拟合训练集完美验证集拉胯现象训练集 R2 到 0.95验证集只有 0.6。原因模型太复杂、特征太多、样本太少或者交叉验证方式不对。解决先降模型复杂度减少num_leaves、增大min_data_in_leaf、提高正则lambda_l2。再检查特征数量是否远超样本量必要时做特征筛选。最后确认交叉验证的折数和数据量匹配小数据用 5 折大数据可以用 3 折。6. 进阶技巧让预测结果更稳的几个实操习惯第一个习惯是固定随机种子并记录。上面代码里random_state42和seed42不是随便写的是为了让每次运行结果可复现。课程大作业要交报告复现性直接影响可信度。我一般会在脚本开头统一设SEED42所有涉及随机的地方都引用它。第二个习惯是保存完整的预处理 pipeline。别只保存模型文件标准化器、目标编码映射表、特征列顺序都要一起存import joblib # 保存模型和预处理对象 joblib.dump(model, lgb_model.pkl) joblib.dump(scaler, scaler.pkl) joblib.dump(brand_map, brand_target_map.pkl) joblib.dump(feature_cols, feature_cols.pkl) # 预测时按同样顺序加载和变换 def predict_new(data_dict): model joblib.load(lgb_model.pkl) scaler joblib.load(scaler.pkl) brand_map joblib.load(brand_target_map.pkl) feature_cols joblib.load(feature_cols.pkl) row pd.DataFrame([data_dict]) row[car_age] 2024 - row[register_year] row[brand_target_enc] row[brand].map(brand_map).fillna(brand_map.mean()) row row[feature_cols] row_scaled scaler.transform(row) pred_log model.predict(row_scaled) return np.expm1(pred_log)[0]第三个习惯是给预测结果加一个合理的区间。点预测容易给人虚假的精确感实际业务里更希望知道“大概在什么范围”。可以用分位数回归或者对残差建模来给出区间# 用验证集残差的分位数构造预测区间 residuals np.expm1(y_train) - np.expm1(oof_preds) lower np.percentile(residuals, 5) upper np.percentile(residuals, 95) def predict_with_interval(x): point predict_new(x) return point lower, point, point upper这样给出的区间虽然粗糙但比单点预测更有参考价值。课程报告里加上这个会比只报一个 MAE 显得更完整。最后一个习惯是留一份“后悔药”每次调参或改特征前把当前版本的验证集指标记下来。我见过太多人改了一堆东西结果效果反而下降又回不去之前的状态。用简单的文本日志或者表格记录版本、改动内容、MAE、RMSE花不了几分钟但能省下大量重复劳动。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

WDCNN轴承故障诊断实战:原始振动信号深度学习与t-SNE特征验证

WDCNN轴承故障诊断实战:原始振动信号深度学习与t-SNE特征验证

简介:基于WDCNN的轴承故障诊断资源面向机械设备故障诊断及深度学习方向的研究者、学生与工程技术人员,提供一套覆盖数据、代码与可视化结果的完整实验方案;该方法采用宽卷积核提取一维振动信号特征,在轴承故障分类任务上表现稳定&…

2026/10/9 14:03:05 阅读更多 →
数据库期末考试试题及答案:从背题到造题的复习路径

数据库期末考试试题及答案:从背题到造题的复习路径

简介:这份数据库期末考试试题及答案面向高校计算机及相关专业学生,用于期末复习、自测与考前查漏补缺,也可供教师命题参考。内容围绕数据库系统核心知识展开,涵盖DBMS、数据模型、概念模型与E-R模型、数据独立性、关系数据模型、关…

2026/10/9 14:03:05 阅读更多 →
IDA Pro 反编译 .so 文件实战:从加载到伪代码的完整链路

IDA Pro 反编译 .so 文件实战:从加载到伪代码的完整链路

简介:这份资源面向逆向工程初学者与安全分析人员,聚焦 Android/Linux 平台 .so 动态库的反编译实战,帮助读者借助 IDA Pro 理解二进制反汇编流程与 C/C 代码还原思路。压缩包共约 2000 个文件,整体 156.76MB,以 1769 个…

2026/10/9 14:03:05 阅读更多 →

最新新闻

CAP理论与数据库分片架构:一致性、可用性与分库分表实战解析

CAP理论与数据库分片架构:一致性、可用性与分库分表实战解析

做分布式系统做了这么久,我发现一个特别有意思的现象:很多人都把CAP背得滚瓜烂熟,一问你“CAP是什么”,张口就来“一致性、可用性、分区容错性,三者不可兼得”。可真到设计一个数据库分片架构的时候,该选什…

2026/10/9 14:29:54 阅读更多 →
银行汇款单网页制作:HTML表单与CSS布局实战详解

银行汇款单网页制作:HTML表单与CSS布局实战详解

上学时做的第一个像样的网页作业,就是这份银行汇款单。当时觉得不就是画个表格、填几个输入框嘛,真动手才发现,越看着简单的页面,越考验基本功。汇款单这玩意儿信息密度高、对齐要求严格、表单控件类型多,还要考虑打印…

2026/10/9 14:29:54 阅读更多 →
MySQL root密码忘记怎么办?重置原理与多环境实操指南

MySQL root密码忘记怎么办?重置原理与多环境实操指南

半夜十二点,微信突然响了。同事发来一串带汗的表情:“生产库连不上了,root密码不对,之前管库的兄弟走了,交接文档里写的是另一个密码……”这种场景我遇到过好几次。MySQL的root密码一旦丢失,正常的登录入口…

2026/10/9 14:29:54 阅读更多 →
MySQL root密码忘记?用skip-grant-tables重置密码实操指南

MySQL root密码忘记?用skip-grant-tables重置密码实操指南

哎,MySQL 的 root 密码忘了,这种事谁遇上谁知道。平时数据库跑得好好的,某天要改个慢查询配置或者导一份数据,输错三次直接被拒,那一刻是真的慌。其实 MySQL 官方留了一条“紧急通道”——启动时跳过授权表&#xff0c…

2026/10/9 14:29:54 阅读更多 →
数据库原理复习链路:往年卷拆解、SQL作业与课设避坑指南

数据库原理复习链路:往年卷拆解、SQL作业与课设避坑指南

简介:面向天津大学「数据库应用(原理)」课程的备考者与自学者,资源包集中整理往年试卷、课程大作业与实验报告,内容覆盖SQL语言、关系数据库模型、数据完整性、事务处理、索引构建与查询优化等核心考点,并包…

2026/10/9 14:29:54 阅读更多 →
MOSS-Transcribe-Diarize Web后端架构解析:任务状态机、作业管理与 FastAPI 实现

MOSS-Transcribe-Diarize Web后端架构解析:任务状态机、作业管理与 FastAPI 实现

MOSS-Transcribe-Diarize Web后端架构解析:任务状态机、作业管理与 FastAPI 实现 【免费下载链接】MOSS-Transcribe-Diarize A 0.9B model for long-form transcription in 50 languages with speaker diarization, timestamps, and acoustic event awareness 项目…

2026/10/9 14:28:53 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →