news 2026/6/23 16:06:11

(一)站稳脚:用Scikit-learn跑通第一条Pipeline

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(一)站稳脚:用Scikit-learn跑通第一条Pipeline

从CSV到模型,一个完整的ML项目长什么样


你装好了Python,跑通了Ollama,手上有一本《动手学深度学习》的克隆。但你可能还在想一个问题:机器学习项目,到底是怎么从零跑到尾的?

网上有大量教程教你怎么调fit()predict(),但很少有教程把你从"有一个CSV文件"带到"训练出一个模型并知道它好不好用"。这篇就是来补这个缺的。

选一个最经典的入门数据集——泰坦尼克号。不是因为它有趣,是因为它小(只有891行)、干净(不需要分布式处理)、而且足够展示一条完整的ML Pipeline长什么样。


从Pandas开始:把数据拿过来

import pandas as pd import numpy as np import os import urllib.request from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix # 下载到本地(跨平台路径) data_dir = os.path.expanduser("~/data") os.makedirs(data_dir, exist_ok=True) file_path = os.path.join(data_dir, 'titanic.csv') if not os.path.exists(file_path): url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv' urllib.request.urlretrieve(url, file_path) df = pd.read_csv(file_path) df.head()

如果你能看到五列数据——Survived、Pclass、Sex、Age、Fare——说明环境没问题。终端里应该出现这样的表格:

PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S

这里有个很多人会忽略的点:先看数据长什么样,别急着建模。看看每一列有多少空值、数据类型是什么、数值分布怎么样:

print(df.info()) # df.describe()

df.info()会告诉你每一列有多少非空值:

<class 'pandas.core.frame.DataFrame'> RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): PassengerId 891 non-null int64 Survived 891 non-null int64 Pclass 891 non-null int64 Name 891 non-null object Sex 891 non-null object Age 714 non-null float64 SibSp 891 non-null int64 Parch 891 non-null int64 Fare 891 non-null float64 Cabin 204 non-null object Embarked 889 non-null object

你会发现Age列有177个空值(891 - 714 = 177),Cabin列更是惨不忍睹(只有204个非空)。这些空值会在训练时报错,所以必须处理。


特征工程:把原始数据变成模型能消化的格式

机器学习的核心不是算法,是你怎么把原始信息变成数字。

# 选几列能用的特征 features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare'] # 填充空值——用中位数比用均值更鲁棒 df['Age'] = df['Age'].fillna(df['Age'].median()) # 把性别从文字变成数字 df['Sex'] = df['Sex'].map({'male': 0, 'female': 1}) X = df[features] y = df['Survived'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

这一步的思考过程比代码重要

  • 为什么用中位数而不是均值填Age?因为年龄分布可能偏斜,中位数不受极端值影响。
  • 为什么Sex要变成0/1?因为模型只能处理数字。
  • 为什么Pclass不需要归一化?因为它是排序特征(1>2>3),树模型对尺度不敏感。

如果你不理解这些"为什么",建议停下来,翻一下 d2l-zh 第4章(线性回归)和第5章(多层感知机)。那些公式在这里会变成"哦,原来是干这个用的"。


训练和评估:看模型实际表现

model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42) model.fit(X_train, y_train) y_pred = model.predict(X_test) print(classification_report(y_test, y_pred))

输出大概是这样的(你的数字可能略有浮动,因为随机种子不同):

precision recall f1-score support 0 0.78 0.88 0.83 105 1 0.79 0.65 0.71 74 accuracy 0.78 179 macro avg 0.78 0.76 0.77 179 weighted avg 0.78 0.78 0.78 179

一个不到20行代码的模型,准确率 78% 左右。这对第一个模型来说是完全正常的。

怎么看这四个指标

  • precision:模型说"这个人没活"时,78% 是对的。说"这个人活了"时,79% 是对的。
  • recall:所有没活的人里,模型找出了 88%。所有活下来的人里,模型找出了 65%。
  • f1-score:precision 和 recall 的调和平均,越接近 1 越好。
  • support:测试集里实际的人数。这里 105 人没活、74 人活下来了。

更重要的不是分数本身,而是你理解了整个流程:读数据 → 清理 → 选特征 → 训练 → 评估。这条Pipeline在以后无论你做什么ML项目,甚至做大模型微调,都会反复出现。


现在你该做什么

跑通上面的代码之后,你有三条路可以选:

第一条:把同样的流程用在其他数据集上。

Kaggle上搜索"Titanic"的同类比赛,或者换一个更现代的数据集——比如Wine Quality、Iris。用同样的代码结构跑一遍,你会发现90%的代码不用改,改的只是数据列名和特征选择。

第二条:理解你刚用了什么算法。

随机森林是"很多棵决策树投票"——听起来简单,但里面涉及Bagging、特征随机采样、OOB评估。去 ML-From-Scratch 打开random_forest.py,你会发现核心逻辑只有几十行循环。读一遍你就能说清楚"随机森林和单棵决策树的区别是什么"——面试高频题。

第三条:了解Scikit-learn的全貌。

Scikit-learn官方文档 的中文翻译版在 sklearn-doc-zh。不用从头读到尾。遇到新问题时去搜——"怎么分训练集?"→train_test_split,"怎么调参数?"→GridSearchCV,"怎么评估分类器?"→classification_report。用多了自然记住。


验收标准:跑通了吗?

你的脚本应该能无报错地输出classification_report。逐条检查:

  • df.head()显示了表格数据(5 行 x 12 列)
  • df.info()中的 Age 空值已被填充(显示 891 non-null)
  • X_trainX_test的行数加起来等于 891(713 + 179)
  • classification_report的 accuracy 在 0.75-0.85 之间
  • 没有报错ValueError: Input contains NaN——说明空值处理干净了

如果你的准确率低于 0.7,检查特征选择:是不是只用了SexPclass两列?加上AgeFareSibSp通常能提升 5-10%。


参考项目

这条 Pipeline 涉及的工具和进一步学习资源:

d2l-zh 第4-6章 :线性回归、MLP、模型选择的理论基础
ML-From-Scratch:读懂随机森林和决策树的纯NumPy实现
sklearn-doc-zh:Scikit-learn API的中文速查手册

三个够了。重点是把上面那条Pipeline跑通、理解、复用,而不是再去Star另外十个仓库。


这篇之后

你从"有一个 CSV 文件"走到了"训练出一个模型并知道它好不好用"。下一篇文章进入深度学习和 Transformer——从调 sklearn API 到手写一个神经网络,理解梯度下降到底在做什么,以及"Attention Is All You Need"那一张图到底在画什么。


本系列 Notebook 及配套文章:github.com/ASPIRINH/hands-on-llm


常见问题

Q:pandas.read_csvSSL: CERTIFICATE_VERIFY_FAILED
A: 把 URL 换成本地文件。先下载 CSV:浏览器打开https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv,保存为~/data/titanic.csv,然后df = pd.read_csv('~/data/titanic.csv')

Q:classification_report出来的全是 0 的分数?
A: 检查y_test的取值分布——如果用print(y_test.value_counts())发现全是同一类,说明 train/test 切分出了问题。检查random_state=42是否写对了,或者把test_size从 0.2 改成 0.3。

Q: 准确率只有 60% 多?
A: 正常。只用 Pclass 和 Sex 两列做特征就是这样。把 Age、Fare、SibSp 都加进去(上面的代码已包含),应该能到 80% 左右。如果你加了所有特征仍然低,检查 Age 的空值有没有处理干净。

Q:ValueError: Input contains NaN, infinity or a value too large for dtype
A: 特征里还有空值。运行df[features].isna().sum()看看哪一列还有 NaN。Titanic 的 Age 和 Cabin 都有空值——代码里只填充了 Age,如果使用了其他列也可能有空值。

Q: 运行df.head()只显示了 3 列而不是 12 列?
A: 终端宽度不够。加一行pd.set_option('display.max_columns', 20)再运行df.head()

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

软件|Navicat Premium16 免费安装配置教程(附安装包)

一、下载安装包官网下载&#xff1a;https://www.navicat.com.cn/products#navicat可直接网盘下载链接 &#xff1a;https://pan.baidu.com/s/1Y_9TzouLX7AtgEww_yVYaQ?pwdsili 如失效后台发送&#xff3b;四里&#xff3d;&#xff0c;重新获取二、安装过程1. 双击安装包2. 选…

作者头像 李华
网站建设 2026/6/23 15:56:15

山东大学项目实训6月20日

在项目中&#xff0c;我主要负责代码审查链路中的代码分析和静态扫描&#xff0c;具体包括以下几个方面&#xff1a;1. 静态分析与结构上下文构建负责将 PR 变更代码、Semgrep 扫描结果和 Tree-sitter 解析结果进行统一组织&#xff0c;形成可用于后续审查的结构化证据输入。 这…

作者头像 李华
网站建设 2026/6/23 15:41:35

基于神经元激活图的目标导向预训练数据选择:原理、实现与实战

1. 项目概述&#xff1a;从“大锅饭”到“精准投喂”的数据选择革命 在深度学习模型训练&#xff0c;尤其是预训练阶段&#xff0c;我们常常面临一个看似简单却极其关键的抉择&#xff1a;用哪些数据&#xff1f;过去很长一段时间&#xff0c;业界的主流做法是“大力出奇迹”—…

作者头像 李华
网站建设 2026/6/23 15:27:31

Ubuntu 12.04 部署 CouchDB 1.6.1 与 Futon 实战指南

1. 项目概述&#xff1a;为什么在 Ubuntu 12.04 上部署 CouchDB Futon 仍值得深挖 CouchDB 是一个以 JSON 为数据模型、HTTP 为 API 协议、MapReduce 为查询引擎的面向文档型数据库&#xff0c;它的设计哲学是“最终一致性”与“离线优先”&#xff0c;这在移动端同步、边缘计…

作者头像 李华
网站建设 2026/6/23 15:13:25

嵌入式实时系统开发

嵌入式实时系统开发&#xff1a;连接数字世界的隐形桥梁 在智能设备无处不在的今天&#xff0c;嵌入式实时系统&#xff08;RTS&#xff09;已成为工业控制、医疗设备、自动驾驶等领域的核心技术。它像一台精准的时钟&#xff0c;在毫秒甚至微秒级的时间内完成任务调度&#x…

作者头像 李华
网站建设 2026/6/23 15:04:22

Python+Selenium UI自动化测试实战:从环境搭建到CI/CD集成

1. 项目概述&#xff1a;为什么我们需要UI自动化测试&#xff1f; 在软件开发的迭代周期里&#xff0c;回归测试是个绕不开的体力活。每次发布新版本&#xff0c;测试同学都要把核心功能点再手动走一遍&#xff0c;耗时费力不说&#xff0c;还容易因为疲劳导致漏测。我经历过一…

作者头像 李华