机器学习前置知识实战:配套数据集与Pipeline全流程指南

发布时间:2026/10/27 10:36:55
机器学习前置知识实战:配套数据集与Pipeline全流程指南 简介这份数据集面向刚接触机器学习、需要动手练习数据处理的初学者与自学者围绕「机器学习前置知识」整理帮助读者在正式建模前熟悉真实数据的读取、清洗与探索流程。压缩包共6个文件以csv为主另有1个h5与1个json整体约2.76MB体积轻便便于快速下载后直接加载练习。内容覆盖电影信息、讽刺新闻标题、星巴克门店目录、股票日线行情以及网约车出行记录等不同主题既有结构化表格也有层级存储与文本类数据可分别用于练习Pandas读写、缺失值处理、时间序列整理与简单文本分析。已有4371人学习下载说明其在入门阶段具有一定参考价值。读者可借助这批数据完成从数据加载、字段理解到基础统计与可视化的完整链路为后续特征工程与模型训练打好基础适合作为课程配套练习或自学阶段的数据素材。1. 机器学习前置知识配套数据集一份能直接跑通全流程的练手资源很多人学机器学习卡住的地方不是模型本身而是数据。教程里一行pd.read_csv(data.csv)轻描淡写轮到自己动手时要么找不到合适的数据要么拿到的数据缺列、编码乱码、标签对不上光清洗就耗掉一整天。这份《机器学习前置知识》配套数据集解决的正是这个断层——它把入门阶段最常练的几类数据场景打包在一起让你能把 pandas 读取、缺失值处理、特征缩放、训练集划分、简单模型拟合这条链路完整走一遍而不是停在看视频的阶段。适合刚学完 Python 基础、想用真实数据把前置知识落地的人也适合带新人时找一套结构干净、字段明确的练手素材。下面按「数据长什么样、怎么读进来、怎么处理、坑在哪」的顺序拆开讲。2. 数据集结构与读取先看清字段再动手拿到一份数据集第一件事不是急着fit而是搞清楚它有几个文件、每个文件什么格式、字段是什么类型、标签在哪一列。这份配套数据围绕机器学习前置知识组织常见形态是若干张 CSV 表加一份字段说明覆盖数值型特征、类别型特征、带缺失值的列以及一个明确的目标列。先把结构摸清后面所有处理才有依据。2.1 目录与文件格式的快速盘点我一般习惯先用命令行把目录结构和文件大小过一遍避免一上来就在 Notebook 里瞎猜。常见做法是# 查看数据集目录结构确认文件类型和数量 find ./ml_prerequisite_dataset -maxdepth 2 -type f -exec ls -lh {} \; # 统计每个 CSV 的行数快速判断数据规模 wc -l ./ml_prerequisite_dataset/*.csv第一行用find列出所有文件及大小-maxdepth 2限制层级防止目录太深刷屏-exec ls -lh把每个文件的详细信息打出来能一眼看出哪个文件是主表、哪个是辅助表。第二行wc -l统计行数注意 CSV 的行数包含表头实际样本数要减一。这一步的价值在于如果某个文件只有几十行那多半是字段说明或示例不是训练数据如果主表几万行而辅助表几百行就要考虑后面合并时的连接键是否唯一。盘完之后用 pandas 做一次结构化读取把每张表的列名、类型、缺失情况一次性打出来import pandas as pd # 读取主表先只取前若干行看结构避免大文件全量加载卡住 df pd.read_csv(./ml_prerequisite_dataset/main.csv, nrows5) print(df.dtypes) # 每列的数据类型 print(df.head()) # 前五行预览 # 全量读取后统计缺失率和唯一值数量 df_full pd.read_csv(./ml_prerequisite_dataset/main.csv) summary pd.DataFrame({ dtype: df_full.dtypes, missing_rate: df_full.isna().mean().round(3), n_unique: df_full.nunique() }) print(summary.sort_values(missing_rate, ascendingFalse))这里nrows5是先用小样本探路确认列名和分隔符没问题再全量读能省掉大文件反复加载的时间。isna().mean()算的是每列缺失比例比isna().sum()更直观因为不同列样本量可能不同。nunique()用来区分类别列和数值列——唯一值很少的列大概率是类别特征唯一值接近行数的列可能是 ID处理时要区别对待。把这张 summary 表按缺失率降序排缺失最严重的列排在最前面后面做缺失值处理时优先看它们。2.2 字段类型判定与目标列确认字段类型判错是新手最常见的翻车点之一。pandas 读 CSV 时会把看起来像数字的列自动转成 int 或 float但有些列本质是类别编码比如用 0/1/2 表示不同类别自动转成数值后如果直接喂给模型模型会误以为它们有大小关系。反过来有些数值列因为混进了空字符串或特殊符号被读成 object 类型后面做算术运算直接报错。确认目标列同样关键。监督学习的数据集一定有一个明确的目标列分类任务看它的取值分布是否均衡回归任务看它的取值范围和分布形态。常见做法是先画个简单的分布统计# 确认目标列分布判断分类是否均衡或回归是否偏态 target_col label # 按字段说明替换为实际目标列名 print(df_full[target_col].value_counts(normalizeTrue)) # 分类任务看占比 print(df_full[target_col].describe()) # 回归任务看分位数 # 强制指定类别列避免被误读为数值 cat_cols [category_a, category_b] df_full[cat_cols] df_full[cat_cols].astype(category)value_counts(normalizeTrue)输出的是每类占比如果某一类占到 90% 以上说明数据严重不均衡后面划分训练集时要考虑分层抽样否则模型可能直接全预测成多数类也能拿到高准确率。describe()给出均值、标准差和四分位数回归目标如果均值远大于中位数说明分布右偏必要时做对数变换。最后一行把类别列显式转成category类型既省内存也提醒自己这些列不能直接参与数值运算需要先做编码。提示字段说明文件一定要先读。很多数据集的问题不是数据本身脏而是使用者没看说明就按自己的理解处理结果标签列和特征列搞反了。3. 前置处理链路缺失值、编码与特征缩放数据读进来只是起点真正决定模型能不能跑出合理结果的是前置处理。这一章按处理顺序展开先补缺失再编码类别最后做缩放和划分。顺序不能乱比如缩放必须在划分训练测试集之后做否则测试集的信息会泄漏进训练过程评估结果虚高。3.1 缺失值处理的三种策略与选择依据缺失值处理没有万能公式要看缺失比例和缺失机制。常见做法分三档缺失比例低于 5% 的列直接删掉含缺失的行影响不大5% 到 30% 之间的列用均值、中位数或众数填充超过 30% 的列要么整列丢弃要么把「是否缺失」本身作为一个新特征保留下来因为缺失本身可能携带信息。from sklearn.impute import SimpleImputer # 数值列用中位数填充对偏态分布更稳健 num_cols df_full.select_dtypes(include[int64, float64]).columns.tolist() num_imputer SimpleImputer(strategymedian) df_full[num_cols] num_imputer.fit_transform(df_full[num_cols]) # 类别列用众数填充 cat_cols_all df_full.select_dtypes(include[object, category]).columns.tolist() cat_imputer SimpleImputer(strategymost_frequent) df_full[cat_cols_all] cat_imputer.fit_transform(df_full[cat_cols_all])select_dtypes按类型筛列避免手动列清单漏列。strategymedian选中位数而不是均值是因为数值列常有离群点均值会被拉偏中位数更稳。类别列用most_frequent填众数逻辑上相当于「假设缺失的人属于最常见的那一类」。这里有个容易忽略的点fit_transform在整份数据上做填充严格来说应该在训练集上fit、在测试集上transform否则测试集的统计量会污染训练。练手阶段可以先这样简化但心里要清楚正确做法后面第 5 章会给出更严谨的写法。如果某列缺失率超过 30%我一般会先加一个指示列再填充# 高缺失列保留缺失指示特征再用中位数填充 high_missing_col feature_x df_full[high_missing_col _isna] df_full[high_missing_col].isna().astype(int) df_full[high_missing_col] df_full[high_missing_col].fillna(df_full[high_missing_col].median())isna().astype(int)把布尔值转成 0/1生成一个「原本是否缺失」的新特征。这个特征在某些场景下比填充值本身更有预测力比如用户没填某个字段可能本身就反映了某种行为倾向。3.2 类别编码独热与序号的适用边界类别列不能直接进模型必须编码。编码方式选错模型效果会莫名其妙地差。核心判断标准是类别之间有没有天然顺序。有顺序的如低、中、高用序号编码没顺序的如颜色、城市用独热编码。用序号编码处理无序类别等于强行给模型灌入一个不存在的大小关系这是血泪经验里排得上号的坑。from sklearn.preprocessing import OneHotEncoder # 无序类别列做独热编码稀疏输出转稠密便于后续拼接 ohe OneHotEncoder(sparse_outputFalse, handle_unknownignore) encoded ohe.fit_transform(df_full[[category_a, category_b]]) encoded_df pd.DataFrame(encoded, columnsohe.get_feature_names_out([category_a, category_b])) # 有序类别列用序号映射顺序按业务含义手动指定 order_map {low: 0, medium: 1, high: 2} df_full[level_encoded] df_full[level].map(order_map)sparse_outputFalse让编码结果返回稠密数组方便直接转 DataFrame如果类别很多、独热后列数爆炸可以保留稀疏格式省内存。handle_unknownignore保证测试集出现训练时没见过的类别不会报错而是编码成全零这个参数在真实部署里几乎是必开的。有序类别用map手动指定映射顺序必须按业务语义来不能按字母序或出现频率排否则编码出来的数值大小关系是错的。编码完成后把独热生成的列和原数值列拼在一起形成最终特征矩阵。拼接时注意索引对齐pd.concat默认按索引对齐如果前面填充或删行导致索引不连续要先reset_index(dropTrue)否则会拼出一堆 NaN。3.3 特征缩放与训练测试划分的先后顺序特征缩放的作用是把不同量纲的列拉到同一尺度距离类模型KNN、SVM和带正则的线性模型对量纲敏感不缩放会导致某些特征主导距离计算。树模型对量纲不敏感可以跳过。缩放的正确顺序是先划分、再在训练集上拟合缩放器、最后应用到测试集。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 先划分stratify 保证分类任务训练测试集类别比例一致 X df_full.drop(columns[target_col]) y df_full[target_col] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) # 缩放器只在训练集上 fit测试集只 transform scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)test_size0.2是常见起点数据量小可以调到 0.3 保证测试集有足够样本。random_state42固定随机种子保证每次划分结果一致方便复现和对比。stratifyy在分类任务里按标签比例分层抽样避免小类别在测试集里一个都没有。最关键的是fit_transform只用在训练集测试集用transform——如果测试集也fit缩放用的均值和方差就包含了测试集信息评估结果会偏乐观这是数据泄漏里最隐蔽的一种。注意缩放之后特征矩阵变成 numpy 数组列名丢失。如果后续要按列名做特征重要性分析记得把scaler.feature_names_in_存下来或者用pd.DataFrame(X_train_scaled, columnsX_train.columns)还原。4. 避坑与排查五个高频翻车现场这套数据在练手阶段最容易出问题的地方往往不是算法本身而是数据处理环节的细节。下面五条是我和身边人反复踩过的按「现象 → 原因 → 解决」整理照着排查能省不少时间。4.1 读取后列数对不上现象pd.read_csv读出来的列数比字段说明里写的少或者多出一列Unnamed: 0。原因通常是分隔符不对文件用分号或制表符分隔默认逗号解析失败或者文件本身带索引列被写进了 CSV。解决先head -3 main.csv看原始文本的分隔符读取时显式指定sep;或sep\t多出的Unnamed: 0用index_col0或读后drop掉。4.2 数值列被读成 object现象某列明明是数字dtypes显示 object做mean()报错。原因列里混进了空字符串、NA、-或千分位逗号pandas 无法整体转数值。解决读取时加na_values[NA, -, ]把这些标记识别为缺失再用pd.to_numeric(col, errorscoerce)强制转换转不了的会变成 NaN配合前面的缺失值处理一起解决。4.3 独热编码后维度爆炸现象对高基数类别列比如几百个取值的 ID 类字段做独热特征矩阵从几十列涨到几千列内存吃紧、训练变慢。原因独热编码对每个类别生成一列基数越高列越多。解决高基数列改用目标编码或频次编码或者先按业务逻辑合并稀有类别确实要独热时用sparse_outputTrue保留稀疏矩阵别急着转稠密。4.4 训练集测试集分布不一致现象训练集准确率很高测试集掉一大截。原因划分时没分层小类别全落进训练集或者缩放、填充在划分前就做了测试集信息泄漏。解决分类任务加stratifyy所有依赖统计量的处理填充、缩放、编码都改成在训练集fit、测试集transform用Pipeline串起来最省心。4.5 随机种子没固定导致结果不可复现现象同样的代码跑两次模型分数不一样调参时无法判断是参数起作用还是随机波动。原因train_test_split、模型初始化、部分算法内部都有随机性没设种子。解决划分时固定random_state模型初始化也传random_state需要更严格时用numpy.random.seed统一环境。调参对比时除了被调参数其他随机因素全部锁死。5. 用 Pipeline 把整条链路锁死一个可复用的验证模板前面几章的处理步骤是拆开讲的实际项目里我更推荐用Pipeline把它们串成一个整体。好处很直接填充、编码、缩放全部封装在管道里fit只在训练集上发生predict时自动对测试集做同样的transform数据泄漏从结构上被堵死换模型、调参数时也不用重写预处理代码改一个参数就行。下面这个模板可以直接套到这份数据集上跑通从原始 CSV 到模型评估的完整链路。from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from sklearn.impute import SimpleImputer from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score, train_test_split import pandas as pd df pd.read_csv(./ml_prerequisite_dataset/main.csv) target_col label X df.drop(columns[target_col]) y df[target_col] # 按类型分两路处理数值路填充缩放类别路填充独热 num_cols X.select_dtypes(include[int64, float64]).columns.tolist() cat_cols X.select_dtypes(include[object, category]).columns.tolist() num_pipe Pipeline([ (imputer, SimpleImputer(strategymedian)), (scaler, StandardScaler()) ]) cat_pipe Pipeline([ (imputer, SimpleImputer(strategymost_frequent)), (encoder, OneHotEncoder(handle_unknownignore, sparse_outputFalse)) ]) preprocessor ColumnTransformer([ (num, num_pipe, num_cols), (cat, cat_pipe, cat_cols) ]) # 预处理 模型串成一条管道 clf Pipeline([ (prep, preprocessor), (model, RandomForestClassifier(n_estimators100, random_state42)) ]) # 交叉验证评估比单次划分更稳 scores cross_val_score(clf, X, y, cv5, scoringaccuracy) print(f5 折交叉验证准确率: {scores.mean():.4f} ± {scores.std():.4f}) # 最终训练并预测 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) clf.fit(X_train, y_train) print(f测试集准确率: {clf.score(X_test, y_test):.4f})ColumnTransformer按列类型分流数值列和类别列各走各的预处理互不干扰。Pipeline把预处理和模型绑成一个对象cross_val_score在每一折里都会重新fit预处理器保证每折的填充和缩放统计量只来自该折的训练部分这是手写代码很难保证的。cv5做五折交叉验证输出均值和标准差标准差大说明模型对数据划分敏感可能需要更多数据或更稳的模型。最后单独留一个测试集做最终评估注意这个测试集在交叉验证阶段没被用过结果才可信。几个参数值得按数据情况调n_estimators是随机森林的树数量100 是起点数据量大可以加到 200 到 300再往上收益递减cv在样本少时可以降到 3样本多可以升到 10scoring在不均衡数据上换成f1或roc_auc比accuracy更能反映真实水平。如果换成逻辑回归或 SVM把model那一步替换掉即可预处理部分完全不用动这就是管道化的价值。从那以后我每次拿到新数据集都强制先跑一遍这个模板把基线分数打出来再谈调参——没有基线后面所有优化都是玄学。希望这份配套数据和这套模板能帮你把机器学习前置知识真正跑通而不是停在收藏夹里。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询